mirror of
https://github.com/coder/code-server.git
synced 2026-05-06 04:25:19 +02:00
chore(vscode): update to 1.55.2
This commit is contained in:
@@ -67,16 +67,19 @@ export type IRecent = IRecentWorkspace | IRecentFolder | IRecentFile;
|
||||
export interface IRecentWorkspace {
|
||||
workspace: IWorkspaceIdentifier;
|
||||
label?: string;
|
||||
remoteAuthority?: string;
|
||||
}
|
||||
|
||||
export interface IRecentFolder {
|
||||
folderUri: URI;
|
||||
label?: string;
|
||||
remoteAuthority?: string;
|
||||
}
|
||||
|
||||
export interface IRecentFile {
|
||||
fileUri: URI;
|
||||
label?: string;
|
||||
remoteAuthority?: string;
|
||||
}
|
||||
|
||||
export function isRecentWorkspace(curr: IRecent): curr is IRecentWorkspace {
|
||||
@@ -416,17 +419,53 @@ export function useSlashForPath(storedFolders: IStoredWorkspaceFolder[]): boolea
|
||||
|
||||
//#region Workspace Storage
|
||||
|
||||
interface ISerializedRecentlyOpened {
|
||||
workspaces3: Array<ISerializedWorkspace | string>; // workspace or URI.toString() // added in 1.32
|
||||
interface ISerializedRecentWorkspace {
|
||||
workspace: {
|
||||
id: string;
|
||||
configPath: string;
|
||||
}
|
||||
label?: string;
|
||||
remoteAuthority?: string;
|
||||
}
|
||||
|
||||
interface ISerializedRecentFolder {
|
||||
folderUri: string;
|
||||
label?: string;
|
||||
remoteAuthority?: string;
|
||||
}
|
||||
|
||||
interface ISerializedRecentFile {
|
||||
fileUri: string;
|
||||
label?: string;
|
||||
remoteAuthority?: string;
|
||||
}
|
||||
|
||||
interface ISerializedRecentlyOpenedLegacy {
|
||||
workspaces3: Array<{ id: string; configURIPath: string; } | string>; // workspace or URI.toString() // added in 1.32
|
||||
workspaceLabels?: Array<string | null>; // added in 1.33
|
||||
files2: string[]; // files as URI.toString() // added in 1.32
|
||||
fileLabels?: Array<string | null>; // added in 1.33
|
||||
}
|
||||
|
||||
interface ISerializedWorkspace { id: string; configURIPath: string; }
|
||||
interface ISerializedRecentlyOpened {
|
||||
entries: Array<ISerializedRecentWorkspace | ISerializedRecentFolder | ISerializedRecentFile>; // since 1.55
|
||||
}
|
||||
|
||||
export type RecentlyOpenedStorageData = object;
|
||||
|
||||
function isSerializedRecentWorkspace(data: any): data is ISerializedRecentWorkspace {
|
||||
return data.workspace && typeof data.workspace === 'object' && typeof data.workspace.id === 'string' && typeof data.workspace.configPath === 'string';
|
||||
}
|
||||
|
||||
function isSerializedRecentFolder(data: any): data is ISerializedRecentFolder {
|
||||
return typeof data.folderUri === 'string';
|
||||
}
|
||||
|
||||
function isSerializedRecentFile(data: any): data is ISerializedRecentFile {
|
||||
return typeof data.fileUri === 'string';
|
||||
}
|
||||
|
||||
|
||||
export function restoreRecentlyOpened(data: RecentlyOpenedStorageData | undefined, logService: ILogService): IRecentlyOpened {
|
||||
const result: IRecentlyOpened = { workspaces: [], files: [] };
|
||||
if (data) {
|
||||
@@ -441,23 +480,39 @@ export function restoreRecentlyOpened(data: RecentlyOpenedStorageData | undefine
|
||||
};
|
||||
|
||||
const storedRecents = data as ISerializedRecentlyOpened;
|
||||
if (Array.isArray(storedRecents.workspaces3)) {
|
||||
restoreGracefully(storedRecents.workspaces3, (workspace, i) => {
|
||||
const label: string | undefined = (Array.isArray(storedRecents.workspaceLabels) && storedRecents.workspaceLabels[i]) || undefined;
|
||||
if (typeof workspace === 'object' && typeof workspace.id === 'string' && typeof workspace.configURIPath === 'string') {
|
||||
result.workspaces.push({ label, workspace: { id: workspace.id, configPath: URI.parse(workspace.configURIPath) } });
|
||||
} else if (typeof workspace === 'string') {
|
||||
result.workspaces.push({ label, folderUri: URI.parse(workspace) });
|
||||
}
|
||||
});
|
||||
}
|
||||
if (Array.isArray(storedRecents.files2)) {
|
||||
restoreGracefully(storedRecents.files2, (file, i) => {
|
||||
const label: string | undefined = (Array.isArray(storedRecents.fileLabels) && storedRecents.fileLabels[i]) || undefined;
|
||||
if (typeof file === 'string') {
|
||||
result.files.push({ label, fileUri: URI.parse(file) });
|
||||
if (Array.isArray(storedRecents.entries)) {
|
||||
restoreGracefully(storedRecents.entries, (entry) => {
|
||||
const label = entry.label;
|
||||
const remoteAuthority = entry.remoteAuthority;
|
||||
|
||||
if (isSerializedRecentWorkspace(entry)) {
|
||||
result.workspaces.push({ label, remoteAuthority, workspace: { id: entry.workspace.id, configPath: URI.parse(entry.workspace.configPath) } });
|
||||
} else if (isSerializedRecentFolder(entry)) {
|
||||
result.workspaces.push({ label, remoteAuthority, folderUri: URI.parse(entry.folderUri) });
|
||||
} else if (isSerializedRecentFile(entry)) {
|
||||
result.files.push({ label, remoteAuthority, fileUri: URI.parse(entry.fileUri) });
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const storedRecents2 = data as ISerializedRecentlyOpenedLegacy;
|
||||
if (Array.isArray(storedRecents2.workspaces3)) {
|
||||
restoreGracefully(storedRecents2.workspaces3, (workspace, i) => {
|
||||
const label: string | undefined = (Array.isArray(storedRecents2.workspaceLabels) && storedRecents2.workspaceLabels[i]) || undefined;
|
||||
if (typeof workspace === 'object' && typeof workspace.id === 'string' && typeof workspace.configURIPath === 'string') {
|
||||
result.workspaces.push({ label, workspace: { id: workspace.id, configPath: URI.parse(workspace.configURIPath) } });
|
||||
} else if (typeof workspace === 'string') {
|
||||
result.workspaces.push({ label, folderUri: URI.parse(workspace) });
|
||||
}
|
||||
});
|
||||
}
|
||||
if (Array.isArray(storedRecents2.files2)) {
|
||||
restoreGracefully(storedRecents2.files2, (file, i) => {
|
||||
const label: string | undefined = (Array.isArray(storedRecents2.fileLabels) && storedRecents2.fileLabels[i]) || undefined;
|
||||
if (typeof file === 'string') {
|
||||
result.files.push({ label, fileUri: URI.parse(file) });
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,37 +520,19 @@ export function restoreRecentlyOpened(data: RecentlyOpenedStorageData | undefine
|
||||
}
|
||||
|
||||
export function toStoreData(recents: IRecentlyOpened): RecentlyOpenedStorageData {
|
||||
const serialized: ISerializedRecentlyOpened = { workspaces3: [], files2: [] };
|
||||
const serialized: ISerializedRecentlyOpened = { entries: [] };
|
||||
|
||||
let hasLabel = false;
|
||||
const workspaceLabels: (string | null)[] = [];
|
||||
for (const recent of recents.workspaces) {
|
||||
if (isRecentFolder(recent)) {
|
||||
serialized.workspaces3.push(recent.folderUri.toString());
|
||||
serialized.entries.push({ folderUri: recent.folderUri.toString(), label: recent.label, remoteAuthority: recent.remoteAuthority });
|
||||
} else {
|
||||
serialized.workspaces3.push({ id: recent.workspace.id, configURIPath: recent.workspace.configPath.toString() });
|
||||
serialized.entries.push({ workspace: { id: recent.workspace.id, configPath: recent.workspace.configPath.toString() }, label: recent.label, remoteAuthority: recent.remoteAuthority });
|
||||
}
|
||||
workspaceLabels.push(recent.label || null);
|
||||
hasLabel = hasLabel || !!recent.label;
|
||||
}
|
||||
|
||||
if (hasLabel) {
|
||||
serialized.workspaceLabels = workspaceLabels;
|
||||
}
|
||||
|
||||
hasLabel = false;
|
||||
|
||||
const fileLabels: (string | null)[] = [];
|
||||
for (const recent of recents.files) {
|
||||
serialized.files2.push(recent.fileUri.toString());
|
||||
fileLabels.push(recent.label || null);
|
||||
hasLabel = hasLabel || !!recent.label;
|
||||
serialized.entries.push({ fileUri: recent.fileUri.toString(), label: recent.label, remoteAuthority: recent.remoteAuthority });
|
||||
}
|
||||
|
||||
if (hasLabel) {
|
||||
serialized.fileLabels = fileLabels;
|
||||
}
|
||||
|
||||
return serialized;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ import { ThrottledDelayer } from 'vs/base/common/async';
|
||||
import { originalFSPath, basename, extUriBiasedIgnorePathCase } from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
|
||||
import { exists } from 'vs/base/node/pfs';
|
||||
import { ILifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -44,8 +43,8 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa
|
||||
|
||||
private static readonly MAX_TOTAL_RECENT_ENTRIES = 100;
|
||||
|
||||
private static readonly MAX_MACOS_DOCK_RECENT_WORKSPACES = 7; // prefer more workspaces...
|
||||
private static readonly MAX_MACOS_DOCK_RECENT_ENTRIES_TOTAL = 10; // ...compared to files
|
||||
private static readonly MAX_MACOS_DOCK_RECENT_WORKSPACES = 7; // prefer higher number of workspaces...
|
||||
private static readonly MAX_MACOS_DOCK_RECENT_ENTRIES_TOTAL = 10; // ...over number of files
|
||||
|
||||
// Exclude some very common files from the dock/taskbar
|
||||
private static readonly COMMON_FILES_FILTER = [
|
||||
@@ -66,7 +65,6 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa
|
||||
@IStateService private readonly stateService: IStateService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IWorkspacesManagementMainService private readonly workspacesManagementMainService: IWorkspacesManagementMainService,
|
||||
@IEnvironmentMainService private readonly environmentMainService: IEnvironmentMainService,
|
||||
@ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService
|
||||
) {
|
||||
super();
|
||||
@@ -393,16 +391,19 @@ export class WorkspacesHistoryMainService extends Disposable implements IWorkspa
|
||||
}
|
||||
|
||||
private getWindowsJumpListLabel(workspace: IWorkspaceIdentifier | URI, recentLabel: string | undefined): { title: string; description: string } {
|
||||
|
||||
// Prefer recent label
|
||||
if (recentLabel) {
|
||||
return { title: splitName(recentLabel).name, description: recentLabel };
|
||||
}
|
||||
|
||||
// Single Folder
|
||||
if (URI.isUri(workspace)) {
|
||||
return { title: basename(workspace), description: renderJumpListPathDescription(workspace) };
|
||||
}
|
||||
|
||||
// Workspace: Untitled
|
||||
if (extUriBiasedIgnorePathCase.isEqualOrParent(workspace.configPath, this.environmentMainService.userHome)) {
|
||||
if (this.workspacesManagementMainService.isUntitledWorkspace(workspace)) {
|
||||
return { title: localize('untitledWorkspace', "Untitled (Workspace)"), description: '' };
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import { originalFSPath, joinPath, basename, extUriBiasedIgnorePathCase } from '
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICodeWindow } from 'vs/platform/windows/electron-main/windows';
|
||||
import { localize } from 'vs/nls';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { MessageBoxOptions, BrowserWindow } from 'electron';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { IBackupMainService } from 'vs/platform/backup/electron-main/backup';
|
||||
@@ -77,7 +77,8 @@ export class WorkspacesManagementMainService extends Disposable implements IWork
|
||||
@IEnvironmentMainService private readonly environmentMainService: IEnvironmentMainService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IBackupMainService private readonly backupMainService: IBackupMainService,
|
||||
@IDialogMainService private readonly dialogMainService: IDialogMainService
|
||||
@IDialogMainService private readonly dialogMainService: IDialogMainService,
|
||||
@IProductService private readonly productService: IProductService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -151,15 +152,7 @@ export class WorkspacesManagementMainService extends Disposable implements IWork
|
||||
const { workspace, storedWorkspace } = this.newUntitledWorkspace(folders, remoteAuthority);
|
||||
const configPath = workspace.configPath.fsPath;
|
||||
|
||||
const configPathDir = dirname(configPath);
|
||||
if (!existsSync(configPathDir)) {
|
||||
const configPathDirDir = dirname(configPathDir);
|
||||
if (!existsSync(configPathDirDir)) {
|
||||
mkdirSync(configPathDirDir);
|
||||
}
|
||||
mkdirSync(configPathDir);
|
||||
}
|
||||
|
||||
mkdirSync(dirname(configPath), { recursive: true });
|
||||
writeFileSync(configPath, JSON.stringify(storedWorkspace, null, '\t'));
|
||||
|
||||
return workspace;
|
||||
@@ -278,7 +271,7 @@ export class WorkspacesManagementMainService extends Disposable implements IWork
|
||||
// Prevent overwriting a workspace that is currently opened in another window
|
||||
if (findWindowOnWorkspaceOrFolder(windows, workspacePath)) {
|
||||
const options: MessageBoxOptions = {
|
||||
title: product.nameLong,
|
||||
title: this.productService.nameLong,
|
||||
type: 'info',
|
||||
buttons: [localize('ok', "OK")],
|
||||
message: localize('workspaceOpenedMessage', "Unable to save workspace '{0}'", basename(workspacePath)),
|
||||
|
||||
@@ -36,6 +36,7 @@ suite('History Storage', () => {
|
||||
for (let i = 0; i < actual.files.length; i++) {
|
||||
assertEqualURI(actual.files[i].fileUri, expected.files[i].fileUri, message);
|
||||
assert.strictEqual(actual.files[i].label, expected.files[i].label);
|
||||
assert.strictEqual(actual.files[i].remoteAuthority, expected.files[i].remoteAuthority);
|
||||
}
|
||||
assert.strictEqual(actual.workspaces.length, expected.workspaces.length, message);
|
||||
for (let i = 0; i < actual.workspaces.length; i++) {
|
||||
@@ -47,6 +48,7 @@ suite('History Storage', () => {
|
||||
assertEqualWorkspace(actualRecent.workspace, (<IRecentWorkspace>expectedRecent).workspace, message);
|
||||
}
|
||||
assert.strictEqual(actualRecent.label, expectedRecent.label);
|
||||
assert.strictEqual(actualRecent.remoteAuthority, actualRecent.remoteAuthority);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +99,11 @@ suite('History Storage', () => {
|
||||
workspaces: [{ label: 'def', workspace: toWorkspace(testWSPath) }, { folderUri: testRemoteFolderURI }]
|
||||
};
|
||||
assertRestoring(ro, 'labels');
|
||||
ro = {
|
||||
files: [{ label: 'abc', remoteAuthority: 'test', fileUri: testRemoteFileURI }],
|
||||
workspaces: [{ label: 'def', remoteAuthority: 'test', workspace: toWorkspace(testWSPath) }, { folderUri: testRemoteFolderURI, remoteAuthority: 'test' }]
|
||||
};
|
||||
assertRestoring(ro, 'authority');
|
||||
});
|
||||
|
||||
test('open 1_33', () => {
|
||||
@@ -131,4 +138,41 @@ suite('History Storage', () => {
|
||||
|
||||
assertEqualRecentlyOpened(windowsState, expected, 'v1_33');
|
||||
});
|
||||
|
||||
test('open 1_55', () => {
|
||||
const v1_55 = `{
|
||||
"entries": [
|
||||
{
|
||||
"folderUri": "foo://bar/23/43",
|
||||
"remoteAuthority": "test+test"
|
||||
},
|
||||
{
|
||||
"workspace": {
|
||||
"id": "53b714b46ef1a2d4346568b4f591028c",
|
||||
"configPath": "file:///home/user/workspaces/testing/custom.code-workspace"
|
||||
}
|
||||
},
|
||||
{
|
||||
"folderUri": "file:///home/user/workspaces/testing/folding",
|
||||
"label": "abc"
|
||||
},
|
||||
{
|
||||
"fileUri": "file:///home/user/.config/code-oss-dev/storage.json",
|
||||
"label": "def"
|
||||
}
|
||||
]
|
||||
}`;
|
||||
|
||||
let windowsState = restoreRecentlyOpened(JSON.parse(v1_55), new NullLogService());
|
||||
let expected: IRecentlyOpened = {
|
||||
files: [{ label: 'def', fileUri: URI.parse('file:///home/user/.config/code-oss-dev/storage.json') }],
|
||||
workspaces: [
|
||||
{ folderUri: URI.parse('foo://bar/23/43'), remoteAuthority: 'test+test' },
|
||||
{ workspace: { id: '53b714b46ef1a2d4346568b4f591028c', configPath: URI.parse('file:///home/user/workspaces/testing/custom.code-workspace') } },
|
||||
{ label: 'abc', folderUri: URI.parse('file:///home/user/workspaces/testing/folding') }
|
||||
]
|
||||
};
|
||||
|
||||
assertEqualRecentlyOpened(windowsState, expected, 'v1_33');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ import { WorkspacesManagementMainService, IStoredWorkspace, getSingleFolderWorks
|
||||
import { WORKSPACE_EXTENSION, IRawFileWorkspaceFolder, IWorkspaceFolderCreationData, IRawUriWorkspaceFolder, rewriteWorkspaceFileForNewLocation, IWorkspaceIdentifier, IStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { getRandomTestPath } from 'vs/base/test/node/testUtils';
|
||||
import { flakySuite, getRandomTestPath } from 'vs/base/test/node/testUtils';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { normalizeDriveLetter } from 'vs/base/common/labels';
|
||||
import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources';
|
||||
@@ -22,8 +22,10 @@ import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMain
|
||||
import { INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IBackupMainService, IWorkspaceBackupInfo } from 'vs/platform/backup/electron-main/backup';
|
||||
import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
|
||||
suite('WorkspacesManagementMainService', () => {
|
||||
flakySuite('WorkspacesManagementMainService', () => {
|
||||
|
||||
class TestDialogMainService implements IDialogMainService {
|
||||
|
||||
@@ -92,10 +94,12 @@ suite('WorkspacesManagementMainService', () => {
|
||||
testDir = getRandomTestPath(tmpDir, 'vsctests', 'workspacesmanagementmainservice');
|
||||
untitledWorkspacesHomePath = path.join(testDir, 'Workspaces');
|
||||
|
||||
const productService: IProductService = { _serviceBrand: undefined, ...product };
|
||||
|
||||
environmentMainService = new class TestEnvironmentService extends EnvironmentMainService {
|
||||
|
||||
constructor() {
|
||||
super(parseArgs(process.argv, OPTIONS));
|
||||
super(parseArgs(process.argv, OPTIONS), productService);
|
||||
}
|
||||
|
||||
get untitledWorkspacesHome(): URI {
|
||||
@@ -103,7 +107,7 @@ suite('WorkspacesManagementMainService', () => {
|
||||
}
|
||||
};
|
||||
|
||||
service = new WorkspacesManagementMainService(environmentMainService, new NullLogService(), new TestBackupMainService(), new TestDialogMainService());
|
||||
service = new WorkspacesManagementMainService(environmentMainService, new NullLogService(), new TestBackupMainService(), new TestDialogMainService(), productService);
|
||||
|
||||
return fs.promises.mkdir(untitledWorkspacesHomePath, { recursive: true });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user