diff --git a/src/vs/workbench/parts/files/browser/fileActions.ts b/src/vs/workbench/parts/files/browser/fileActions.ts index a1458c0fbb8..1f8608c2ca4 100644 --- a/src/vs/workbench/parts/files/browser/fileActions.ts +++ b/src/vs/workbench/parts/files/browser/fileActions.ts @@ -568,6 +568,7 @@ export class CreateFileAction extends BaseCreateAction { constructor( element: FileStat, @IFileService fileService: IFileService, + @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IMessageService messageService: IMessageService, @ITextFileService textFileService: ITextFileService ) { @@ -577,7 +578,9 @@ export class CreateFileAction extends BaseCreateAction { } public runAction(fileName: string): TPromise { - return this.fileService.createFile(URI.file(paths.join(this.element.parent.resource.fsPath, fileName))).then(null, (error) => { + return this.fileService.createFile(URI.file(paths.join(this.element.parent.resource.fsPath, fileName))).then(stat => { + return this.editorService.openEditor({ resource: stat.resource, options: { pinned: true } }); + }, (error) => { this.onErrorWithRetry(error, () => this.runAction(fileName)); }); } @@ -592,6 +595,7 @@ export class CreateFolderAction extends BaseCreateAction { constructor( element: FileStat, @IFileService fileService: IFileService, + @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IMessageService messageService: IMessageService, @ITextFileService textFileService: ITextFileService ) { @@ -601,7 +605,9 @@ export class CreateFolderAction extends BaseCreateAction { } public runAction(fileName: string): TPromise { - return this.fileService.createFolder(URI.file(paths.join(this.element.parent.resource.fsPath, fileName))).then(null, (error) => { + return this.fileService.createFolder(URI.file(paths.join(this.element.parent.resource.fsPath, fileName))).then(stat => { + return this.editorService.openEditor({ resource: stat.resource, options: { pinned: true } }); + }, (error) => { this.onErrorWithRetry(error, () => this.runAction(fileName)); }); } @@ -758,6 +764,7 @@ export class ImportFileAction extends BaseFileAction { element: FileStat, clazz: string, @IFileService fileService: IFileService, + @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IMessageService messageService: IMessageService, @ITextFileService textFileService: ITextFileService ) { @@ -843,7 +850,13 @@ export class ImportFileAction extends BaseFileAction { } return revertPromise.then(() => { - return this.fileService.importFile(sourceFile, targetElement.resource).then(null, (error: any) => { + return this.fileService.importFile(sourceFile, targetElement.resource).then(res => { + + // if we only import one file, just open it directly + if (filesArray.length === 1) { + this.editorService.openEditor({ resource: res.stat.resource, options: { pinned: true } }).done(null, errors.onUnexpectedError); + } + }, (error: any) => { this.messageService.show(Severity.Error, error); }); }); @@ -975,6 +988,7 @@ export class DuplicateFileAction extends BaseFileAction { element: FileStat, target: FileStat, @IFileService fileService: IFileService, + @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IMessageService messageService: IMessageService, @ITextFileService textFileService: ITextFileService ) { @@ -994,7 +1008,11 @@ export class DuplicateFileAction extends BaseFileAction { } // Copy File - const result = this.fileService.copyFile(this.element.resource, this.findTarget()).then(null, (error: any) => { + const result = this.fileService.copyFile(this.element.resource, this.findTarget()).then(stat => { + if (!stat.isDirectory) { + return this.editorService.openEditor({ resource: stat.resource, options: { pinned: true } }); + } + }, (error: any) => { this.onError(error); }); diff --git a/src/vs/workbench/parts/files/browser/views/explorerView.ts b/src/vs/workbench/parts/files/browser/views/explorerView.ts index 13266ed94c7..41bfb7157cc 100644 --- a/src/vs/workbench/parts/files/browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/browser/views/explorerView.ts @@ -277,13 +277,12 @@ export class ExplorerView extends CollapsibleViewletView { } // Otherwise restore last used file: By lastActiveFileResource - const root = this.getInput(); let lastActiveFileResource: URI; if (this.settings[ExplorerView.MEMENTO_LAST_ACTIVE_FILE_RESOURCE]) { lastActiveFileResource = URI.parse(this.settings[ExplorerView.MEMENTO_LAST_ACTIVE_FILE_RESOURCE]); } - if (lastActiveFileResource && root && root.find(lastActiveFileResource)) { + if (lastActiveFileResource && this.root && this.root.find(lastActiveFileResource)) { this.editorService.openEditor({ resource: lastActiveFileResource, options: { revealIfVisible: true } }).done(null, errors.onUnexpectedError); return refreshPromise; @@ -316,7 +315,7 @@ export class ExplorerView extends CollapsibleViewletView { return toResource(input, { supportSideBySide: true, filter: 'file' }); } - private getInput(): FileStat { + private get root(): FileStat { return this.explorerViewer ? (this.explorerViewer.getInput()) : null; } @@ -376,7 +375,7 @@ export class ExplorerView extends CollapsibleViewletView { if (e.operation === FileOperation.CREATE || e.operation === FileOperation.IMPORT || e.operation === FileOperation.COPY) { const addedElement = e.target; parentResource = URI.file(paths.dirname(addedElement.resource.fsPath)); - parentElement = this.getInput().find(parentResource); + parentElement = this.root.find(parentResource); if (parentElement) { @@ -385,32 +384,14 @@ export class ExplorerView extends CollapsibleViewletView { parentElement.removeChild(childElement); // make sure to remove any previous version of the file if any parentElement.addChild(childElement); - const refreshPromise = () => { + // Refresh the Parent (View) + this.explorerViewer.refresh(parentElement).then(() => { + return this.reveal(childElement, 0.5).then(() => { - // Refresh the Parent (View) - return this.explorerViewer.refresh(parentElement).then(() => { - return this.reveal(childElement, 0.5).then(() => { - - // Focus new element - this.explorerViewer.setFocus(childElement); - - // Open new file in editor (pinned) - if (!childElement.isDirectory) { - return this.editorService.openEditor({ resource: childElement.resource, options: { pinned: true } }); - } - }); + // Focus new element + this.explorerViewer.setFocus(childElement); }); - }; - - // For file imports, use a delayer to not refresh too many times when multiple files are imported - if (e.operation === FileOperation.IMPORT) { - this.explorerImportDelayer.trigger(refreshPromise).done(null, errors.onUnexpectedError); - } - - // Otherwise just refresh immediately - else { - refreshPromise().done(null, errors.onUnexpectedError); - } + }).done(null, errors.onUnexpectedError); } } @@ -423,15 +404,15 @@ export class ExplorerView extends CollapsibleViewletView { const newParentResource = URI.file(paths.dirname(newElement.resource.fsPath)); // Only update focus if renamed/moved element is selected - let updateFocus = false; + let restoreFocus = false; const focus: FileStat = this.explorerViewer.getFocus(); if (focus && focus.resource && focus.resource.toString() === oldResource.toString()) { - updateFocus = true; + restoreFocus = true; } // Handle Rename if (oldParentResource && newParentResource && oldParentResource.toString() === newParentResource.toString()) { - modelElement = this.getInput().find(oldResource); + modelElement = this.root.find(oldResource); if (modelElement) { // Rename File (Model) @@ -443,7 +424,7 @@ export class ExplorerView extends CollapsibleViewletView { this.explorerViewer.refresh(parent).done(() => { // Select in Viewer if set - if (updateFocus) { + if (restoreFocus) { this.explorerViewer.setFocus(modelElement); } }, errors.onUnexpectedError); @@ -453,9 +434,9 @@ export class ExplorerView extends CollapsibleViewletView { // Handle Move else if (oldParentResource && newParentResource) { - const oldParent = this.getInput().find(oldParentResource); - const newParent = this.getInput().find(newParentResource); - modelElement = this.getInput().find(oldResource); + const oldParent = this.root.find(oldParentResource); + const newParent = this.root.find(newParentResource); + modelElement = this.root.find(oldResource); if (oldParent && newParent && modelElement) { @@ -467,9 +448,7 @@ export class ExplorerView extends CollapsibleViewletView { }, () => { // Update new parent - this.explorerViewer.refresh(newParent, true).done(() => { - return this.explorerViewer.expand(newParent); - }, errors.onUnexpectedError); + this.explorerViewer.refresh(newParent, true).done(() => this.explorerViewer.expand(newParent), errors.onUnexpectedError); }); } } @@ -477,7 +456,7 @@ export class ExplorerView extends CollapsibleViewletView { // Delete else if (e.operation === FileOperation.DELETE) { - modelElement = this.getInput().find(e.resource); + modelElement = this.root.find(e.resource); if (modelElement && modelElement.parent) { parent = modelElement.parent; @@ -485,10 +464,13 @@ export class ExplorerView extends CollapsibleViewletView { parent.removeChild(modelElement); // Refresh Parent (View) + const restoreFocus = this.explorerViewer.isDOMFocused(); this.explorerViewer.refresh(parent).done(() => { // Ensure viewer has keyboard focus if event originates from viewer - this.explorerViewer.DOMFocus(); + if (restoreFocus) { + this.explorerViewer.DOMFocus(); + } }, errors.onUnexpectedError); } } @@ -532,8 +514,7 @@ export class ExplorerView extends CollapsibleViewletView { const added = e.getAdded(); const deleted = e.getDeleted(); - const root = this.getInput(); - if (!root) { + if (!this.root) { return false; } @@ -554,8 +535,8 @@ export class ExplorerView extends CollapsibleViewletView { } // Compute if parent is visible and added file not yet part of it - const parentStat = root.find(URI.file(parent)); - if (parentStat && parentStat.isDirectoryResolved && !root.find(change.resource)) { + const parentStat = this.root.find(URI.file(parent)); + if (parentStat && parentStat.isDirectoryResolved && !this.root.find(change.resource)) { return true; } @@ -572,7 +553,7 @@ export class ExplorerView extends CollapsibleViewletView { continue; // out of workspace file } - if (root.find(del.resource)) { + if (this.root.find(del.resource)) { return true; } } @@ -645,7 +626,6 @@ export class ExplorerView extends CollapsibleViewletView { } private doRefresh(): TPromise { - const root = this.getInput(); const targetsToResolve: URI[] = []; let targetsToExpand: URI[] = []; @@ -654,7 +634,7 @@ export class ExplorerView extends CollapsibleViewletView { } // First time refresh: Receive target through active editor input or selection and also include settings from previous session - if (!root) { + if (!this.root) { const activeFile = this.getActiveFile(); if (activeFile) { targetsToResolve.push(activeFile); @@ -667,7 +647,7 @@ export class ExplorerView extends CollapsibleViewletView { // Subsequent refresh: Receive targets through expanded folders in tree else { - this.getResolvedDirectories(root, targetsToResolve); + this.getResolvedDirectories(this.root, targetsToResolve); } // Load Root Stat with given target path configured @@ -679,12 +659,12 @@ export class ExplorerView extends CollapsibleViewletView { const modelStat = FileStat.create(stat, options.resolveTo); // First time refresh: The stat becomes the input of the viewer - if (!root) { + if (!this.root) { explorerPromise = this.explorerViewer.setInput(modelStat).then(() => { // Make sure to expand all folders that where expanded in the previous session if (targetsToExpand) { - return this.explorerViewer.expandAll(targetsToExpand.map(expand => this.getInput().find(expand))); + return this.explorerViewer.expandAll(targetsToExpand.map(expand => this.root.find(expand))); } return TPromise.as(null); @@ -693,9 +673,9 @@ export class ExplorerView extends CollapsibleViewletView { // Subsequent refresh: Merge stat into our local model and refresh tree else { - FileStat.mergeLocalWithDisk(modelStat, root); + FileStat.mergeLocalWithDisk(modelStat, this.root); - explorerPromise = this.explorerViewer.refresh(root); + explorerPromise = this.explorerViewer.refresh(this.root); } return explorerPromise; @@ -751,12 +731,11 @@ export class ExplorerView extends CollapsibleViewletView { } // First try to get the stat object from the input to avoid a roundtrip - const root = this.getInput(); - if (!root) { + if (!this.root) { return TPromise.as(null); } - const fileStat = root.find(resource); + const fileStat = this.root.find(resource); if (fileStat) { return this.doSelect(fileStat, reveal); } @@ -769,10 +748,10 @@ export class ExplorerView extends CollapsibleViewletView { const modelStat = FileStat.create(stat, options.resolveTo); // Update Input with disk Stat - FileStat.mergeLocalWithDisk(modelStat, root); + FileStat.mergeLocalWithDisk(modelStat, this.root); // Select and Reveal - return this.explorerViewer.refresh(root).then(() => this.doSelect(root.find(resource), reveal)); + return this.explorerViewer.refresh(this.root).then(() => this.doSelect(this.root.find(resource), reveal)); }, (e: any) => this.messageService.show(Severity.Error, e)); } @@ -823,8 +802,7 @@ export class ExplorerView extends CollapsibleViewletView { public shutdown(): void { // Keep list of expanded folders to restore on next load - const root = this.getInput(); - if (root) { + if (this.root) { const expanded = this.explorerViewer.getExpandedElements() .filter((e: FileStat) => e.resource.toString() !== this.contextService.getWorkspace().resource.toString()) .map((e: FileStat) => e.resource.toString());