提交 8b478ef1 编写于 作者: B Benjamin Pasero

workspace editing: allow to add/remove folder in non-workspace setup

上级 2c468454
......@@ -13,7 +13,7 @@ import Event, { Emitter } from 'vs/base/common/event';
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
import { IProgress } from 'vs/platform/progress/common/progress';
import { ISearchResultProvider, ISearchQuery, ISearchComplete, ISearchProgressItem, QueryType, IFileMatch, ISearchService } from 'vs/platform/search/common/search';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
@extHostNamedCustomer(MainContext.MainThreadFileSystem)
export class MainThreadFileSystem implements MainThreadFileSystemShape {
......@@ -26,7 +26,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape {
extHostContext: IExtHostContext,
@IFileService private readonly _fileService: IFileService,
@ISearchService private readonly _searchService: ISearchService,
@IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService
@IWorkspaceEditingService private readonly _workspaceEditingService: IWorkspaceEditingService
) {
this._proxy = extHostContext.get(ExtHostContext.ExtHostFileSystem);
}
......@@ -45,7 +45,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape {
}
$onDidAddFileSystemRoot(uri: URI): void {
this._workspaceContextService.addFolders([uri]);
this._workspaceEditingService.addFolders([uri]);
}
$onFileSystemChange(handle: number, changes: IFileChange[]): void {
......
......@@ -8,7 +8,6 @@
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, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
......@@ -213,25 +212,13 @@ export class AddRootFolderAction extends BaseWorkspacesAction {
}
public run(): TPromise<any> {
let addFoldersPromise: TPromise<void>;
// Workspace
if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
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);
}
addFoldersPromise = this.workspaceEditingService.addFolders(folders.map(folder => URI.file(folder)));
}
// Empty or Folder
else {
addFoldersPromise = this.instantiationService.createInstance(NewWorkspaceAction, NewWorkspaceAction.ID, NewWorkspaceAction.LABEL, this.contextService.getWorkspace().folders.map(folder => folder.uri)).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);
}
// Add and show Files Explorer viewlet
return addFoldersPromise.then(() => this.viewletService.openViewlet(this.viewletService.getDefaultViewletId(), true));
return this.workspaceEditingService.addFolders(folders.map(folder => URI.file(folder))).then(() => this.viewletService.openViewlet(this.viewletService.getDefaultViewletId(), true));
}
}
......@@ -260,13 +247,6 @@ export class GlobalRemoveRootFolderAction extends BaseWorkspacesAction {
if (state === WorkbenchState.WORKSPACE || state === WorkbenchState.FOLDER) {
return this.commandService.executeCommand<IWorkspaceFolder>(PICK_WORKSPACE_FOLDER_COMMAND).then(folder => {
if (folder) {
// Folder: close workspace
if (state === WorkbenchState.FOLDER) {
return this.windowService.closeWorkspace().then(() => true);
}
// Workspace: remove folder
return this.workspaceEditingService.removeFolders([folder.uri]).then(() => true);
}
......@@ -278,40 +258,6 @@ export class GlobalRemoveRootFolderAction extends BaseWorkspacesAction {
}
}
class NewWorkspaceAction extends BaseWorkspacesAction {
static ID = 'workbench.action.newWorkspace';
static LABEL = nls.localize('newWorkspace', "New Workspace...");
constructor(
id: string,
label: string,
private presetRoots: URI[],
@IWindowService windowService: IWindowService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IEnvironmentService environmentService: IEnvironmentService,
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
@IHistoryService historyService: IHistoryService
) {
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))]);
}
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.workspaceEditingService.createAndEnterWorkspace(workspaceFolders);
}
}
export class RemoveRootFolderAction extends Action {
static ID = 'workbench.action.removeRootFolder';
......
......@@ -39,7 +39,7 @@ import { IExtensionService } from 'vs/platform/extensions/common/extensions';
import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService';
import { Themable } from 'vs/workbench/common/theme';
import { ipcRenderer as ipc, webFrame } from 'electron';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { IMenuService, MenuId, IMenu, MenuItemAction, ICommandAction } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
......@@ -402,21 +402,7 @@ export class ElectronWindow extends Themable {
private onAddFolders(request: IAddFoldersRequest): void {
const foldersToAdd = request.foldersToAdd.map(folderToAdd => URI.file(folderToAdd.filePath));
// Workspace: just add to workspace config
if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
this.contextService.addFolders(foldersToAdd).done(null, errors.onUnexpectedError);
}
// Single folder or no workspace: create workspace and open
else {
const workspaceFolders: URI[] = [...this.contextService.getWorkspace().folders.map(folder => folder.uri)];
// Fill in remaining ones from request
workspaceFolders.push(...request.foldersToAdd.map(folderToAdd => URI.file(folderToAdd.filePath)));
// Create workspace and open (ensure no duplicates)
this.workspaceEditingService.createAndEnterWorkspace(arrays.distinct(workspaceFolders.map(folder => folder.fsPath), folder => platform.isLinux ? folder : folder.toLowerCase()));
}
this.workspaceEditingService.addFolders(foldersToAdd).done(null, errors.onUnexpectedError);
}
private onOpenFiles(request: IOpenFileRequest): void {
......
......@@ -53,7 +53,6 @@ import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { distinct } from 'vs/base/common/arrays';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { getPathLabel } from 'vs/base/common/labels';
import { extractResources } from 'vs/base/browser/dnd';
......@@ -909,23 +908,19 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop {
// Handle folders by adding to workspace if we are in workspace context
const folders = result.filter(result => result.stat.isDirectory).map(result => result.stat.resource);
if (folders.length > 0) {
if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
return this.workspaceEditingService.addFolders(folders);
}
// If we are in single-folder context, ask for confirmation to create a workspace
const result = this.messageService.confirmSync({
message: folders.length > 1 ? nls.localize('dropFolders', "Do you want to add the folders to the workspace?") : nls.localize('dropFolder', "Do you want to add the folder to the workspace?"),
type: 'question',
primaryButton: folders.length > 1 ? nls.localize('addFolders', "&&Add Folders") : nls.localize('addFolder', "&&Add Folder")
});
if (result) {
const currentFolders = this.contextService.getWorkspace().folders.map(folder => folder.uri);
const newRoots = [...currentFolders, ...folders];
// If we are in no-workspace context, ask for confirmation to create a workspace
let confirmed = true;
if (this.contextService.getWorkbenchState() !== WorkbenchState.WORKSPACE) {
confirmed = this.messageService.confirmSync({
message: folders.length > 1 ? nls.localize('dropFolders', "Do you want to add the folders to the workspace?") : nls.localize('dropFolder', "Do you want to add the folder to the workspace?"),
type: 'question',
primaryButton: folders.length > 1 ? nls.localize('addFolders', "&&Add Folders") : nls.localize('addFolder', "&&Add Folder")
});
}
// Create and open workspace
return this.workspaceEditingService.createAndEnterWorkspace(distinct(newRoots.map(root => root.fsPath)));
if (confirmed) {
return this.workspaceEditingService.addFolders(folders);
}
}
......
......@@ -25,6 +25,9 @@ import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { BackupFileService } from 'vs/workbench/services/backup/node/backupFileService';
import { IChoiceService, Severity, IMessageService } from 'vs/platform/message/common/message';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { distinct } from 'vs/base/common/arrays';
import { isLinux } from 'vs/base/common/platform';
import { isEqual } from 'vs/base/common/resources';
export class WorkspaceEditingService implements IWorkspaceEditingService {
......@@ -46,13 +49,48 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
public addFolders(foldersToAdd: URI[]): TPromise<void>;
public addFolders(foldersToAdd: { uri: URI, name?: string }[]): TPromise<void>;
public addFolders(folders: any[]): TPromise<void> {
return this.contextService.addFolders(folders)
public addFolders(foldersToAdd: any[]): TPromise<void> {
const state = this.contextService.getWorkbenchState();
// If we are in no-workspace or single-folder workspace, adding folders has to
// enter a workspace.
if (state !== WorkbenchState.WORKSPACE) {
const newWorkspaceFolders = distinct([
...this.contextService.getWorkspace().folders.map(folder => folder.uri),
...foldersToAdd.map(folder => {
if (URI.isUri(folder)) {
return folder;
}
return folder.uri;
})
].map(folder => folder.fsPath), folder => isLinux ? folder : folder.toLowerCase());
if (state === WorkbenchState.EMPTY && newWorkspaceFolders.length === 0 || state === WorkbenchState.FOLDER && newWorkspaceFolders.length === 1) {
return TPromise.as(void 0); // return if the operation is a no-op for the current state
}
return this.createAndEnterWorkspace(newWorkspaceFolders);
}
// Delegate addition of folders to workspace service otherwise
return this.contextService.addFolders(foldersToAdd)
.then(() => null, error => this.handleWorkspaceConfigurationEditingError(error));
}
public removeFolders(folders: URI[]): TPromise<void> {
return this.contextService.removeFolders(folders)
public removeFolders(foldersToRemove: URI[]): TPromise<void> {
// If we are in single-folder state and the opened folder is to be removed,
// we close the workspace and enter the empty workspace state for the window.
if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) {
const workspaceFolder = this.contextService.getWorkspace().folders[0];
if (foldersToRemove.some(folder => isEqual(folder, workspaceFolder.uri, isLinux))) {
return this.windowService.closeWorkspace();
}
}
// Delegate removal of folders to workspace service otherwise
return this.contextService.removeFolders(foldersToRemove)
.then(() => null, error => this.handleWorkspaceConfigurationEditingError(error));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册