@@ -95,13 +95,25 @@ export class DirtyDiffWidget implements Disposable {
9595 }
9696
9797 protected handleChangedChanges ( updated : readonly Change [ ] ) : void {
98+ if ( ! updated . length ) {
99+ return this . dispose ( ) ;
100+ }
98101 if ( this . currentChange ) {
99- const { previousRange : { start, end} } = this . currentChange ;
100- this . index = updated . findIndex ( candidate => candidate . previousRange . start === start && candidate . previousRange . end === end ) ;
102+ const { previousRange : { start, end } } = this . currentChange ;
103+ // Same change or first after it.
104+ const newIndex = updated . findIndex ( candidate => ( candidate . previousRange . start === start && candidate . previousRange . end === end )
105+ || candidate . previousRange . start > start ) ;
106+ if ( newIndex !== - 1 ) {
107+ this . index = newIndex ;
108+ } else {
109+ this . index = Math . min ( this . index , updated . length - 1 ) ;
110+ }
111+ this . showCurrentChange ( ) ;
101112 } else {
102113 this . index = - 1 ;
103114 }
104115 this . _changes = updated ;
116+ this . updateHeading ( ) ;
105117 }
106118
107119 async showChange ( index : number ) : Promise < void > {
@@ -112,21 +124,24 @@ export class DirtyDiffWidget implements Disposable {
112124 }
113125 }
114126
115- async showNextChange ( ) : Promise < void > {
116- const editor = await this . checkCreated ( ) ;
117- editor . diffNavigator . next ( ) ;
118- this . updateIndex ( editor ) ;
119- }
120-
121- async showPreviousChange ( ) : Promise < void > {
122- const editor = await this . checkCreated ( ) ;
123- editor . diffNavigator . previous ( ) ;
124- this . updateIndex ( editor ) ;
127+ showNextChange ( ) : void {
128+ this . checkCreated ( ) ;
129+ const index = this . index ;
130+ const length = this . changes . length ;
131+ if ( length > 0 && ( index < 0 || length > 1 ) ) {
132+ this . index = index < 0 ? 0 : cycle ( index , 1 , length ) ;
133+ this . showCurrentChange ( ) ;
134+ }
125135 }
126136
127- protected updateIndex ( editor : MonacoDiffEditor ) : void {
128- const line = editor . cursor . line ;
129- this . index = this . changes . findIndex ( candidate => candidate . currentRange . start <= line && candidate . currentRange . end >= line ) ;
137+ showPreviousChange ( ) : void {
138+ this . checkCreated ( ) ;
139+ const index = this . index ;
140+ const length = this . changes . length ;
141+ if ( length > 0 && ( index < 0 || length > 1 ) ) {
142+ this . index = index < 0 ? length - 1 : cycle ( index , - 1 , length ) ;
143+ this . showCurrentChange ( ) ;
144+ }
130145 }
131146
132147 async getContentWithSelectedChanges ( predicate : ( change : Change , index : number , changes : readonly Change [ ] ) => boolean ) : Promise < string > {
@@ -143,7 +158,7 @@ export class DirtyDiffWidget implements Disposable {
143158 }
144159
145160 protected showCurrentChange ( ) : void {
146- this . peekView ! . setTitle ( this . computePrimaryHeading ( ) , this . computeSecondaryHeading ( ) ) ;
161+ this . updateHeading ( ) ;
147162 const { previousRange, currentRange } = this . changes [ this . index ] ;
148163 this . peekView . show ( Position . create ( LineRange . getEndPosition ( currentRange ) . line , 0 ) ,
149164 this . computeHeightInLines ( ) ) ;
@@ -162,6 +177,10 @@ export class DirtyDiffWidget implements Disposable {
162177 this . editor . focus ( ) ;
163178 }
164179
180+ protected updateHeading ( ) : void {
181+ this . peekView . setTitle ( this . computePrimaryHeading ( ) , this . computeSecondaryHeading ( ) ) ;
182+ }
183+
165184 protected computePrimaryHeading ( ) : string {
166185 return this . uri . path . base ;
167186 }
@@ -190,6 +209,10 @@ export class DirtyDiffWidget implements Disposable {
190209 }
191210}
192211
212+ function cycle ( index : number , offset : - 1 | 1 , length : number ) : number {
213+ return ( index + offset + length ) % length ;
214+ }
215+
193216// adapted from https://github.com/microsoft/vscode/blob/823d54f86ee13eb357bc6e8e562e89d793f3c43b/extensions/git/src/staging.ts
194217function applyChanges ( changes : readonly Change [ ] , original : monaco . editor . ITextModel , modified : monaco . editor . ITextModel ) : string {
195218 const result : string [ ] = [ ] ;
@@ -325,7 +348,7 @@ class DirtyDiffPeekView extends MonacoEditorPeekViewWidget {
325348 // Close editor on successful contributed action.
326349 // https://github.com/microsoft/vscode/blob/11b1500e0a2e8b5ba12e98a3905f9d120b8646a0/src/vs/workbench/contrib/scm/browser/quickDiffWidget.ts#L356-L361
327350 this . addAction ( id , label , icon , menuCommandExecutor . isEnabled ( menuPath , command , this . widget ) , ( ) => {
328- menuCommandExecutor . executeCommand ( menuPath , command , this . widget ) . then ( ( ) => this . dispose ( ) ) ;
351+ menuCommandExecutor . executeCommand ( menuPath , command , this . widget ) . then ( ( ) => this . dispose ( ) ) ;
329352 } ) ;
330353 }
331354 }
0 commit comments