|
|
|
|
@@ -8,22 +8,45 @@
|
|
|
|
|
import { TPromise } from 'vs/base/common/winjs.base';
|
|
|
|
|
import { Action } from 'vs/base/common/actions';
|
|
|
|
|
import nls = require('vs/nls');
|
|
|
|
|
import { distinct } from 'vs/base/common/arrays';
|
|
|
|
|
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
|
|
|
|
|
import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
|
|
|
|
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
|
|
|
|
import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
|
|
|
|
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
|
|
|
|
|
import URI from 'vs/base/common/uri';
|
|
|
|
|
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
|
|
|
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
|
|
|
|
import { IWorkspacesService, WORKSPACE_FILTER } from 'vs/platform/workspaces/common/workspaces';
|
|
|
|
|
import { IMessageService, Severity } from 'vs/platform/message/common/message';
|
|
|
|
|
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
|
|
|
|
import { WORKSPACE_FILTER, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
|
|
|
|
|
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
|
|
|
|
import { isLinux } from 'vs/base/common/platform';
|
|
|
|
|
import { dirname } from 'vs/base/common/paths';
|
|
|
|
|
import { mnemonicButtonLabel } from 'vs/base/common/labels';
|
|
|
|
|
import { isParent } from 'vs/platform/files/common/files';
|
|
|
|
|
import * as resources from 'vs/base/common/resources';
|
|
|
|
|
import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels';
|
|
|
|
|
import { isParent, FileKind } from 'vs/platform/files/common/files';
|
|
|
|
|
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
|
|
|
|
import { IQuickOpenService, IFilePickOpenEntry, IPickOptions } from 'vs/platform/quickOpen/common/quickOpen';
|
|
|
|
|
import { CancellationToken } from 'vs/base/common/cancellation';
|
|
|
|
|
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
|
|
|
|
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
|
|
|
|
|
|
|
|
|
export class OpenFileAction extends Action {
|
|
|
|
|
|
|
|
|
|
static ID = 'workbench.action.files.openFile';
|
|
|
|
|
static LABEL = nls.localize('openFile', "Open File...");
|
|
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
|
id: string,
|
|
|
|
|
label: string,
|
|
|
|
|
@IWindowService private windowService: IWindowService,
|
|
|
|
|
@IHistoryService private historyService: IHistoryService,
|
|
|
|
|
@IWorkspaceContextService private contextService: IWorkspaceContextService
|
|
|
|
|
) {
|
|
|
|
|
super(id, label);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run(event?: any, data?: ITelemetryData): TPromise<any> {
|
|
|
|
|
return this.windowService.pickFileAndOpen({ telemetryExtraData: data, dialogOptions: { defaultPath: defaultFilePath(this.contextService, this.historyService) } });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class OpenFolderAction extends Action {
|
|
|
|
|
|
|
|
|
|
@@ -33,13 +56,15 @@ export class OpenFolderAction extends Action {
|
|
|
|
|
constructor(
|
|
|
|
|
id: string,
|
|
|
|
|
label: string,
|
|
|
|
|
@IWindowService private windowService: IWindowService
|
|
|
|
|
@IWindowService private windowService: IWindowService,
|
|
|
|
|
@IHistoryService private historyService: IHistoryService,
|
|
|
|
|
@IWorkspaceContextService private contextService: IWorkspaceContextService
|
|
|
|
|
) {
|
|
|
|
|
super(id, label);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run(event?: any, data?: ITelemetryData): TPromise<any> {
|
|
|
|
|
return this.windowService.pickFolderAndOpen({ telemetryExtraData: data });
|
|
|
|
|
return this.windowService.pickFolderAndOpen({ telemetryExtraData: data, dialogOptions: { defaultPath: defaultFolderPath(this.contextService, this.historyService) } });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -51,16 +76,57 @@ export class OpenFileFolderAction extends Action {
|
|
|
|
|
constructor(
|
|
|
|
|
id: string,
|
|
|
|
|
label: string,
|
|
|
|
|
@IWindowService private windowService: IWindowService
|
|
|
|
|
@IWindowService private windowService: IWindowService,
|
|
|
|
|
@IHistoryService private historyService: IHistoryService,
|
|
|
|
|
@IWorkspaceContextService private contextService: IWorkspaceContextService
|
|
|
|
|
) {
|
|
|
|
|
super(id, label);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run(event?: any, data?: ITelemetryData): TPromise<any> {
|
|
|
|
|
return this.windowService.pickFileFolderAndOpen({ telemetryExtraData: data });
|
|
|
|
|
return this.windowService.pickFileFolderAndOpen({ telemetryExtraData: data, dialogOptions: { defaultPath: defaultFilePath(this.contextService, this.historyService) } });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const openFileFolderInNewWindowCommand = (accessor: ServicesAccessor) => {
|
|
|
|
|
const { windowService, historyService, contextService } = services(accessor);
|
|
|
|
|
|
|
|
|
|
windowService.pickFileFolderAndOpen({ forceNewWindow: true, dialogOptions: { defaultPath: defaultFilePath(contextService, historyService) } });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const openFolderCommand = (accessor: ServicesAccessor, forceNewWindow: boolean) => {
|
|
|
|
|
const { windowService, historyService, contextService } = services(accessor);
|
|
|
|
|
|
|
|
|
|
windowService.pickFolderAndOpen({ forceNewWindow, dialogOptions: { defaultPath: defaultFolderPath(contextService, historyService) } });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const openFolderInNewWindowCommand = (accessor: ServicesAccessor) => {
|
|
|
|
|
const { windowService, historyService, contextService } = services(accessor);
|
|
|
|
|
|
|
|
|
|
windowService.pickFolderAndOpen({ forceNewWindow: true, dialogOptions: { defaultPath: defaultFolderPath(contextService, historyService) } });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const openFileInNewWindowCommand = (accessor: ServicesAccessor) => {
|
|
|
|
|
const { windowService, historyService, contextService } = services(accessor);
|
|
|
|
|
|
|
|
|
|
windowService.pickFileAndOpen({ forceNewWindow: true, dialogOptions: { defaultPath: defaultFilePath(contextService, historyService) } });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const openWorkspaceInNewWindowCommand = (accessor: ServicesAccessor) => {
|
|
|
|
|
const { windowService, historyService, contextService, environmentService } = services(accessor);
|
|
|
|
|
|
|
|
|
|
windowService.pickWorkspaceAndOpen({ forceNewWindow: true, dialogOptions: { defaultPath: defaultWorkspacePath(contextService, historyService, environmentService) } });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function services(accessor: ServicesAccessor): { windowService: IWindowService, historyService: IHistoryService, contextService: IWorkspaceContextService, environmentService: IEnvironmentService } {
|
|
|
|
|
return {
|
|
|
|
|
windowService: accessor.get(IWindowService),
|
|
|
|
|
historyService: accessor.get(IHistoryService),
|
|
|
|
|
contextService: accessor.get(IWorkspaceContextService),
|
|
|
|
|
environmentService: accessor.get(IEnvironmentService)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export abstract class BaseWorkspacesAction extends Action {
|
|
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
|
@@ -68,27 +134,65 @@ export abstract class BaseWorkspacesAction extends Action {
|
|
|
|
|
label: string,
|
|
|
|
|
protected windowService: IWindowService,
|
|
|
|
|
protected environmentService: IEnvironmentService,
|
|
|
|
|
protected contextService: IWorkspaceContextService
|
|
|
|
|
protected contextService: IWorkspaceContextService,
|
|
|
|
|
protected historyService: IHistoryService
|
|
|
|
|
) {
|
|
|
|
|
super(id, label);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected pickFolders(buttonLabel: string, title: string): string[] {
|
|
|
|
|
const workspace = this.contextService.getWorkspace();
|
|
|
|
|
let defaultPath: string;
|
|
|
|
|
if (workspace && workspace.roots.length > 0) {
|
|
|
|
|
defaultPath = dirname(workspace.roots[0].fsPath); // pick the parent of the first root by default
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.windowService.showOpenDialog({
|
|
|
|
|
buttonLabel,
|
|
|
|
|
title,
|
|
|
|
|
properties: ['multiSelections', 'openDirectory', 'createDirectory'],
|
|
|
|
|
defaultPath
|
|
|
|
|
defaultPath: defaultFolderPath(this.contextService, this.historyService)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function defaultFilePath(contextService: IWorkspaceContextService, historyService: IHistoryService): string {
|
|
|
|
|
let candidate: URI;
|
|
|
|
|
|
|
|
|
|
// Check for last active file first...
|
|
|
|
|
candidate = historyService.getLastActiveFile();
|
|
|
|
|
|
|
|
|
|
// ...then for last active file root
|
|
|
|
|
if (!candidate) {
|
|
|
|
|
candidate = historyService.getLastActiveWorkspaceRoot('file');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return candidate ? dirname(candidate.fsPath) : void 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function defaultFolderPath(contextService: IWorkspaceContextService, historyService: IHistoryService): string {
|
|
|
|
|
let candidate: URI;
|
|
|
|
|
|
|
|
|
|
// Check for last active file root first...
|
|
|
|
|
candidate = historyService.getLastActiveWorkspaceRoot('file');
|
|
|
|
|
|
|
|
|
|
// ...then for last active file
|
|
|
|
|
if (!candidate) {
|
|
|
|
|
candidate = historyService.getLastActiveFile();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return candidate ? dirname(candidate.fsPath) : void 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function defaultWorkspacePath(contextService: IWorkspaceContextService, historyService: IHistoryService, environmentService: IEnvironmentService): string {
|
|
|
|
|
|
|
|
|
|
// Check for current workspace config file first...
|
|
|
|
|
if (contextService.getWorkbenchState() === WorkbenchState.WORKSPACE && !isUntitledWorkspace(contextService.getWorkspace().configuration.fsPath, environmentService)) {
|
|
|
|
|
return dirname(contextService.getWorkspace().configuration.fsPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ...then fallback to default folder path
|
|
|
|
|
return defaultFolderPath(contextService, historyService);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isUntitledWorkspace(path: string, environmentService: IEnvironmentService): boolean {
|
|
|
|
|
return isParent(path, environmentService.workspacesHome, !isLinux /* ignore case */);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class AddRootFolderAction extends BaseWorkspacesAction {
|
|
|
|
|
|
|
|
|
|
static ID = 'workbench.action.addRootFolder';
|
|
|
|
|
@@ -102,62 +206,56 @@ export class AddRootFolderAction extends BaseWorkspacesAction {
|
|
|
|
|
@IEnvironmentService environmentService: IEnvironmentService,
|
|
|
|
|
@IInstantiationService private instantiationService: IInstantiationService,
|
|
|
|
|
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
|
|
|
|
|
@IViewletService private viewletService: IViewletService
|
|
|
|
|
@IViewletService private viewletService: IViewletService,
|
|
|
|
|
@IHistoryService historyService: IHistoryService
|
|
|
|
|
) {
|
|
|
|
|
super(id, label, windowService, environmentService, contextService);
|
|
|
|
|
super(id, label, windowService, environmentService, contextService, historyService);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public run(): TPromise<any> {
|
|
|
|
|
if (!this.contextService.hasWorkspace()) {
|
|
|
|
|
return this.instantiationService.createInstance(NewWorkspaceAction, NewWorkspaceAction.ID, NewWorkspaceAction.LABEL, []).run();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.contextService.hasFolderWorkspace()) {
|
|
|
|
|
return this.instantiationService.createInstance(NewWorkspaceAction, NewWorkspaceAction.ID, NewWorkspaceAction.LABEL, this.contextService.getWorkspace().roots).run();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const folders = super.pickFolders(mnemonicButtonLabel(nls.localize({ key: 'add', comment: ['&& denotes a mnemonic'] }, "&&Add")), nls.localize('addFolderToWorkspaceTitle', "Add Folder to Workspace"));
|
|
|
|
|
if (!folders || !folders.length) {
|
|
|
|
|
return TPromise.as(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.workspaceEditingService.addRoots(folders.map(folder => URI.file(folder))).then(() => {
|
|
|
|
|
return this.viewletService.openViewlet(this.viewletService.getDefaultViewletId(), true);
|
|
|
|
|
});
|
|
|
|
|
// Add and show Files Explorer viewlet
|
|
|
|
|
return this.workspaceEditingService.addFolders(folders.map(folder => ({ uri: URI.file(folder) }))).then(() => this.viewletService.openViewlet(this.viewletService.getDefaultViewletId(), true));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class NewWorkspaceAction extends BaseWorkspacesAction {
|
|
|
|
|
export class GlobalRemoveRootFolderAction extends BaseWorkspacesAction {
|
|
|
|
|
|
|
|
|
|
static ID = 'workbench.action.newWorkspace';
|
|
|
|
|
static LABEL = nls.localize('newWorkspace', "New Workspace...");
|
|
|
|
|
static ID = 'workbench.action.removeRootFolder';
|
|
|
|
|
static LABEL = nls.localize('globalRemoveFolderFromWorkspace', "Remove Folder from Workspace...");
|
|
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
|
id: string,
|
|
|
|
|
label: string,
|
|
|
|
|
private presetRoots: URI[],
|
|
|
|
|
@IWindowService windowService: IWindowService,
|
|
|
|
|
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
|
|
|
|
@IEnvironmentService environmentService: IEnvironmentService,
|
|
|
|
|
@IWorkspacesService protected workspacesService: IWorkspacesService,
|
|
|
|
|
@IWindowsService protected windowsService: IWindowsService,
|
|
|
|
|
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
|
|
|
|
|
@ICommandService private commandService: ICommandService,
|
|
|
|
|
@IHistoryService historyService: IHistoryService
|
|
|
|
|
) {
|
|
|
|
|
super(id, label, windowService, environmentService, contextService);
|
|
|
|
|
super(id, label, windowService, environmentService, contextService, historyService);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public run(): TPromise<any> {
|
|
|
|
|
const folders = super.pickFolders(mnemonicButtonLabel(nls.localize({ key: 'select', comment: ['&& denotes a mnemonic'] }, "&&Select")), nls.localize('selectWorkspace', "Select Folders for Workspace"));
|
|
|
|
|
if (folders && folders.length) {
|
|
|
|
|
return this.createWorkspace([...this.presetRoots, ...folders.map(folder => URI.file(folder))]);
|
|
|
|
|
const state = this.contextService.getWorkbenchState();
|
|
|
|
|
|
|
|
|
|
// Workspace / Folder
|
|
|
|
|
if (state === WorkbenchState.WORKSPACE || state === WorkbenchState.FOLDER) {
|
|
|
|
|
return this.commandService.executeCommand<IWorkspaceFolder>(PICK_WORKSPACE_FOLDER_COMMAND).then(folder => {
|
|
|
|
|
if (folder) {
|
|
|
|
|
return this.workspaceEditingService.removeFolders([folder.uri]).then(() => true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TPromise.as(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private createWorkspace(folders: URI[]): TPromise<void> {
|
|
|
|
|
const workspaceFolders = distinct(folders.map(folder => folder.fsPath), folder => isLinux ? folder : folder.toLowerCase());
|
|
|
|
|
|
|
|
|
|
return this.windowService.createAndOpenWorkspace(workspaceFolders);
|
|
|
|
|
return TPromise.as(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -176,7 +274,29 @@ export class RemoveRootFolderAction extends Action {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public run(): TPromise<any> {
|
|
|
|
|
return this.workspaceEditingService.removeRoots([this.rootUri]);
|
|
|
|
|
return this.workspaceEditingService.removeFolders([this.rootUri]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class OpenFolderSettingsAction extends Action {
|
|
|
|
|
|
|
|
|
|
static ID = 'workbench.action.openFolderSettings';
|
|
|
|
|
static LABEL = nls.localize('openFolderSettings', "Open Folder Settings");
|
|
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
|
private rootUri: URI,
|
|
|
|
|
id: string,
|
|
|
|
|
label: string,
|
|
|
|
|
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
|
|
|
|
@ICommandService private commandService: ICommandService
|
|
|
|
|
) {
|
|
|
|
|
super(id, label);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public run(): TPromise<any> {
|
|
|
|
|
const workspaceFolder = this.contextService.getWorkspaceFolder(this.rootUri);
|
|
|
|
|
|
|
|
|
|
return this.commandService.executeCommand('_workbench.action.openFolderSettings', workspaceFolder);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -191,63 +311,37 @@ export class SaveWorkspaceAsAction extends BaseWorkspacesAction {
|
|
|
|
|
@IWindowService windowService: IWindowService,
|
|
|
|
|
@IEnvironmentService environmentService: IEnvironmentService,
|
|
|
|
|
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
|
|
|
|
@IWorkspacesService protected workspacesService: IWorkspacesService,
|
|
|
|
|
@IWindowsService private windowsService: IWindowsService,
|
|
|
|
|
@IMessageService private messageService: IMessageService
|
|
|
|
|
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
|
|
|
|
|
@IHistoryService historyService: IHistoryService
|
|
|
|
|
) {
|
|
|
|
|
super(id, label, windowService, environmentService, contextService);
|
|
|
|
|
super(id, label, windowService, environmentService, contextService, historyService);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public run(): TPromise<any> {
|
|
|
|
|
if (!this.contextService.hasWorkspace()) {
|
|
|
|
|
this.messageService.show(Severity.Info, nls.localize('saveEmptyWorkspaceNotSupported', "Please open a workspace first to save."));
|
|
|
|
|
return TPromise.as(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const configPath = this.getNewWorkspaceConfigPath();
|
|
|
|
|
if (configPath) {
|
|
|
|
|
if (this.contextService.hasFolderWorkspace()) {
|
|
|
|
|
return this.saveFolderWorkspace(configPath);
|
|
|
|
|
}
|
|
|
|
|
switch (this.contextService.getWorkbenchState()) {
|
|
|
|
|
case WorkbenchState.EMPTY:
|
|
|
|
|
case WorkbenchState.FOLDER:
|
|
|
|
|
const folders = this.contextService.getWorkspace().folders.map(folder => ({ uri: folder.uri }));
|
|
|
|
|
return this.workspaceEditingService.createAndEnterWorkspace(folders, configPath);
|
|
|
|
|
|
|
|
|
|
if (this.contextService.hasMultiFolderWorkspace()) {
|
|
|
|
|
return this.saveWorkspace(configPath);
|
|
|
|
|
case WorkbenchState.WORKSPACE:
|
|
|
|
|
return this.workspaceEditingService.saveAndEnterWorkspace(configPath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TPromise.as(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private saveWorkspace(configPath: string): TPromise<void> {
|
|
|
|
|
return this.windowService.saveAndOpenWorkspace(configPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private saveFolderWorkspace(configPath: string): TPromise<void> {
|
|
|
|
|
const workspaceFolders = this.contextService.getWorkspace().roots.map(root => root.fsPath);
|
|
|
|
|
|
|
|
|
|
return this.windowService.createAndOpenWorkspace(workspaceFolders, configPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private getNewWorkspaceConfigPath(): string {
|
|
|
|
|
const workspace = this.contextService.getWorkspace();
|
|
|
|
|
let defaultPath: string;
|
|
|
|
|
if (this.contextService.hasMultiFolderWorkspace() && !this.isUntitledWorkspace(workspace.configuration.fsPath)) {
|
|
|
|
|
defaultPath = workspace.configuration.fsPath;
|
|
|
|
|
} else if (workspace && workspace.roots.length > 0) {
|
|
|
|
|
defaultPath = dirname(workspace.roots[0].fsPath); // pick the parent of the first root by default
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.windowService.showSaveDialog({
|
|
|
|
|
buttonLabel: mnemonicButtonLabel(nls.localize({ key: 'save', comment: ['&& denotes a mnemonic'] }, "&&Save")),
|
|
|
|
|
title: nls.localize('saveWorkspace', "Save Workspace"),
|
|
|
|
|
filters: WORKSPACE_FILTER,
|
|
|
|
|
defaultPath
|
|
|
|
|
defaultPath: defaultWorkspacePath(this.contextService, this.historyService, this.environmentService)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private isUntitledWorkspace(path: string): boolean {
|
|
|
|
|
return isParent(path, this.environmentService.workspacesHome, !isLinux /* ignore case */);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class OpenWorkspaceAction extends Action {
|
|
|
|
|
@@ -259,12 +353,15 @@ export class OpenWorkspaceAction extends Action {
|
|
|
|
|
id: string,
|
|
|
|
|
label: string,
|
|
|
|
|
@IWindowService private windowService: IWindowService,
|
|
|
|
|
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
|
|
|
|
@IHistoryService private historyService: IHistoryService,
|
|
|
|
|
@IEnvironmentService private environmentService: IEnvironmentService
|
|
|
|
|
) {
|
|
|
|
|
super(id, label);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public run(): TPromise<any> {
|
|
|
|
|
return this.windowService.openWorkspace();
|
|
|
|
|
public run(event?: any, data?: ITelemetryData): TPromise<any> {
|
|
|
|
|
return this.windowService.pickWorkspaceAndOpen({ telemetryExtraData: data, dialogOptions: { defaultPath: defaultWorkspacePath(this.contextService, this.historyService, this.environmentService) } });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -281,10 +378,114 @@ export class OpenWorkspaceConfigFileAction extends Action {
|
|
|
|
|
) {
|
|
|
|
|
super(id, label);
|
|
|
|
|
|
|
|
|
|
this.enabled = this.workspaceContextService.hasMultiFolderWorkspace();
|
|
|
|
|
this.enabled = !!this.workspaceContextService.getWorkspace().configuration;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public run(): TPromise<any> {
|
|
|
|
|
return this.editorService.openEditor({ resource: this.workspaceContextService.getWorkspace().configuration });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class OpenFolderAsWorkspaceInNewWindowAction extends Action {
|
|
|
|
|
|
|
|
|
|
public static ID = 'workbench.action.openFolderAsWorkspaceInNewWindow';
|
|
|
|
|
public static LABEL = nls.localize('openFolderAsWorkspaceInNewWindow', "Open Folder as Workspace in New Window");
|
|
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
|
id: string,
|
|
|
|
|
label: string,
|
|
|
|
|
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
|
|
|
|
|
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
|
|
|
|
|
@IWindowsService private windowsService: IWindowsService,
|
|
|
|
|
@ICommandService private commandService: ICommandService,
|
|
|
|
|
@IWorkspacesService private workspacesService: IWorkspacesService
|
|
|
|
|
) {
|
|
|
|
|
super(id, label);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public run(): TPromise<any> {
|
|
|
|
|
const folders = this.workspaceContextService.getWorkspace().folders;
|
|
|
|
|
|
|
|
|
|
let folderPromise: TPromise<IWorkspaceFolder>;
|
|
|
|
|
if (folders.length === 0) {
|
|
|
|
|
folderPromise = TPromise.as(null);
|
|
|
|
|
} else if (folders.length === 1) {
|
|
|
|
|
folderPromise = TPromise.as(folders[0]);
|
|
|
|
|
} else {
|
|
|
|
|
folderPromise = this.commandService.executeCommand<IWorkspaceFolder>(PICK_WORKSPACE_FOLDER_COMMAND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return folderPromise.then(folder => {
|
|
|
|
|
if (!folder) {
|
|
|
|
|
return void 0; // need at least one folder
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.workspacesService.createWorkspace([{ uri: folder.uri }]).then(newWorkspace => {
|
|
|
|
|
return this.workspaceEditingService.copyWorkspaceSettings(newWorkspace).then(() => {
|
|
|
|
|
return this.windowsService.openWindow([newWorkspace.configPath], { forceNewWindow: true });
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const PICK_WORKSPACE_FOLDER_COMMAND = '_workbench.pickWorkspaceFolder';
|
|
|
|
|
|
|
|
|
|
CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND, function (accessor: ServicesAccessor, args?: [IPickOptions, CancellationToken]) {
|
|
|
|
|
const contextService = accessor.get(IWorkspaceContextService);
|
|
|
|
|
const quickOpenService = accessor.get(IQuickOpenService);
|
|
|
|
|
const environmentService = accessor.get(IEnvironmentService);
|
|
|
|
|
|
|
|
|
|
const folders = contextService.getWorkspace().folders;
|
|
|
|
|
if (!folders.length) {
|
|
|
|
|
return void 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const folderPicks = folders.map(folder => {
|
|
|
|
|
return {
|
|
|
|
|
label: folder.name,
|
|
|
|
|
description: getPathLabel(resources.dirname(folder.uri), void 0, environmentService),
|
|
|
|
|
folder,
|
|
|
|
|
resource: folder.uri,
|
|
|
|
|
fileKind: FileKind.ROOT_FOLDER
|
|
|
|
|
} as IFilePickOpenEntry;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let options: IPickOptions;
|
|
|
|
|
if (args) {
|
|
|
|
|
options = args[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!options) {
|
|
|
|
|
options = Object.create(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!options.autoFocus) {
|
|
|
|
|
options.autoFocus = { autoFocusFirstEntry: true };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!options.placeHolder) {
|
|
|
|
|
options.placeHolder = nls.localize('workspaceFolderPickerPlaceholder', "Select workspace folder");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typeof options.matchOnDescription !== 'boolean') {
|
|
|
|
|
options.matchOnDescription = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let token: CancellationToken;
|
|
|
|
|
if (args) {
|
|
|
|
|
token = args[1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!token) {
|
|
|
|
|
token = CancellationToken.None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return quickOpenService.pick(folderPicks, options, token).then(pick => {
|
|
|
|
|
if (!pick) {
|
|
|
|
|
return void 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return folders[folderPicks.indexOf(pick)];
|
|
|
|
|
});
|
|
|
|
|
});
|