提交 fd7d83f6 编写于 作者: S Sandeep Somavarapu

Use URI instead of Path for folders

上级 cf54770f
......@@ -7,6 +7,18 @@
import * as paths from 'vs/base/common/paths';
import uri from 'vs/base/common/uri';
import { equalsIgnoreCase } from 'vs/base/common/strings';
import { Schemas } from 'vs/base/common/network';
import { isLinux } from 'vs/base/common/platform';
export function getComparisonKey(resource: uri): string {
return hasToIgnoreCase(resource) ? resource.toString().toLowerCase() : resource.toString();
}
export function hasToIgnoreCase(resource: uri): boolean {
// A file scheme resource is in the same platform as code, so ignore case for non linux platforms
// Resource can be from another platform. Lowering the case as an hack. Should come from File system provider
return resource.scheme === Schemas.file ? !isLinux : true;
}
export function basenameOrAuthority(resource: uri): string {
return paths.basename(resource.path) || resource.authority;
......
......@@ -154,14 +154,14 @@ export class CodeApplication {
});
});
let macOpenFiles: string[] = [];
let macOpenFiles: URI[] = [];
let runningTimeout: number = null;
app.on('open-file', (event: Event, path: string) => {
this.logService.trace('App#open-file: ', path);
event.preventDefault();
// Keep in array because more might come!
macOpenFiles.push(path);
macOpenFiles.push(URI.file(path));
// Clear previous handler if any
if (runningTimeout !== null) {
......@@ -465,7 +465,7 @@ export class CodeApplication {
if (args['new-window'] && args._.length === 0) {
this.windowsMainService.open({ context, cli: args, forceNewWindow: true, forceEmpty: true, initialStartup: true }); // new window if "-n" was used without paths
} else if (macOpenFiles && macOpenFiles.length && (!args._ || !args._.length)) {
this.windowsMainService.open({ context: OpenContext.DOCK, cli: args, pathsToOpen: macOpenFiles, initialStartup: true }); // mac: open-file event received on startup
this.windowsMainService.open({ context: OpenContext.DOCK, cli: args, pathsToOpen: macOpenFiles.map(file => URI.file(file)), initialStartup: true }); // mac: open-file event received on startup
} else {
this.windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!args._.length && args['unity-launch']), diffMode: args.diff, initialStartup: true }); // default: read paths from cli
}
......
......@@ -277,8 +277,10 @@ export class LaunchService implements ILaunchService {
private codeWindowToInfo(window: ICodeWindow): IWindowInfo {
const folders: string[] = [];
if (window.openedFolderPath) {
folders.push(window.openedFolderPath);
if (window.openedFolderUri) {
if (window.openedFolderUri.scheme === Schemas.file) {
folders.push(window.openedFolderUri.fsPath); // todo@remote signal remote folders?
}
} else if (window.openedWorkspace) {
const rootFolders = this.workspacesMainService.resolveWorkspaceSync(window.openedWorkspace.configPath).folders;
rootFolders.forEach(root => {
......
......@@ -20,8 +20,9 @@ import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel, getPathLabel }
import { KeybindingsResolver } from 'vs/code/electron-main/keyboard';
import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows';
import { IHistoryMainService } from 'vs/platform/history/common/history';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier2, isSingleFolderWorkspaceIdentifier2, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IMenubarData, IMenubarMenuItemAction, IMenubarMenuItemSeparator } from 'vs/platform/menubar/common/menubar';
import URI from 'vs/base/common/uri';
// interface IExtensionViewlet {
// id: string;
......@@ -511,15 +512,18 @@ export class Menubar {
});
}
private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): Electron.MenuItem {
private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | string, commandId: string, isFile: boolean): Electron.MenuItem {
let label: string;
let path: string;
if (isSingleFolderWorkspaceIdentifier(workspace) || typeof workspace === 'string') {
let uri: URI;
if (isSingleFolderWorkspaceIdentifier2(workspace)) {
label = unmnemonicLabel(getPathLabel(workspace, this.environmentService, null));
path = workspace;
} else {
uri = workspace;
} else if (isWorkspaceIdentifier(workspace)) {
label = getWorkspaceLabel(workspace, this.environmentService, { verbose: true });
path = workspace.configPath;
uri = URI.file(workspace.configPath);
} else {
label = unmnemonicLabel(getPathLabel(workspace, this.environmentService, null));
uri = URI.file(workspace);
}
return new MenuItem(this.likeAction(commandId, {
......@@ -529,12 +533,13 @@ export class Menubar {
const success = this.windowsMainService.open({
context: OpenContext.MENU,
cli: this.environmentService.args,
pathsToOpen: [path], forceNewWindow: openInNewWindow,
pathsToOpen: [uri],
forceNewWindow: openInNewWindow,
forceOpenWorkspaceAsFile: isFile
}).length > 0;
if (!success) {
this.historyMainService.removeFromRecentlyOpened([isSingleFolderWorkspaceIdentifier(workspace) ? workspace : workspace.configPath]);
this.historyMainService.removeFromRecentlyOpened([workspace]);
}
}
}, false));
......
......@@ -22,7 +22,8 @@ import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel, getPathLabel }
import { KeybindingsResolver } from 'vs/code/electron-main/keyboard';
import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows';
import { IHistoryMainService } from 'vs/platform/history/common/history';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier2, isSingleFolderWorkspaceIdentifier2, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import URI from 'vs/base/common/uri';
interface IMenuItemClickHandler {
inDevTools: (contents: Electron.WebContents) => void;
......@@ -194,7 +195,7 @@ export class CodeMenu {
private updateWorkspaceMenuItems(): void {
const window = this.windowsMainService.getLastActiveWindow();
const isInWorkspaceContext = window && !!window.openedWorkspace;
const isInFolderContext = window && !!window.openedFolderPath;
const isInFolderContext = window && !!window.openedFolderUri;
this.closeWorkspace.visible = isInWorkspaceContext;
this.closeFolder.visible = !isInWorkspaceContext;
......@@ -487,15 +488,18 @@ export class CodeMenu {
}
}
private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): Electron.MenuItem {
private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | string, commandId: string, isFile: boolean): Electron.MenuItem {
let label: string;
let path: string;
if (isSingleFolderWorkspaceIdentifier(workspace) || typeof workspace === 'string') {
label = unmnemonicLabel(getPathLabel(workspace, this.environmentService));
path = workspace;
} else {
let resource: URI;
if (isSingleFolderWorkspaceIdentifier2(workspace)) {
label = unmnemonicLabel(getPathLabel(workspace, this.environmentService, null));
resource = workspace;
} else if (isWorkspaceIdentifier(workspace)) {
label = getWorkspaceLabel(workspace, this.environmentService, { verbose: true });
path = workspace.configPath;
resource = URI.file(workspace.configPath);
} else {
label = unmnemonicLabel(getPathLabel(workspace, this.environmentService, null));
resource = URI.file(workspace);
}
return new MenuItem(this.likeAction(commandId, {
......@@ -505,12 +509,12 @@ export class CodeMenu {
const success = this.windowsMainService.open({
context: OpenContext.MENU,
cli: this.environmentService.args,
pathsToOpen: [path], forceNewWindow: openInNewWindow,
pathsToOpen: [resource], forceNewWindow: openInNewWindow,
forceOpenWorkspaceAsFile: isFile
}).length > 0;
if (!success) {
this.historyMainService.removeFromRecentlyOpened([isSingleFolderWorkspaceIdentifier(workspace) ? workspace : workspace.configPath]);
this.historyMainService.removeFromRecentlyOpened([workspace]);
}
}
}, false));
......
......@@ -297,8 +297,8 @@ export class CodeWindow implements ICodeWindow {
return this.currentConfig ? this.currentConfig.workspace : void 0;
}
get openedFolderPath(): string {
return this.currentConfig ? this.currentConfig.folderPath : void 0;
get openedFolderUri(): URI {
return this.currentConfig ? this.currentConfig.folderUri : void 0;
}
setReady(): void {
......
......@@ -8,12 +8,14 @@
import * as platform from 'vs/base/common/platform';
import * as paths from 'vs/base/common/paths';
import { OpenContext } from 'vs/platform/windows/common/windows';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IResolvedWorkspace } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, IResolvedWorkspace, ISingleFolderWorkspaceIdentifier2, isSingleFolderWorkspaceIdentifier2 } from 'vs/platform/workspaces/common/workspaces';
import { Schemas } from 'vs/base/common/network';
import URI from 'vs/base/common/uri';
import { hasToIgnoreCase, isEqual } from 'vs/base/common/resources';
export interface ISimpleWindow {
openedWorkspace?: IWorkspaceIdentifier;
openedFolderPath?: string;
openedFolderUri?: URI;
openedFilePath?: string;
extensionDevelopmentPath?: string;
lastFocusTime: number;
......@@ -30,7 +32,7 @@ export interface IBestWindowOrFolderOptions<W extends ISimpleWindow> {
workspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace;
}
export function findBestWindowOrFolderForFile<W extends ISimpleWindow>({ windows, newWindow, reuseWindow, context, filePath, workspaceResolver }: IBestWindowOrFolderOptions<W>): W | string {
export function findBestWindowOrFolderForFile<W extends ISimpleWindow>({ windows, newWindow, reuseWindow, context, filePath, workspaceResolver }: IBestWindowOrFolderOptions<W>): W {
if (!newWindow && filePath && (context === OpenContext.DESKTOP || context === OpenContext.CLI || context === OpenContext.DOCK)) {
const windowOnFilePath = findWindowOnFilePath(windows, filePath, workspaceResolver);
if (windowOnFilePath) {
......@@ -54,9 +56,9 @@ function findWindowOnFilePath<W extends ISimpleWindow>(windows: W[], filePath: s
}
// Then go with single folder windows that are parent of the provided file path
const singleFolderWindowsOnFilePath = windows.filter(window => typeof window.openedFolderPath === 'string' && paths.isEqualOrParent(filePath, window.openedFolderPath, !platform.isLinux /* ignorecase */));
const singleFolderWindowsOnFilePath = windows.filter(window => window.openedFolderUri && window.openedFolderUri.scheme === Schemas.file && paths.isEqualOrParent(filePath, window.openedFolderUri.fsPath, !platform.isLinux /* ignorecase */));
if (singleFolderWindowsOnFilePath.length) {
return singleFolderWindowsOnFilePath.sort((a, b) => -(a.openedFolderPath.length - b.openedFolderPath.length))[0];
return singleFolderWindowsOnFilePath.sort((a, b) => -(a.openedFolderUri.path.length - b.openedFolderUri.path.length))[0];
}
return null;
......@@ -68,12 +70,12 @@ export function getLastActiveWindow<W extends ISimpleWindow>(windows: W[]): W {
return windows.filter(window => window.lastFocusTime === lastFocusedDate)[0];
}
export function findWindowOnWorkspace<W extends ISimpleWindow>(windows: W[], workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)): W {
export function findWindowOnWorkspace<W extends ISimpleWindow>(windows: W[], workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2)): W {
return windows.filter(window => {
// match on folder
if (isSingleFolderWorkspaceIdentifier(workspace)) {
if (typeof window.openedFolderPath === 'string' && (paths.isEqual(window.openedFolderPath, workspace, !platform.isLinux /* ignorecase */))) {
if (isSingleFolderWorkspaceIdentifier2(workspace)) {
if (window.openedFolderUri && isEqual(window.openedFolderUri, workspace, hasToIgnoreCase(window.openedFolderUri))) { //TODO:#54483
return true;
}
}
......@@ -110,7 +112,7 @@ export function findWindowOnWorkspaceOrFolderPath<W extends ISimpleWindow>(windo
}
// check for folder path
if (window.openedFolderPath && paths.isEqual(window.openedFolderPath, path, !platform.isLinux /* ignorecase */)) {
if (window.openedFolderUri && window.openedFolderUri.scheme === Schemas.file && paths.isEqual(window.openedFolderUri.fsPath, path, !platform.isLinux /* ignorecase */)) {
return true;
}
......
......@@ -8,7 +8,7 @@ import Severity from 'vs/base/common/severity';
import URI from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
import { IConfigurationService, IConfigurationChangeEvent, IConfigurationOverrides, IConfigurationData } from 'vs/platform/configuration/common/configuration';
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier2 } from 'vs/platform/workspaces/common/workspaces';
import { ICommandService, ICommand, ICommandEvent, ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands';
import { AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
......@@ -532,7 +532,7 @@ export class SimpleWorkspaceContextService implements IWorkspaceContextService {
return resource && resource.scheme === SimpleWorkspaceContextService.SCHEME;
}
public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean {
public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier2 | IWorkspaceIdentifier): boolean {
return true;
}
}
......
......@@ -14,7 +14,13 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IFilesConfiguration, HotExitConfiguration } from 'vs/platform/files/common/files';
import { ILogService } from 'vs/platform/log/common/log';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
type ISingleFolderWorkspaceIdentifier = string;
function isSingleFolderWorkspaceIdentifier(obj: any): obj is ISingleFolderWorkspaceIdentifier {
return typeof obj === 'string';
}
export class BackupMainService implements IBackupMainService {
......@@ -227,7 +233,7 @@ export class BackupMainService implements IBackupMainService {
const workspacePath = isSingleFolderWorkspaceIdentifier(workspaceId) ? workspaceId : workspaceId.configPath;
const backupPath = path.join(this.backupHome, isSingleFolderWorkspaceIdentifier(workspaceId) ? this.getFolderHash(workspaceId) : workspaceId.id);
const hasBackups = this.hasBackupsSync(backupPath);
const missingWorkspace = hasBackups && !fs.existsSync(workspacePath);
const missingWorkspace = hasBackups && !fs.existsSync(workspacePath); //TODO:#54483
// If the workspace/folder has no backups, make sure to delete it
// If the workspace/folder has backups, but the target workspace is missing, convert backups to empty ones
......@@ -320,6 +326,7 @@ export class BackupMainService implements IBackupMainService {
}
private sanitizePath(p: string): string {
//TODO:#54483
return platform.isLinux ? p : p.toLowerCase();
}
......
......@@ -8,12 +8,12 @@
import { IPath } from 'vs/platform/windows/common/windows';
import { Event as CommonEvent } from 'vs/base/common/event';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier2 } from 'vs/platform/workspaces/common/workspaces';
export const IHistoryMainService = createDecorator<IHistoryMainService>('historyMainService');
export interface IRecentlyOpened {
workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[];
workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2)[];
files: string[];
}
......@@ -22,9 +22,9 @@ export interface IHistoryMainService {
onRecentlyOpenedChange: CommonEvent<void>;
addRecentlyOpened(workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], files: string[]): void;
getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier, currentFiles?: IPath[]): IRecentlyOpened;
removeFromRecentlyOpened(paths: string[]): void;
addRecentlyOpened(workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2)[], files: string[]): void;
getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2, currentFiles?: IPath[]): IRecentlyOpened;
removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | string)[]): void;
clearRecentlyOpened(): void;
updateWindowsJumpList(): void;
......
......@@ -16,11 +16,19 @@ import { getPathLabel, getBaseLabel } from 'vs/base/common/labels';
import { IPath } from 'vs/platform/windows/common/windows';
import { Event as CommonEvent, Emitter } from 'vs/base/common/event';
import { isWindows, isMacintosh, isLinux } from 'vs/base/common/platform';
import { IWorkspaceIdentifier, IWorkspacesMainService, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceSavedEvent } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, IWorkspacesMainService, getWorkspaceLabel, IWorkspaceSavedEvent, ISingleFolderWorkspaceIdentifier2, isSingleFolderWorkspaceIdentifier2, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IHistoryMainService, IRecentlyOpened } from 'vs/platform/history/common/history';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { isEqual } from 'vs/base/common/paths';
import { RunOnceScheduler } from 'vs/base/common/async';
import { getComparisonKey, isEqual as areResourcesEqual, hasToIgnoreCase } from 'vs/base/common/resources';
import URI, { UriComponents } from 'vs/base/common/uri';
import { Schemas } from 'vs/base/common/network';
interface ISerializedRecentlyOpened {
workspaces: (IWorkspaceIdentifier | string | UriComponents)[];
files: string[];
}
export class HistoryMainService implements IHistoryMainService {
......@@ -57,14 +65,14 @@ export class HistoryMainService implements IHistoryMainService {
this.addRecentlyOpened([e.workspace], []);
}
addRecentlyOpened(workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], files: string[]): void {
addRecentlyOpened(workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2)[], files: string[]): void {
if ((workspaces && workspaces.length > 0) || (files && files.length > 0)) {
const mru = this.getRecentlyOpened();
// Workspaces
if (Array.isArray(workspaces)) {
workspaces.forEach(workspace => {
const isUntitledWorkspace = !isSingleFolderWorkspaceIdentifier(workspace) && this.workspacesMainService.isUntitledWorkspace(workspace);
const isUntitledWorkspace = !isSingleFolderWorkspaceIdentifier2(workspace) && this.workspacesMainService.isUntitledWorkspace(workspace);
if (isUntitledWorkspace) {
return; // only store saved workspaces
}
......@@ -104,21 +112,37 @@ export class HistoryMainService implements IHistoryMainService {
}
}
removeFromRecentlyOpened(pathsToRemove: string[]): void {
removeFromRecentlyOpened(pathsToRemove: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | string)[]): void {
const mru = this.getRecentlyOpened();
let update = false;
pathsToRemove.forEach((pathToRemove => {
// Remove workspace
let index = arrays.firstIndex(mru.workspaces, workspace => isEqual(isSingleFolderWorkspaceIdentifier(workspace) ? workspace : workspace.configPath, pathToRemove, !isLinux /* ignorecase */));
let index = arrays.firstIndex(mru.workspaces, workspace => {
if (isWorkspaceIdentifier(pathToRemove)) {
return isWorkspaceIdentifier(workspace) && isEqual(pathToRemove.configPath, workspace.configPath, !isLinux /* ignorecase */);
}
if (isSingleFolderWorkspaceIdentifier2(pathToRemove)) {
return isSingleFolderWorkspaceIdentifier2(workspace) && areResourcesEqual(pathToRemove, workspace, hasToIgnoreCase(pathToRemove));
}
if (typeof pathsToRemove === 'string') {
if (isSingleFolderWorkspaceIdentifier2(workspace)) {
return workspace.scheme === Schemas.file && areResourcesEqual(URI.file(pathToRemove), workspace, hasToIgnoreCase(workspace));
}
if (isWorkspaceIdentifier(workspace)) {
return isEqual(pathToRemove, workspace.configPath, !isLinux /* ignorecase */);
}
}
return false;
});
if (index >= 0) {
mru.workspaces.splice(index, 1);
update = true;
}
// Remove file
index = arrays.firstIndex(mru.files, file => isEqual(file, pathToRemove, !isLinux /* ignorecase */));
index = arrays.firstIndex(mru.files, file => typeof pathToRemove === 'string' && isEqual(file, pathToRemove, !isLinux /* ignorecase */));
if (index >= 0) {
mru.files.splice(index, 1);
update = true;
......@@ -155,7 +179,7 @@ export class HistoryMainService implements IHistoryMainService {
// Take up to maxEntries/2 workspaces
for (let i = 0; i < mru.workspaces.length && i < HistoryMainService.MAX_MACOS_DOCK_RECENT_ENTRIES / 2; i++) {
const workspace = mru.workspaces[i];
app.addRecentDocument(isSingleFolderWorkspaceIdentifier(workspace) ? workspace : workspace.configPath);
app.addRecentDocument(isSingleFolderWorkspaceIdentifier2(workspace) ? workspace.toString() : workspace.configPath);
maxEntries--;
}
......@@ -174,12 +198,12 @@ export class HistoryMainService implements IHistoryMainService {
this._onRecentlyOpenedChange.fire();
}
getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier, currentFiles?: IPath[]): IRecentlyOpened {
let workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[];
getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2, currentFiles?: IPath[]): IRecentlyOpened {
let workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2)[];
let files: string[];
// Get from storage
const storedRecents = this.stateService.getItem<IRecentlyOpened>(HistoryMainService.recentlyOpenedStorageKey);
const storedRecents = this.getRecentlyOpenedFromStorage();
if (storedRecents) {
workspaces = storedRecents.workspaces || [];
files = storedRecents.files || [];
......@@ -203,20 +227,46 @@ export class HistoryMainService implements IHistoryMainService {
files = arrays.distinct(files, file => this.distinctFn(file));
// Hide untitled workspaces
workspaces = workspaces.filter(workspace => isSingleFolderWorkspaceIdentifier(workspace) || !this.workspacesMainService.isUntitledWorkspace(workspace));
workspaces = workspaces.filter(workspace => isSingleFolderWorkspaceIdentifier2(workspace) || !this.workspacesMainService.isUntitledWorkspace(workspace));
return { workspaces, files };
}
private distinctFn(workspaceOrFile: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string): string {
if (isSingleFolderWorkspaceIdentifier(workspaceOrFile)) {
private distinctFn(workspaceOrFile: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | string): string {
if (isSingleFolderWorkspaceIdentifier2(workspaceOrFile)) {
return getComparisonKey(workspaceOrFile);
}
if (typeof workspaceOrFile === 'string') {
return isLinux ? workspaceOrFile : workspaceOrFile.toLowerCase();
}
return workspaceOrFile.id;
}
private getRecentlyOpenedFromStorage(): IRecentlyOpened {
const storedRecents: ISerializedRecentlyOpened = this.stateService.getItem<ISerializedRecentlyOpened>(HistoryMainService.recentlyOpenedStorageKey);
const result: IRecentlyOpened = { workspaces: [], files: storedRecents.files };
for (const workspace of storedRecents.workspaces) {
if (typeof workspace === 'string') {
result.workspaces.push(URI.file(workspace));
} else if (isWorkspaceIdentifier(workspace)) {
result.workspaces.push(workspace);
} else {
result.workspaces.push(URI.revive(workspace));
}
}
return result;
}
private saveRecentlyOpened(recent: IRecentlyOpened): void {
const serialized: ISerializedRecentlyOpened = { workspaces: [], files: recent.files };
for (const workspace of recent.workspaces) {
if (isSingleFolderWorkspaceIdentifier2(workspace)) {
serialized.workspaces.push(<UriComponents>workspace.toJSON());
} else {
serialized.workspaces.push(workspace);
}
}
this.stateService.setItem(HistoryMainService.recentlyOpenedStorageKey, recent);
}
......@@ -257,15 +307,26 @@ export class HistoryMainService implements IHistoryMainService {
type: 'custom',
name: nls.localize('recentFolders', "Recent Workspaces"),
items: this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(workspace => {
const title = isSingleFolderWorkspaceIdentifier(workspace) ? getBaseLabel(workspace) : getWorkspaceLabel(workspace, this.environmentService);
const description = isSingleFolderWorkspaceIdentifier(workspace) ? nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(path.dirname(workspace), this.environmentService)) : nls.localize('codeWorkspace', "Code Workspace");
const title = isSingleFolderWorkspaceIdentifier2(workspace) ? getBaseLabel(workspace) : getWorkspaceLabel(workspace, this.environmentService);
const description = isSingleFolderWorkspaceIdentifier2(workspace) ? nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(path.dirname(workspace.path), this.environmentService)) : nls.localize('codeWorkspace', "Code Workspace");
let args;
// use quotes to support paths with whitespaces
if (isSingleFolderWorkspaceIdentifier2(workspace)) {
if (workspace.scheme === Schemas.file) {
args = `"${workspace.fsPath}"`;
} else {
args = `--folderUri "${workspace.path}"`;
}
} else {
args = `"${workspace.configPath}"`;
}
return <Electron.JumpListItem>{
type: 'task',
title,
description,
program: process.execPath,
args: `"${isSingleFolderWorkspaceIdentifier(workspace) ? workspace : workspace.configPath}"`, // open folder (use quotes to support paths with whitespaces)
args,
iconPath: 'explorer.exe', // simulate folder icon
iconIndex: 0
};
......
......@@ -11,12 +11,13 @@ import { Event, latch, anyEvent } from 'vs/base/common/event';
import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
import { IProcessEnvironment } from 'vs/base/common/platform';
import { ParsedArgs } from 'vs/platform/environment/common/environment';
import { IWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier2 } from 'vs/platform/workspaces/common/workspaces';
import { IRecentlyOpened } from 'vs/platform/history/common/history';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
import { PerformanceEntry } from 'vs/base/common/performance';
import { LogLevel } from 'vs/platform/log/common/log';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import URI, { UriComponents } from 'vs/base/common/uri';
export const IWindowsService = createDecorator<IWindowsService>('windowsService');
......@@ -126,7 +127,7 @@ export interface IWindowsService {
toggleFullScreen(windowId: number): TPromise<void>;
setRepresentedFilename(windowId: number, fileName: string): TPromise<void>;
addRecentlyOpened(files: string[]): TPromise<void>;
removeFromRecentlyOpened(paths: string[]): TPromise<void>;
removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | string)[]): TPromise<void>;
clearRecentlyOpened(): TPromise<void>;
getRecentlyOpened(windowId: number): TPromise<IRecentlyOpened>;
focusWindow(windowId: number): TPromise<void>;
......@@ -156,7 +157,7 @@ export interface IWindowsService {
toggleSharedProcess(): TPromise<void>;
// Global methods
openWindow(windowId: number, paths: string[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean; }): TPromise<void>;
openWindow(windowId: number, paths: URI[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean; }): TPromise<void>;
openNewWindow(): TPromise<void>;
showWindow(windowId: number): TPromise<void>;
getWindows(): TPromise<{ id: number; workspace?: IWorkspaceIdentifier; folderPath?: string; title: string; filename?: string; }[]>;
......@@ -209,7 +210,7 @@ export interface IWindowService {
getRecentlyOpened(): TPromise<IRecentlyOpened>;
focusWindow(): TPromise<void>;
closeWindow(): TPromise<void>;
openWindow(paths: string[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean; }): TPromise<void>;
openWindow(paths: URI[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean; }): TPromise<void>;
isFocused(): TPromise<boolean>;
setDocumentEdited(flag: boolean): TPromise<void>;
isMaximized(): TPromise<boolean>;
......@@ -317,7 +318,7 @@ export interface IOpenFileRequest {
}
export interface IAddFoldersRequest {
foldersToAdd: IPath[];
foldersToAdd: UriComponents[];
}
export interface IWindowConfiguration extends ParsedArgs, IOpenFileRequest {
......@@ -335,7 +336,7 @@ export interface IWindowConfiguration extends ParsedArgs, IOpenFileRequest {
backupPath?: string;
workspace?: IWorkspaceIdentifier;
folderPath?: string;
folderUri?: ISingleFolderWorkspaceIdentifier2;
zoomLevel?: number;
fullscreen?: boolean;
......
......@@ -9,7 +9,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { Event, buffer } from 'vs/base/common/event';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult, CrashReporterStartOptions, IMessageBoxResult, MessageBoxOptions, SaveDialogOptions, OpenDialogOptions, IDevToolsOptions } from 'vs/platform/windows/common/windows';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, isSingleFolderWorkspaceIdentifier2, ISingleFolderWorkspaceIdentifier2, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IRecentlyOpened } from 'vs/platform/history/common/history';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
import URI from 'vs/base/common/uri';
......@@ -32,6 +32,7 @@ export interface IWindowsChannel extends IChannel {
call(command: 'showSaveDialog', arg: [number, SaveDialogOptions]): TPromise<string>;
call(command: 'showOpenDialog', arg: [number, OpenDialogOptions]): TPromise<string[]>;
call(command: 'reloadWindow', arg: [number, ParsedArgs]): TPromise<void>;
call(command: 'openDevTools', arg: [number, IDevToolsOptions]): TPromise<void>;
call(command: 'toggleDevTools', arg: number): TPromise<void>;
call(command: 'closeWorkspace', arg: number): TPromise<void>;
call(command: 'enterWorkspace', arg: [number, string]): TPromise<IEnterWorkspaceResult>;
......@@ -40,14 +41,14 @@ export interface IWindowsChannel extends IChannel {
call(command: 'toggleFullScreen', arg: number): TPromise<void>;
call(command: 'setRepresentedFilename', arg: [number, string]): TPromise<void>;
call(command: 'addRecentlyOpened', arg: string[]): TPromise<void>;
call(command: 'removeFromRecentlyOpened', arg: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[]): TPromise<void>;
call(command: 'removeFromRecentlyOpened', arg: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | string)[]): TPromise<void>;
call(command: 'clearRecentlyOpened'): TPromise<void>;
call(command: 'getRecentlyOpened', arg: number): TPromise<IRecentlyOpened>;
call(command: 'showPreviousWindowTab', arg: number): TPromise<void>;
call(command: 'showNextWindowTab', arg: number): TPromise<void>;
call(command: 'moveWindowTabToNewWindow', arg: number): TPromise<void>;
call(command: 'mergeAllWindowTabs', arg: number): TPromise<void>;
call(command: 'toggleWindowTabsBar', arg: number): TPromise<void>;
call(command: 'showPreviousWindowTab'): TPromise<void>;
call(command: 'showNextWindowTab'): TPromise<void>;
call(command: 'moveWindowTabToNewWindow'): TPromise<void>;
call(command: 'mergeAllWindowTabs'): TPromise<void>;
call(command: 'toggleWindowTabsBar'): TPromise<void>;
call(command: 'updateTouchBar', arg: [number, ISerializableCommandAction[][]]): TPromise<void>;
call(command: 'focusWindow', arg: number): TPromise<void>;
call(command: 'closeWindow', arg: number): TPromise<void>;
......@@ -59,12 +60,12 @@ export interface IWindowsChannel extends IChannel {
call(command: 'onWindowTitleDoubleClick', arg: number): TPromise<void>;
call(command: 'setDocumentEdited', arg: [number, boolean]): TPromise<void>;
call(command: 'quit'): TPromise<void>;
call(command: 'openWindow', arg: [number, string[], { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean }]): TPromise<void>;
call(command: 'openWindow', arg: [number, URI[], { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean }]): TPromise<void>;
call(command: 'openNewWindow'): TPromise<void>;
call(command: 'showWindow', arg: number): TPromise<void>;
call(command: 'getWindows'): TPromise<{ id: number; workspace?: IWorkspaceIdentifier; folderPath?: string; title: string; filename?: string; }[]>;
call(command: 'getWindowCount'): TPromise<number>;
call(command: 'relaunch', arg: { addArgs?: string[], removeArgs?: string[] }): TPromise<number>;
call(command: 'relaunch', arg: [{ addArgs?: string[], removeArgs?: string[] }]): TPromise<void>;
call(command: 'whenSharedProcessReady'): TPromise<void>;
call(command: 'toggleSharedProcess'): TPromise<void>;
call(command: 'log', arg: [string, string[]]): TPromise<void>;
......@@ -74,7 +75,6 @@ export interface IWindowsChannel extends IChannel {
call(command: 'startCrashReporter', arg: CrashReporterStartOptions): TPromise<void>;
call(command: 'openAccessibilityOptions'): TPromise<void>;
call(command: 'openAboutDialog'): TPromise<void>;
call(command: string, arg?: any): TPromise<any>;
}
export class WindowsChannel implements IWindowsChannel {
......@@ -140,7 +140,7 @@ export class WindowsChannel implements IWindowsChannel {
case 'toggleFullScreen': return this.service.toggleFullScreen(arg);
case 'setRepresentedFilename': return this.service.setRepresentedFilename(arg[0], arg[1]);
case 'addRecentlyOpened': return this.service.addRecentlyOpened(arg);
case 'removeFromRecentlyOpened': return this.service.removeFromRecentlyOpened(arg);
case 'removeFromRecentlyOpened': return this.service.removeFromRecentlyOpened(isSingleFolderWorkspaceIdentifier2(arg) ? URI.revive(arg) : arg);
case 'clearRecentlyOpened': return this.service.clearRecentlyOpened();
case 'showPreviousWindowTab': return this.service.showPreviousWindowTab();
case 'showNextWindowTab': return this.service.showNextWindowTab();
......@@ -158,7 +158,7 @@ export class WindowsChannel implements IWindowsChannel {
case 'minimizeWindow': return this.service.minimizeWindow(arg);
case 'onWindowTitleDoubleClick': return this.service.onWindowTitleDoubleClick(arg);
case 'setDocumentEdited': return this.service.setDocumentEdited(arg[0], arg[1]);
case 'openWindow': return this.service.openWindow(arg[0], arg[1], arg[2]);
case 'openWindow': return this.service.openWindow(arg[0], arg[1] ? (<URI[]>arg[1]).map(r => URI.revive(r)) : arg[1], arg[2]);
case 'openNewWindow': return this.service.openNewWindow();
case 'showWindow': return this.service.showWindow(arg);
case 'getWindows': return this.service.getWindows();
......@@ -260,7 +260,7 @@ export class WindowsChannelClient implements IWindowsService {
return this.channel.call('addRecentlyOpened', files);
}
removeFromRecentlyOpened(paths: string[]): TPromise<void> {
removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | string)[]): TPromise<void> {
return this.channel.call('removeFromRecentlyOpened', paths);
}
......@@ -269,7 +269,11 @@ export class WindowsChannelClient implements IWindowsService {
}
getRecentlyOpened(windowId: number): TPromise<IRecentlyOpened> {
return this.channel.call('getRecentlyOpened', windowId);
return this.channel.call('getRecentlyOpened', windowId)
.then(recentlyOpened => {
recentlyOpened.workspaces = recentlyOpened.workspaces.map(workspace => isWorkspaceIdentifier(workspace) ? workspace : URI.revive(workspace));
return recentlyOpened;
});
}
showPreviousWindowTab(): TPromise<void> {
......@@ -344,7 +348,7 @@ export class WindowsChannelClient implements IWindowsService {
return this.channel.call('toggleSharedProcess');
}
openWindow(windowId: number, paths: string[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean }): TPromise<void> {
openWindow(windowId: number, paths: URI[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean }): TPromise<void> {
return this.channel.call('openWindow', [windowId, paths, options]);
}
......
......@@ -12,6 +12,7 @@ import { IRecentlyOpened } from 'vs/platform/history/common/history';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
import { IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
import { ParsedArgs } from 'vs/platform/environment/common/environment';
import URI from 'vs/base/common/uri';
export class WindowService implements IWindowService {
......@@ -93,7 +94,7 @@ export class WindowService implements IWindowService {
return this.windowsService.saveAndEnterWorkspace(this.windowId, path);
}
openWindow(paths: string[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean; }): TPromise<void> {
openWindow(paths: URI[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean; }): TPromise<void> {
return this.windowsService.openWindow(this.windowId, paths, options);
}
......
......@@ -13,6 +13,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
import { IProcessEnvironment } from 'vs/base/common/platform';
import { IWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
import URI from 'vs/base/common/uri';
export interface IWindowState {
width?: number;
......@@ -35,7 +36,7 @@ export interface ICodeWindow {
win: Electron.BrowserWindow;
config: IWindowConfiguration;
openedFolderPath: string;
openedFolderUri: URI;
openedWorkspace: IWorkspaceIdentifier;
backupPath: string;
......@@ -123,7 +124,7 @@ export interface IOpenConfiguration {
contextWindowId?: number;
cli: ParsedArgs;
userEnv?: IProcessEnvironment;
pathsToOpen?: string[];
pathsToOpen?: URI[];
preferNewWindow?: boolean;
forceNewWindow?: boolean;
forceReuseWindow?: boolean;
......
......@@ -19,7 +19,7 @@ import { IURLService, IURLHandler } from 'vs/platform/url/common/url';
import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
import { IWindowsMainService, ISharedProcess } from 'vs/platform/windows/electron-main/windows';
import { IHistoryMainService, IRecentlyOpened } from 'vs/platform/history/common/history';
import { IWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier2 } from 'vs/platform/workspaces/common/workspaces';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
import { Schemas } from 'vs/base/common/network';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
......@@ -233,7 +233,7 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
return TPromise.as(null);
}
removeFromRecentlyOpened(paths: string[]): TPromise<void> {
removeFromRecentlyOpened(paths: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | string)[]): TPromise<void> {
this.logService.trace('windowsService#removeFromRecentlyOpened');
this.historyService.removeFromRecentlyOpened(paths);
......@@ -252,7 +252,7 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
const codeWindow = this.windowsMainService.getWindowById(windowId);
if (codeWindow) {
return TPromise.as(this.historyService.getRecentlyOpened(codeWindow.config.workspace || codeWindow.config.folderPath, codeWindow.config.filesToOpen));
return TPromise.as(this.historyService.getRecentlyOpened(codeWindow.config.workspace || codeWindow.config.folderUri, codeWindow.config.filesToOpen));
}
return TPromise.as(this.historyService.getRecentlyOpened());
......@@ -392,7 +392,7 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
return TPromise.as(null);
}
openWindow(windowId: number, paths: string[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean }): TPromise<void> {
openWindow(windowId: number, paths: URI[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean }): TPromise<void> {
this.logService.trace('windowsService#openWindow');
if (!paths || !paths.length) {
return TPromise.as(null);
......@@ -428,10 +428,10 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
return TPromise.as(null);
}
getWindows(): TPromise<{ id: number; workspace?: IWorkspaceIdentifier; folderPath?: string; title: string; filename?: string; }[]> {
getWindows(): TPromise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: string; title: string; filename?: string; }[]> {
this.logService.trace('windowsService#getWindows');
const windows = this.windowsMainService.getWindows();
const result = windows.map(w => ({ id: w.id, workspace: w.openedWorkspace, openedFolderPath: w.openedFolderPath, title: w.win.getTitle(), filename: w.getRepresentedFilename() }));
const result = windows.map(w => ({ id: w.id, workspace: w.openedWorkspace, openedFolderUri: w.openedFolderUri, title: w.win.getTitle(), filename: w.getRepresentedFilename() }));
return TPromise.as(result);
}
......@@ -563,7 +563,7 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
private openFileForURI(uri: URI): TPromise<boolean> {
const cli = assign(Object.create(null), this.environmentService.args, { goto: true });
const pathsToOpen = [uri.fsPath];
const pathsToOpen = [uri];
this.windowsMainService.open({ context: OpenContext.API, cli, pathsToOpen });
return TPromise.wrap(true);
......
......@@ -10,7 +10,7 @@ import * as resources from 'vs/base/common/resources';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { TernarySearchTree } from 'vs/base/common/map';
import { Event } from 'vs/base/common/event';
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier, IStoredWorkspaceFolder, isRawFileWorkspaceFolder, isRawUriWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, IStoredWorkspaceFolder, isRawFileWorkspaceFolder, isRawUriWorkspaceFolder, ISingleFolderWorkspaceIdentifier2 } from 'vs/platform/workspaces/common/workspaces';
import { coalesce, distinct } from 'vs/base/common/arrays';
import { isLinux } from 'vs/base/common/platform';
......@@ -69,7 +69,7 @@ export interface IWorkspaceContextService {
/**
* Return `true` if the current workspace has the given identifier otherwise `false`.
*/
isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean;
isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier2 | IWorkspaceIdentifier): boolean;
/**
* Returns if the provided resource is inside the workspace or not.
......
......@@ -13,9 +13,10 @@ import { basename, dirname, join } from 'vs/base/common/paths';
import { isLinux } from 'vs/base/common/platform';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { Event } from 'vs/base/common/event';
import { tildify, getPathLabel } from 'vs/base/common/labels';
import { tildify, getPathLabel, getBaseLabel } from 'vs/base/common/labels';
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import URI from 'vs/base/common/uri';
import { Schemas } from 'vs/base/common/network';
export const IWorkspacesMainService = createDecorator<IWorkspacesMainService>('workspacesMainService');
export const IWorkspacesService = createDecorator<IWorkspacesService>('workspacesService');
......@@ -27,7 +28,7 @@ export const UNTITLED_WORKSPACE_NAME = 'workspace.json';
/**
* A single folder workspace identifier is just the path to the folder.
*/
export type ISingleFolderWorkspaceIdentifier = string;
export type ISingleFolderWorkspaceIdentifier2 = URI;
export interface IWorkspaceIdentifier {
id: string;
......@@ -111,11 +112,17 @@ export interface IWorkspacesService {
createWorkspace(folders?: IWorkspaceFolderCreationData[]): TPromise<IWorkspaceIdentifier>;
}
export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), environmentService: IEnvironmentService, options?: { verbose: boolean }): string {
export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2), environmentService: IEnvironmentService, options?: { verbose: boolean }): string {
// Workspace: Single Folder
if (isSingleFolderWorkspaceIdentifier(workspace)) {
return tildify(workspace, environmentService.userHome);
if (isSingleFolderWorkspaceIdentifier2(workspace)) {
// Folder on disk
if (workspace.scheme === Schemas.file) {
return tildify(workspace.fsPath, environmentService.userHome);
}
// Remote folder
return getBaseLabel(workspace);
}
// Workspace: Untitled
......@@ -133,8 +140,8 @@ export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFold
return localize('workspaceName', "{0} (Workspace)", workspaceName);
}
export function isSingleFolderWorkspaceIdentifier(obj: any): obj is ISingleFolderWorkspaceIdentifier {
return typeof obj === 'string';
export function isSingleFolderWorkspaceIdentifier2(obj: any): obj is ISingleFolderWorkspaceIdentifier2 {
return obj instanceof URI;
}
export function isWorkspaceIdentifier(obj: any): obj is IWorkspaceIdentifier {
......
......@@ -19,6 +19,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL, PICK_WORKSPACE_FOLDER_COMMAND_ID, defaultWorkspacePath, defaultFilePath, defaultFolderPath } from 'vs/workbench/browser/actions/workspaceCommands';
import URI from 'vs/base/common/uri';
export class OpenFileAction extends Action {
......@@ -239,7 +240,7 @@ export class DuplicateWorkspaceInNewWindowAction extends Action {
return this.workspacesService.createWorkspace(folders).then(newWorkspace => {
return this.workspaceEditingService.copyWorkspaceSettings(newWorkspace).then(() => {
return this.windowService.openWindow([newWorkspace.configPath], { forceNewWindow: true });
return this.windowService.openWindow([URI.file(newWorkspace.configPath)], { forceNewWindow: true });
});
});
}
......
......@@ -290,16 +290,16 @@ export class ResourcesDropHandler {
// Pass focus to window
this.windowService.focusWindow();
let workspacesToOpen: TPromise<string[]>;
let workspacesToOpen: TPromise<URI[]>;
// Open in separate windows if we drop workspaces or just one folder
if (workspaces.length > 0 || folders.length === 1) {
workspacesToOpen = TPromise.as([...workspaces, ...folders].map(resources => resources.fsPath));
workspacesToOpen = TPromise.as([...workspaces, ...folders].map(resources => resources));
}
// Multiple folders: Create new workspace with folders and open
else if (folders.length > 1) {
workspacesToOpen = this.workspacesService.createWorkspace(folders.map(folder => ({ uri: folder }))).then(workspace => [workspace.configPath]);
workspacesToOpen = this.workspacesService.createWorkspace(folders.map(folder => ({ uri: folder }))).then(workspace => [URI.file(workspace.configPath)]);
}
// Open
......
......@@ -29,11 +29,12 @@ import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { domEvent } from 'vs/base/browser/event';
import { IRecentlyOpened } from 'vs/platform/history/common/history';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, getWorkspaceLabel } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier2, isSingleFolderWorkspaceIdentifier2, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { getPathLabel } from 'vs/base/common/labels';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { RunOnceScheduler } from 'vs/base/common/async';
import { MENUBAR_SELECTION_FOREGROUND, MENUBAR_SELECTION_BACKGROUND, MENUBAR_SELECTION_BORDER, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, MENU_BACKGROUND, MENU_FOREGROUND, MENU_SELECTION_BACKGROUND, MENU_SELECTION_FOREGROUND, MENU_SELECTION_BORDER } from 'vs/workbench/common/theme';
import URI from 'vs/base/common/uri';
interface CustomMenu {
title: string;
......@@ -508,23 +509,26 @@ export class MenubarPart extends Part {
return this.currentEnableMenuBarMnemonics ? label : label.replace(/&&(.)/g, '$1');
}
private createOpenRecentMenuAction(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): IAction {
private createOpenRecentMenuAction(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | string, commandId: string, isFile: boolean): IAction {
let label: string;
let path: string;
let uri: URI;
if (isSingleFolderWorkspaceIdentifier(workspace) || typeof workspace === 'string') {
if (isSingleFolderWorkspaceIdentifier2(workspace)) {
label = getPathLabel(workspace, this.environmentService);
path = workspace;
} else {
uri = workspace;
} else if (isWorkspaceIdentifier(workspace)) {
label = getWorkspaceLabel(workspace, this.environmentService, { verbose: true });
path = workspace.configPath;
uri = URI.file(workspace.configPath);
} else {
label = getPathLabel(workspace, this.environmentService);
uri = URI.file(workspace);
}
return new Action(commandId, label, undefined, undefined, (event) => {
const openInNewWindow = event && ((!isMacintosh && (event.ctrlKey || event.shiftKey)) || (isMacintosh && (event.metaKey || event.altKey)));
return this.windowService.openWindow([path], {
return this.windowService.openWindow([uri], {
forceNewWindow: openInNewWindow,
forceOpenWorkspaceAsFile: isFile
});
......
......@@ -36,7 +36,7 @@ import { webFrame, shell } from 'electron';
import { getPathLabel, getBaseLabel } from 'vs/base/common/labels';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { IPanel } from 'vs/workbench/common/panel';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier2, isSingleFolderWorkspaceIdentifier2, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { FileKind } from 'vs/platform/files/common/files';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IExtensionService, ActivationTimes } from 'vs/workbench/services/extensions/common/extensions';
......@@ -721,24 +721,28 @@ export abstract class BaseOpenRecentAction extends Action {
.then(({ workspaces, files }) => this.openRecent(workspaces, files));
}
private openRecent(recentWorkspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[], recentFiles: string[]): void {
private openRecent(recentWorkspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2)[], recentFiles: string[]): void {
function toPick(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier, separator: ISeparator, fileKind: FileKind, environmentService: IEnvironmentService, removeAction?: RemoveFromRecentlyOpened): IFilePickOpenEntry {
let path: string;
function toPick(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | string, separator: ISeparator, fileKind: FileKind, environmentService: IEnvironmentService, removeAction?: RemoveFromRecentlyOpened): IFilePickOpenEntry {
let resource: URI;
let label: string;
let description: string;
if (isSingleFolderWorkspaceIdentifier(workspace)) {
path = workspace;
label = getBaseLabel(path);
description = getPathLabel(paths.dirname(path), environmentService);
} else {
path = workspace.configPath;
if (isSingleFolderWorkspaceIdentifier2(workspace)) {
resource = workspace;
label = getBaseLabel(resource);
description = getPathLabel(paths.dirname(resource.path), environmentService);
} else if (isWorkspaceIdentifier(workspace)) {
resource = URI.file(workspace.configPath);
label = getWorkspaceLabel(workspace, environmentService);
description = getPathLabel(paths.dirname(workspace.configPath), environmentService);
} else {
resource = URI.file(workspace);
label = getBaseLabel(workspace);
description = getPathLabel(paths.dirname(workspace), environmentService);
}
return {
resource: URI.file(path),
resource,
fileKind,
label,
description,
......@@ -747,19 +751,19 @@ export abstract class BaseOpenRecentAction extends Action {
setTimeout(() => {
// Bug: somehow when not running this code in a timeout, it is not possible to use this picker
// with quick navigate keys (not able to trigger quick navigate once running it once).
runPick(path, fileKind === FileKind.FILE, context);
runPick(resource, fileKind === FileKind.FILE, context);
});
},
action: removeAction
};
}
const runPick = (path: string, isFile: boolean, context: IEntryRunContext) => {
const runPick = (resource: URI, isFile: boolean, context: IEntryRunContext) => {
const forceNewWindow = context.keymods.ctrlCmd;
this.windowService.openWindow([path], { forceNewWindow, forceOpenWorkspaceAsFile: isFile });
this.windowService.openWindow([resource], { forceNewWindow, forceOpenWorkspaceAsFile: isFile });
};
const workspacePicks: IFilePickOpenEntry[] = recentWorkspaces.map((workspace, index) => toPick(workspace, index === 0 ? { label: nls.localize('workspaces', "workspaces") } : void 0, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, !this.isQuickNavigate() ? this.removeAction : void 0));
const workspacePicks: IFilePickOpenEntry[] = recentWorkspaces.map((workspace, index) => toPick(workspace, index === 0 ? { label: nls.localize('workspaces', "workspaces") } : void 0, isSingleFolderWorkspaceIdentifier2(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, !this.isQuickNavigate() ? this.removeAction : void 0));
const filePicks: IFilePickOpenEntry[] = recentFiles.map((p, index) => toPick(p, index === 0 ? { label: nls.localize('files', "files"), border: true } : void 0, FileKind.FILE, this.environmentService, !this.isQuickNavigate() ? this.removeAction : void 0));
// focus second entry if the first recent workspace is the current workspace
......
......@@ -19,6 +19,7 @@ import { range } from 'vs/base/common/arrays';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { ITree } from 'vs/base/parts/tree/browser/tree';
import { InEditorZenModeContext, NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench/common/editor';
import { ISingleFolderWorkspaceIdentifier2 } from 'vs/platform/workspaces/common/workspaces';
// --- List Commands
......@@ -548,7 +549,7 @@ export function registerCommands(): void {
win: { primary: void 0 }
});
CommandsRegistry.registerCommand('_workbench.removeFromRecentlyOpened', function (accessor: ServicesAccessor, path: string) {
CommandsRegistry.registerCommand('_workbench.removeFromRecentlyOpened', function (accessor: ServicesAccessor, path: string | ISingleFolderWorkspaceIdentifier2) {
const windowsService = accessor.get(IWindowsService);
return windowsService.removeFromRecentlyOpened([path]).then(() => void 0);
......
......@@ -39,7 +39,7 @@ import { IUpdateService } from 'vs/platform/update/common/update';
import { URLHandlerChannel, URLServiceChannelClient } from 'vs/platform/url/common/urlIpc';
import { IURLService } from 'vs/platform/url/common/url';
import { WorkspacesChannelClient } from 'vs/platform/workspaces/common/workspacesIpc';
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspacesService, ISingleFolderWorkspaceIdentifier2 } from 'vs/platform/workspaces/common/workspaces';
import { createSpdLogService } from 'vs/platform/log/node/spdlogService';
import * as fs from 'fs';
import { ConsoleLogService, MultiplexLogService, ILogService } from 'vs/platform/log/common/log';
......@@ -116,7 +116,7 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise<void> {
}
function createAndInitializeWorkspaceService(configuration: IWindowConfiguration, environmentService: EnvironmentService): TPromise<WorkspaceService> {
const folderUri = configuration.folderPath ? uri.file(configuration.folderPath) /* TODO:Sandy Change to URI.parse once main sends URIs*/ : null;
const folderUri = configuration.folderUri ? uri.revive(configuration.folderUri) : null;
return validateFolderUri(folderUri, configuration.verbose).then(validatedFolderUri => {
const workspaceService = new WorkspaceService(environmentService);
......@@ -125,7 +125,7 @@ function createAndInitializeWorkspaceService(configuration: IWindowConfiguration
});
}
function validateFolderUri(folderUri: uri, verbose: boolean): TPromise<uri> {
function validateFolderUri(folderUri: ISingleFolderWorkspaceIdentifier2, verbose: boolean): TPromise<uri> {
// Return early if we do not have a single folder uri or if it is a non file uri
if (!folderUri || folderUri.scheme !== Schemas.file) {
......
......@@ -66,7 +66,7 @@ export class ElectronWindow extends Themable {
private previousConfiguredZoomLevel: number;
private addFoldersScheduler: RunOnceScheduler;
private pendingFoldersToAdd: IAddFoldersRequest[];
private pendingFoldersToAdd: URI[];
constructor(
@IEditorService private editorService: EditorServiceImpl,
......@@ -404,7 +404,7 @@ export class ElectronWindow extends Themable {
private onAddFoldersRequest(request: IAddFoldersRequest): void {
// Buffer all pending requests
this.pendingFoldersToAdd.push(request);
this.pendingFoldersToAdd.push(...request.foldersToAdd.map(f => URI.revive(f)));
// Delay the adding of folders a bit to buffer in case more requests are coming
if (!this.addFoldersScheduler.isScheduled()) {
......@@ -415,8 +415,8 @@ export class ElectronWindow extends Themable {
private doAddFolders(): void {
const foldersToAdd: IWorkspaceFolderCreationData[] = [];
this.pendingFoldersToAdd.forEach(request => {
foldersToAdd.push(...request.foldersToAdd.map(folderToAdd => ({ uri: URI.file(folderToAdd.filePath) })));
this.pendingFoldersToAdd.forEach(folder => {
foldersToAdd.push(({ uri: folder }));
});
this.pendingFoldersToAdd = [];
......
......@@ -1443,7 +1443,7 @@ export class ShowOpenedFileInNewWindow extends Action {
public run(): TPromise<any> {
const fileResource = toResource(this.editorService.activeEditor, { supportSideBySide: true, filter: Schemas.file /* todo@remote */ });
if (fileResource) {
this.windowService.openWindow([fileResource.fsPath], { forceNewWindow: true, forceOpenWorkspaceAsFile: true });
this.windowService.openWindow([fileResource], { forceNewWindow: true, forceOpenWorkspaceAsFile: true });
} else {
this.notificationService.info(nls.localize('openFileToShowInNewWindow', "Open a file first to open in new window"));
}
......
......@@ -81,8 +81,7 @@ export const REMOVE_ROOT_FOLDER_LABEL = nls.localize('removeFolderFromWorkspace'
export const openWindowCommand = (accessor: ServicesAccessor, paths: string[], forceNewWindow: boolean) => {
const windowService = accessor.get(IWindowService);
windowService.openWindow(paths, { forceNewWindow });
windowService.openWindow(paths.map(path => URI.file(path)), { forceNewWindow });
};
function save(
......
......@@ -34,7 +34,7 @@ import { registerColor, focusBorder, textLinkForeground, textLinkActiveForegroun
import { getExtraColor } from 'vs/workbench/parts/welcome/walkThrough/node/walkThroughUtils';
import { IExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/common/extensions';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier2, isSingleFolderWorkspaceIdentifier2, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IEditorInputFactory, EditorInput } from 'vs/workbench/common/editor';
import { getIdAndVersionFromLocalExtensionId } from 'vs/platform/extensionManagement/node/extensionManagementUtil';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
......@@ -256,7 +256,7 @@ class WelcomePage {
return this.editorService.openEditor(this.editorInput, { pinned: false });
}
private onReady(container: HTMLElement, recentlyOpened: TPromise<{ files: string[]; workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[]; }>, installedExtensions: TPromise<IExtensionStatus[]>): void {
private onReady(container: HTMLElement, recentlyOpened: TPromise<{ files: string[]; workspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2)[]; }>, installedExtensions: TPromise<IExtensionStatus[]>): void {
const enabled = isWelcomePageEnabled(this.configurationService);
const showOnStartup = <HTMLInputElement>container.querySelector('#showOnStartup');
if (enabled) {
......@@ -279,15 +279,19 @@ class WelcomePage {
workspaces.slice(0, 5).forEach(workspace => {
let label: string;
let parent: string;
let wsPath: string;
if (isSingleFolderWorkspaceIdentifier(workspace)) {
label = getBaseLabel(workspace);
parent = path.dirname(workspace);
wsPath = workspace;
} else {
let resource: URI;
if (isSingleFolderWorkspaceIdentifier2(workspace)) {
resource = workspace;
label = getBaseLabel(resource);
parent = path.dirname(resource.path);
} else if (isWorkspaceIdentifier(workspace)) {
label = getWorkspaceLabel(workspace, this.environmentService);
parent = path.dirname(workspace.configPath);
wsPath = workspace.configPath;
resource = URI.file(workspace.configPath);
} else {
label = getBaseLabel(workspace);
parent = path.dirname(workspace);
resource = URI.file(workspace);
}
const li = document.createElement('li');
......@@ -317,7 +321,7 @@ class WelcomePage {
id: 'openRecentFolder',
from: telemetryFrom
});
this.windowService.openWindow([wsPath], { forceNewWindow: e.ctrlKey || e.metaKey });
this.windowService.openWindow([resource], { forceNewWindow: e.ctrlKey || e.metaKey });
e.preventDefault();
e.stopPropagation();
});
......
......@@ -26,7 +26,7 @@ import { IWorkspaceConfigurationService, FOLDER_CONFIG_FOLDER_NAME, defaultSetti
import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationNode, IConfigurationRegistry, Extensions, IConfigurationPropertySchema, allSettings, windowSettings, resourceSettings, applicationSettings } from 'vs/platform/configuration/common/configurationRegistry';
import { createHash } from 'crypto';
import { getWorkspaceLabel, IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
import { getWorkspaceLabel, IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier2, isSingleFolderWorkspaceIdentifier2 } from 'vs/platform/workspaces/common/workspaces';
import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { ICommandService } from 'vs/platform/commands/common/commands';
......@@ -41,7 +41,7 @@ import { UserConfiguration } from 'vs/platform/configuration/node/configuration'
import { getBaseLabel } from 'vs/base/common/labels';
import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema';
import { localize } from 'vs/nls';
import { isEqual } from 'vs/base/common/resources';
import { isEqual, hasToIgnoreCase } from 'vs/base/common/resources';
export class WorkspaceService extends Disposable implements IWorkspaceConfigurationService, IWorkspaceContextService {
......@@ -129,21 +129,16 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
return !!this.getWorkspaceFolder(resource);
}
public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean {
public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier2 | IWorkspaceIdentifier): boolean {
switch (this.getWorkbenchState()) {
case WorkbenchState.FOLDER:
return isSingleFolderWorkspaceIdentifier(workspaceIdentifier) && isEqual(this.workspace.folders[0].uri, this.toUri(workspaceIdentifier), this.workspace.folders[0].uri.scheme !== Schemas.file || !isLinux);
return isSingleFolderWorkspaceIdentifier2(workspaceIdentifier) && isEqual(workspaceIdentifier, this.workspace.folders[0].uri, hasToIgnoreCase(workspaceIdentifier));
case WorkbenchState.WORKSPACE:
return isWorkspaceIdentifier(workspaceIdentifier) && this.workspace.id === workspaceIdentifier.id;
}
return false;
}
private toUri(folderIdentifier: ISingleFolderWorkspaceIdentifier): URI {
// TODO:Sandy Change to URI.parse parsing once main sends URIs
return URI.file(folderIdentifier);
}
private doUpdateFolders(foldersToAdd: IWorkspaceFolderCreationData[], foldersToRemove: URI[], index?: number): TPromise<void> {
if (this.getWorkbenchState() !== WorkbenchState.WORKSPACE) {
return TPromise.as(void 0); // we need a workspace to begin with
......@@ -301,7 +296,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
return this._configuration.keys();
}
initialize(arg: IWorkspaceIdentifier | URI | IWindowConfiguration, postInitialisationTask: () => void = () => null): TPromise<any> {
initialize(arg: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier2 | IWindowConfiguration, postInitialisationTask: () => void = () => null): TPromise<any> {
return this.createWorkspace(arg)
.then(workspace => this.updateWorkspaceAndInitializeConfiguration(workspace, postInitialisationTask));
}
......@@ -333,7 +328,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
return this.createMulitFolderWorkspace(arg);
}
if (arg instanceof URI) {
if (isSingleFolderWorkspaceIdentifier2(arg)) {
return this.createSingleFolderWorkspace(arg);
}
......
......@@ -124,11 +124,11 @@ suite('WorkspaceContextService - Folder', () => {
});
test('isCurrentWorkspace() => true', () => {
assert.ok(workspaceContextService.isCurrentWorkspace(workspaceResource));
assert.ok(workspaceContextService.isCurrentWorkspace(URI.file(workspaceResource)));
});
test('isCurrentWorkspace() => false', () => {
assert.ok(!workspaceContextService.isCurrentWorkspace(workspaceResource + 'abc'));
assert.ok(!workspaceContextService.isCurrentWorkspace(URI.file(workspaceResource + 'abc')));
});
});
......
......@@ -49,7 +49,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
import { isLinux } from 'vs/base/common/platform';
import { generateUuid } from 'vs/base/common/uuid';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
import { IWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier2 } from 'vs/platform/workspaces/common/workspaces';
import { IRecentlyOpened } from 'vs/platform/history/common/history';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
import { IPosition, Position as EditorPosition } from 'vs/editor/common/core/position';
......@@ -159,7 +159,7 @@ export class TestContextService implements IWorkspaceContextService {
return URI.file(paths.join('C:\\', workspaceRelativePath));
}
public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean {
public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier2 | IWorkspaceIdentifier): boolean {
return isSingleFolderWorkspaceIdentifier(workspaceIdentifier) && this.pathEquals(this.workspace.folders[0].uri.fsPath, workspaceIdentifier);
}
......@@ -1064,7 +1064,7 @@ export class TestWindowService implements IWindowService {
return TPromise.as(void 0);
}
openWindow(paths: string[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean }): TPromise<void> {
openWindow(paths: URI[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean }): TPromise<void> {
return TPromise.as(void 0);
}
......@@ -1266,7 +1266,7 @@ export class TestWindowsService implements IWindowsService {
}
// Global methods
openWindow(windowId: number, paths: string[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean }): TPromise<void> {
openWindow(windowId: number, paths: URI[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean }): TPromise<void> {
return TPromise.as(void 0);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册