@@ -953,6 +953,10 @@ export class EditorService extends Disposable implements EditorServiceImpl {
953953 editors = [ editors ] ;
954954 }
955955
956+ // Make sure to not save the same editor multiple times
957+ // by using the `matches()` method to find duplicates
958+ const uniqueEditors = this . getUniqueEditors ( editors ) ;
959+
956960 // Split editors up into a bucket that is saved in parallel
957961 // and sequentially. Unless "Save As", all non-untitled editors
958962 // can be saved in parallel to speed up the operation. Remaining
@@ -961,9 +965,9 @@ export class EditorService extends Disposable implements EditorServiceImpl {
961965 const editorsToSaveParallel : IEditorIdentifier [ ] = [ ] ;
962966 const editorsToSaveSequentially : IEditorIdentifier [ ] = [ ] ;
963967 if ( options ?. saveAs ) {
964- editorsToSaveSequentially . push ( ...editors ) ;
968+ editorsToSaveSequentially . push ( ...uniqueEditors ) ;
965969 } else {
966- for ( const { groupId, editor } of editors ) {
970+ for ( const { groupId, editor } of uniqueEditors ) {
967971 if ( editor . isUntitled ( ) ) {
968972 editorsToSaveSequentially . push ( { groupId, editor } ) ;
969973 } else {
@@ -973,7 +977,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
973977 }
974978
975979 // Editors to save in parallel
976- await Promise . all ( editorsToSaveParallel . map ( ( { groupId, editor } ) => {
980+ const saveResults = await Promise . all ( editorsToSaveParallel . map ( ( { groupId, editor } ) => {
977981
978982 // Use save as a hint to pin the editor if used explicitly
979983 if ( options ?. reason === SaveReason . EXPLICIT ) {
@@ -1000,8 +1004,10 @@ export class EditorService extends Disposable implements EditorServiceImpl {
10001004 }
10011005
10021006 const result = options ?. saveAs ? await editor . saveAs ( groupId , options ) : await editor . save ( groupId , options ) ;
1007+ saveResults . push ( result ) ;
1008+
10031009 if ( ! result ) {
1004- return false ; // failed or cancelled, abort
1010+ break ; // failed or cancelled, abort
10051011 }
10061012
10071013 // Replace editor preserving viewstate (either across all groups or
@@ -1015,7 +1021,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
10151021 }
10161022 }
10171023
1018- return true ;
1024+ return saveResults . every ( result => ! ! result ) ;
10191025 }
10201026
10211027 saveAll ( options ?: ISaveAllEditorsOptions ) : Promise < boolean > {
@@ -1029,7 +1035,11 @@ export class EditorService extends Disposable implements EditorServiceImpl {
10291035 editors = [ editors ] ;
10301036 }
10311037
1032- await Promise . all ( editors . map ( async ( { groupId, editor } ) => {
1038+ // Make sure to not revert the same editor multiple times
1039+ // by using the `matches()` method to find duplicates
1040+ const uniqueEditors = this . getUniqueEditors ( editors ) ;
1041+
1042+ await Promise . all ( uniqueEditors . map ( async ( { groupId, editor } ) => {
10331043
10341044 // Use revert as a hint to pin the editor
10351045 this . editorGroupService . getGroup ( groupId ) ?. pinEditor ( editor ) ;
@@ -1056,6 +1066,19 @@ export class EditorService extends Disposable implements EditorServiceImpl {
10561066 return editors ;
10571067 }
10581068
1069+ private getUniqueEditors ( editors : IEditorIdentifier [ ] ) : IEditorIdentifier [ ] {
1070+ const uniqueEditors : IEditorIdentifier [ ] = [ ] ;
1071+ for ( const { editor, groupId } of editors ) {
1072+ if ( uniqueEditors . some ( uniqueEditor => uniqueEditor . editor . matches ( editor ) ) ) {
1073+ continue ;
1074+ }
1075+
1076+ uniqueEditors . push ( { editor, groupId } ) ;
1077+ }
1078+
1079+ return uniqueEditors ;
1080+ }
1081+
10591082 //#endregion
10601083
10611084 dispose ( ) : void {
0 commit comments