@@ -29,7 +29,7 @@ import { IListService } from 'vs/platform/list/browser/listService';
2929import { Tree } from 'vs/base/parts/tree/browser/treeImpl' ;
3030import { CommandsRegistry } from 'vs/platform/commands/common/commands' ;
3131import { RawContextKey , IContextKey , IContextKeyService } from 'vs/platform/contextkey/common/contextkey' ;
32- import { IResourceInput , Position , IEditorInput } from 'vs/platform/editor/common/editor' ;
32+ import { IResourceInput , Position } from 'vs/platform/editor/common/editor' ;
3333import { IFileService } from 'vs/platform/files/common/files' ;
3434import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService' ;
3535import { IEditorViewState } from 'vs/editor/common/editorCommon' ;
@@ -73,25 +73,38 @@ export const openWindowCommand = (accessor: ServicesAccessor, paths: string[], f
7373 windowsService . openWindow ( paths , { forceNewWindow } ) ;
7474} ;
7575
76- function save ( resource : URI , isSaveAs : boolean , editorService : IWorkbenchEditorService , fileService : IFileService , untitledEditorService : IUntitledEditorService ,
77- textFileService : ITextFileService , editorGroupService : IEditorGroupService ) : TPromise < any > {
76+ // Commands can get exeucted from a command pallete, from a context menu or from some list using a keybinding
77+ // To cover all these cases we need to properly compute the resource on which the command is being executed
78+ export function getResourceForCommand ( resource : URI , listService : IListService , editorService : IWorkbenchEditorService ) : URI {
79+ if ( URI . isUri ( resource ) ) {
80+ return resource ;
81+ }
7882
79- let source : URI ;
80- if ( resource instanceof URI ) {
81- source = resource ;
82- } else {
83- source = toResource ( editorService . getActiveEditorInput ( ) , { supportSideBySide : true } ) ;
83+ const list = listService . lastFocusedList ;
84+ if ( list && list . isDOMFocused ( ) ) {
85+ const focus = list . getFocus ( ) ;
86+ if ( focus instanceof FileStat ) {
87+ return focus . resource ;
88+ } else if ( focus instanceof OpenEditor ) {
89+ return focus . editorInput . getResource ( ) ;
90+ }
8491 }
8592
86- if ( source && ( fileService . canHandleResource ( source ) || source . scheme === 'untitled' ) ) {
93+ return toResource ( editorService . getActiveEditorInput ( ) , { supportSideBySide : true } ) ;
94+ }
95+
96+ function save ( resource : URI , isSaveAs : boolean , editorService : IWorkbenchEditorService , fileService : IFileService , untitledEditorService : IUntitledEditorService ,
97+ textFileService : ITextFileService , editorGroupService : IEditorGroupService ) : TPromise < any > {
98+
99+ if ( resource && ( fileService . canHandleResource ( resource ) || resource . scheme === 'untitled' ) ) {
87100
88101 // Save As (or Save untitled with associated path)
89- if ( isSaveAs || source . scheme === 'untitled' ) {
102+ if ( isSaveAs || resource . scheme === 'untitled' ) {
90103 let encodingOfSource : string ;
91- if ( source . scheme === 'untitled' ) {
92- encodingOfSource = untitledEditorService . getEncoding ( source ) ;
93- } else if ( source . scheme === 'file' ) {
94- const textModel = textFileService . models . get ( source ) ;
104+ if ( resource . scheme === 'untitled' ) {
105+ encodingOfSource = untitledEditorService . getEncoding ( resource ) ;
106+ } else if ( resource . scheme === 'file' ) {
107+ const textModel = textFileService . models . get ( resource ) ;
95108 encodingOfSource = textModel && textModel . getEncoding ( ) ; // text model can be null e.g. if this is a binary file!
96109 }
97110
@@ -100,17 +113,17 @@ function save(resource: URI, isSaveAs: boolean, editorService: IWorkbenchEditorS
100113 const editor = getCodeEditor ( activeEditor ) ;
101114 if ( editor ) {
102115 const activeResource = toResource ( activeEditor . input , { supportSideBySide : true } ) ;
103- if ( activeResource && ( fileService . canHandleResource ( activeResource ) || source . scheme === 'untitled' ) && activeResource . toString ( ) === source . toString ( ) ) {
116+ if ( activeResource && ( fileService . canHandleResource ( activeResource ) || resource . scheme === 'untitled' ) && activeResource . toString ( ) === resource . toString ( ) ) {
104117 viewStateOfSource = editor . saveViewState ( ) ;
105118 }
106119 }
107120
108121 // Special case: an untitled file with associated path gets saved directly unless "saveAs" is true
109122 let savePromise : TPromise < URI > ;
110- if ( ! isSaveAs && source . scheme === 'untitled' && untitledEditorService . hasAssociatedFilePath ( source ) ) {
111- savePromise = textFileService . save ( source ) . then ( ( result ) => {
123+ if ( ! isSaveAs && resource . scheme === 'untitled' && untitledEditorService . hasAssociatedFilePath ( resource ) ) {
124+ savePromise = textFileService . save ( resource ) . then ( ( result ) => {
112125 if ( result ) {
113- return URI . file ( source . fsPath ) ;
126+ return URI . file ( resource . fsPath ) ;
114127 }
115128
116129 return null ;
@@ -119,11 +132,11 @@ function save(resource: URI, isSaveAs: boolean, editorService: IWorkbenchEditorS
119132
120133 // Otherwise, really "Save As..."
121134 else {
122- savePromise = textFileService . saveAs ( source ) ;
135+ savePromise = textFileService . saveAs ( resource ) ;
123136 }
124137
125138 return savePromise . then ( ( target ) => {
126- if ( ! target || target . toString ( ) === source . toString ( ) ) {
139+ if ( ! target || target . toString ( ) === resource . toString ( ) ) {
127140 return void 0 ; // save canceled or same resource used
128141 }
129142
@@ -137,22 +150,20 @@ function save(resource: URI, isSaveAs: boolean, editorService: IWorkbenchEditorS
137150 } ;
138151
139152 return editorService . replaceEditors ( [ {
140- toReplace : { resource : source } ,
153+ toReplace : { resource : resource } ,
141154 replaceWith
142155 } ] ) . then ( ( ) => true ) ;
143156 } ) ;
144157 }
145158
146159 // Pin the active editor if we are saving it
147- if ( ! resource ) {
148- const editor = editorService . getActiveEditor ( ) ;
149- if ( editor ) {
150- editorGroupService . pinEditor ( editor . position , editor . input ) ;
151- }
160+ const editor = editorService . getActiveEditor ( ) ;
161+ if ( editor && editor . input && editor . input . getResource ( ) . toString ( ) === resource . toString ( ) ) {
162+ editorGroupService . pinEditor ( editor . position , editor . input ) ;
152163 }
153164
154165 // Just save
155- return textFileService . save ( source , { force : true /* force a change to the file to trigger external watchers if any */ } ) ;
166+ return textFileService . save ( resource , { force : true /* force a change to the file to trigger external watchers if any */ } ) ;
156167 }
157168
158169 return TPromise . as ( false ) ;
@@ -244,10 +255,7 @@ CommandsRegistry.registerCommand({
244255 const editorService = accessor . get ( IWorkbenchEditorService ) ;
245256 const textFileService = accessor . get ( ITextFileService ) ;
246257 const messageService = accessor . get ( IMessageService ) ;
247-
248- if ( ! URI . isUri ( resource ) ) {
249- resource = toResource ( editorService . getActiveEditorInput ( ) , { supportSideBySide : true , filter : 'file' } ) ;
250- }
258+ resource = getResourceForCommand ( resource , accessor . get ( IListService ) , editorService ) ;
251259
252260 if ( resource && resource . scheme !== 'untitled' ) {
253261 return textFileService . revert ( resource , { force : true } ) . then ( null , error => {
@@ -270,29 +278,16 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
270278 const editorService = accessor . get ( IWorkbenchEditorService ) ;
271279 const listService = accessor . get ( IListService ) ;
272280 const tree = listService . lastFocusedList ;
273-
274- let resourceOrEditor : URI | IEditorInput ;
275- if ( URI . isUri ( resource ) ) {
276- resourceOrEditor = resource ;
277- } else {
278- const focus = tree . getFocus ( ) ;
279- if ( focus instanceof FileStat && ! focus . isDirectory ) {
280- resourceOrEditor = focus . resource ;
281- } else if ( focus instanceof OpenEditor ) {
282- resourceOrEditor = focus . editorInput ;
283- }
284- }
281+ resource = getResourceForCommand ( resource , listService , editorService ) ;
285282
286283 // Remove highlight
287284 if ( tree instanceof Tree ) {
288285 tree . clearHighlight ( ) ;
289286 }
290287
291288 // Set side input
292- if ( URI . isUri ( resourceOrEditor ) ) {
293- return editorService . openEditor ( { resource : resourceOrEditor , options : { preserveFocus : false } } , true ) ;
294- } else if ( resourceOrEditor ) {
295- return editorService . openEditor ( resourceOrEditor , { preserveFocus : false } , true ) ;
289+ if ( URI . isUri ( resource ) ) {
290+ return editorService . openEditor ( { resource, options : { preserveFocus : false } } , true ) ;
296291 }
297292
298293 return TPromise . as ( true ) ;
@@ -315,9 +310,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
315310 }
316311
317312 const editorService = accessor . get ( IWorkbenchEditorService ) ;
318- if ( ! URI . isUri ( resource ) ) {
319- resource = toResource ( editorService . getActiveEditorInput ( ) , { supportSideBySide : true , filter : 'file' } ) ;
320- }
313+ resource = getResourceForCommand ( resource , accessor . get ( IListService ) , editorService ) ;
321314
322315 if ( resource && resource . scheme === 'file' ) {
323316 const name = paths . basename ( resource . fsPath ) ;
@@ -343,7 +336,7 @@ CommandsRegistry.registerCommand({
343336 tree . DOMFocus ( ) ;
344337 }
345338
346- globalResourceToCompare = resource ;
339+ globalResourceToCompare = getResourceForCommand ( resource , listService , accessor . get ( IWorkbenchEditorService ) ) ;
347340 if ( ! resourceSelectedForCompareContext ) {
348341 resourceSelectedForCompareContext = ResourceSelectedForCompareContext . bindTo ( accessor . get ( IContextKeyService ) ) ;
349342 }
@@ -364,17 +357,14 @@ CommandsRegistry.registerCommand({
364357
365358 return editorService . openEditor ( {
366359 leftResource : globalResourceToCompare ,
367- rightResource : resource
360+ rightResource : getResourceForCommand ( resource , listService , editorService )
368361 } ) ;
369362 }
370363} ) ;
371364
372365const revealInOSHandler = ( accessor : ServicesAccessor , resource : URI ) => {
373366 // Without resource, try to look at the active editor
374- if ( ! URI . isUri ( resource ) ) {
375- const editorService = accessor . get ( IWorkbenchEditorService ) ;
376- resource = toResource ( editorService . getActiveEditorInput ( ) , { supportSideBySide : true , filter : 'file' } ) ;
377- }
367+ resource = getResourceForCommand ( resource , accessor . get ( IListService ) , accessor . get ( IWorkbenchEditorService ) ) ;
378368
379369 if ( resource ) {
380370 const windowsService = accessor . get ( IWindowsService ) ;
@@ -410,18 +400,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
410400 } ,
411401 id : COPY_PATH_COMMAND_ID ,
412402 handler : ( accessor , resource : URI ) => {
413- // Without resource, try to look at the active editor
414- if ( ! URI . isUri ( resource ) ) {
415- const editorGroupService = accessor . get ( IEditorGroupService ) ;
416- const editorService = accessor . get ( IWorkbenchEditorService ) ;
417- const activeEditor = editorService . getActiveEditor ( ) ;
418-
419- resource = activeEditor ? toResource ( activeEditor . input , { supportSideBySide : true } ) : void 0 ;
420- if ( activeEditor ) {
421- editorGroupService . focusGroup ( activeEditor . position ) ; // focus back to active editor group
422- }
423- }
424-
403+ resource = getResourceForCommand ( resource , accessor . get ( IListService ) , accessor . get ( IWorkbenchEditorService ) ) ;
425404 if ( resource ) {
426405 const clipboardService = accessor . get ( IClipboardService ) ;
427406 clipboardService . writeText ( resource . scheme === 'file' ? labels . getPathLabel ( resource ) : resource . toString ( ) ) ;
@@ -437,6 +416,7 @@ CommandsRegistry.registerCommand({
437416 handler : ( accessor , resource : URI ) => {
438417 const viewletService = accessor . get ( IViewletService ) ;
439418 const contextService = accessor . get ( IWorkspaceContextService ) ;
419+ resource = getResourceForCommand ( resource , accessor . get ( IListService ) , accessor . get ( IWorkbenchEditorService ) ) ;
440420
441421 viewletService . openViewlet ( VIEWLET_ID , false ) . then ( ( viewlet : ExplorerViewlet ) => {
442422 const isInsideWorkspace = contextService . isInsideWorkspace ( resource ) ;
@@ -462,7 +442,9 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
462442 when : undefined ,
463443 primary : KeyMod . CtrlCmd | KeyMod . Shift | KeyCode . KEY_S ,
464444 handler : ( accessor , resource : URI ) => {
465- return save ( resource , true , accessor . get ( IWorkbenchEditorService ) , accessor . get ( IFileService ) , accessor . get ( IUntitledEditorService ) , accessor . get ( ITextFileService ) , accessor . get ( IEditorGroupService ) ) ;
445+ const editorService = accessor . get ( IWorkbenchEditorService ) ;
446+ resource = getResourceForCommand ( resource , accessor . get ( IListService ) , editorService ) ;
447+ return save ( resource , true , editorService , accessor . get ( IFileService ) , accessor . get ( IUntitledEditorService ) , accessor . get ( ITextFileService ) , accessor . get ( IEditorGroupService ) ) ;
466448 }
467449} ) ;
468450
@@ -472,7 +454,9 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
472454 primary : KeyMod . CtrlCmd | KeyCode . KEY_S ,
473455 id : SAVE_FILE_COMMAND_ID ,
474456 handler : ( accessor , resource : URI ) => {
475- return save ( resource , false , accessor . get ( IWorkbenchEditorService ) , accessor . get ( IFileService ) , accessor . get ( IUntitledEditorService ) , accessor . get ( ITextFileService ) , accessor . get ( IEditorGroupService ) ) ;
457+ const editorService = accessor . get ( IWorkbenchEditorService ) ;
458+ resource = getResourceForCommand ( resource , accessor . get ( IListService ) , editorService ) ;
459+ return save ( resource , false , editorService , accessor . get ( IFileService ) , accessor . get ( IUntitledEditorService ) , accessor . get ( ITextFileService ) , accessor . get ( IEditorGroupService ) ) ;
476460 }
477461} ) ;
478462
0 commit comments