Refresh master with initial release/0.24 snapshot (#332)

* Initial port of release/0.24 source code

* Fix additional headers

* Fix a typo in launch.json
This commit is contained in:
Karl Burtram
2017-12-15 15:38:57 -08:00
committed by GitHub
parent 271b3a0b82
commit 6ad0df0e3e
7118 changed files with 107999 additions and 56466 deletions

View File

@@ -1,93 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import nls = require('vs/nls');
import * as Path from 'vs/base/common/paths';
import URI from 'vs/base/common/uri';
import * as Labels from 'vs/base/common/labels';
import * as Platform from 'vs/base/common/platform';
import { Action } from 'vs/base/common/actions';
import { Registry } from 'vs/platform/registry/common/platform';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actionRegistry';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IEditor } from 'vs/platform/editor/common/editor';
import { IFileService } from 'vs/platform/files/common/files';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
class ConfigureLocaleAction extends Action {
public static ID = 'workbench.action.configureLocale';
public static LABEL = nls.localize('configureLocale', "Configure Language");
private static DEFAULT_CONTENT: string = [
'{',
`\t// ${nls.localize('displayLanguage', 'Defines VSCode\'s display language.')}`,
`\t// ${nls.localize('doc', 'See {0} for a list of supported languages.', 'https://go.microsoft.com/fwlink/?LinkId=761051')}`,
`\t// ${nls.localize('restart', 'Changing the value requires restarting VSCode.')}`,
`\t"locale":"${Platform.language}"`,
'}'
].join('\n');
constructor(id, label,
@IFileService private fileService: IFileService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IEnvironmentService private environmentService: IEnvironmentService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService
) {
super(id, label);
}
public run(event?: any): TPromise<IEditor> {
const file = URI.file(Path.join(this.environmentService.appSettingsHome, 'locale.json'));
return this.fileService.resolveFile(file).then(null, (error) => {
return this.fileService.createFile(file, ConfigureLocaleAction.DEFAULT_CONTENT);
}).then((stat) => {
if (!stat) {
return undefined;
}
return this.editorService.openEditor({
resource: stat.resource,
options: {
forceOpen: true
}
});
}, (error) => {
throw new Error(nls.localize('fail.createSettings', "Unable to create '{0}' ({1}).", Labels.getPathLabel(file, this.contextService), error));
});
}
}
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
registry.registerWorkbenchAction(new SyncActionDescriptor(ConfigureLocaleAction, ConfigureLocaleAction.ID, ConfigureLocaleAction.LABEL), 'Configure Language');
const schemaId = 'vscode://schemas/locale';
// Keep en-US since we generated files with that content.
const schema: IJSONSchema =
{
id: schemaId,
description: 'Locale Definition file',
type: 'object',
default: {
'locale': 'en'
},
required: ['locale'],
properties: {
locale: {
type: 'string',
enum: ['de', 'en', 'en-US', 'es', 'fr', 'it', 'ja', 'ko', 'ru', 'zh-CN', 'zh-TW'],
description: nls.localize('JsonSchema.locale', 'The UI Language to use.')
}
}
};
const jsonRegistry = Registry.as<IJSONContributionRegistry>(JSONExtensions.JSONContribution);
jsonRegistry.registerSchema(schemaId, schema);

View File

@@ -9,8 +9,8 @@ import nls = require('vs/nls');
import { Registry } from 'vs/platform/registry/common/platform';
import { Action } from 'vs/base/common/actions';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actionRegistry';
import { IConfigurationEditingService, ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
export class ToggleActivityBarVisibilityAction extends Action {
@@ -24,7 +24,7 @@ export class ToggleActivityBarVisibilityAction extends Action {
id: string,
label: string,
@IPartService private partService: IPartService,
@IConfigurationEditingService private configurationEditingService: IConfigurationEditingService
@IConfigurationService private configurationService: IConfigurationService
) {
super(id, label);
@@ -35,9 +35,7 @@ export class ToggleActivityBarVisibilityAction extends Action {
const visibility = this.partService.isVisible(Parts.ACTIVITYBAR_PART);
const newVisibilityValue = !visibility;
this.configurationEditingService.writeConfiguration(ConfigurationTarget.USER, { key: ToggleActivityBarVisibilityAction.activityBarVisibleKey, value: newVisibilityValue });
return TPromise.as(null);
return this.configurationService.updateValue(ToggleActivityBarVisibilityAction.activityBarVisibleKey, newVisibilityValue, ConfigurationTarget.USER);
}
}

View File

@@ -10,7 +10,7 @@ import nls = require('vs/nls');
import { Registry } from 'vs/platform/registry/common/platform';
import { Action } from 'vs/base/common/actions';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actionRegistry';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { IEditorGroupService, GroupOrientation } from 'vs/workbench/services/group/common/groupService';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';

View File

@@ -9,9 +9,9 @@ import nls = require('vs/nls');
import { Registry } from 'vs/platform/registry/common/platform';
import { Action } from 'vs/base/common/actions';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actionRegistry';
import { IConfigurationEditingService, ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
import { IPartService, Position } from 'vs/workbench/services/part/common/partService';
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
export class ToggleSidebarPositionAction extends Action {
@@ -24,20 +24,18 @@ export class ToggleSidebarPositionAction extends Action {
id: string,
label: string,
@IPartService private partService: IPartService,
@IConfigurationEditingService private configurationEditingService: IConfigurationEditingService
@IConfigurationService private configurationService: IConfigurationService
) {
super(id, label);
this.enabled = !!this.partService && !!this.configurationEditingService;
this.enabled = !!this.partService && !!this.configurationService;
}
public run(): TPromise<any> {
const position = this.partService.getSideBarPosition();
const newPositionValue = (position === Position.LEFT) ? 'right' : 'left';
this.configurationEditingService.writeConfiguration(ConfigurationTarget.USER, { key: ToggleSidebarPositionAction.sidebarPositionConfigurationKey, value: newPositionValue });
return TPromise.as(null);
return this.configurationService.updateValue(ToggleSidebarPositionAction.sidebarPositionConfigurationKey, newPositionValue, ConfigurationTarget.USER);
}
}

View File

@@ -9,7 +9,7 @@ import nls = require('vs/nls');
import { Registry } from 'vs/platform/registry/common/platform';
import { Action } from 'vs/base/common/actions';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actionRegistry';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';

View File

@@ -9,8 +9,8 @@ import nls = require('vs/nls');
import { Registry } from 'vs/platform/registry/common/platform';
import { Action } from 'vs/base/common/actions';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actionRegistry';
import { IConfigurationEditingService, ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
export class ToggleStatusbarVisibilityAction extends Action {
@@ -24,7 +24,7 @@ export class ToggleStatusbarVisibilityAction extends Action {
id: string,
label: string,
@IPartService private partService: IPartService,
@IConfigurationEditingService private configurationEditingService: IConfigurationEditingService
@IConfigurationService private configurationService: IConfigurationService
) {
super(id, label);
@@ -35,9 +35,7 @@ export class ToggleStatusbarVisibilityAction extends Action {
const visibility = this.partService.isVisible(Parts.STATUSBAR_PART);
const newVisibilityValue = !visibility;
this.configurationEditingService.writeConfiguration(ConfigurationTarget.USER, { key: ToggleStatusbarVisibilityAction.statusbarVisibleKey, value: newVisibilityValue });
return TPromise.as(null);
return this.configurationService.updateValue(ToggleStatusbarVisibilityAction.statusbarVisibleKey, newVisibilityValue, ConfigurationTarget.USER);
}
}

View File

@@ -9,7 +9,7 @@ import { Action } from 'vs/base/common/actions';
import { KeyCode, KeyMod, KeyChord } from 'vs/base/common/keyCodes';
import { Registry } from 'vs/platform/registry/common/platform';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actionRegistry';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
import { IPartService } from 'vs/workbench/services/part/common/partService';
class ToggleZenMode extends Action {

View File

@@ -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)];
});
});