@@ -44,6 +44,8 @@ import { DiffEditorViewModel, DiffMapping, DiffState } from './diffEditorViewMod
44
44
import { AccessibleDiffViewer } from 'vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer' ;
45
45
import { CursorChangeReason } from 'vs/editor/common/cursorEvents' ;
46
46
import { AudioCue , IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService' ;
47
+ import { LengthObj } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length' ;
48
+ import { Range } from 'vs/editor/common/core/range' ;
47
49
48
50
export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
49
51
private readonly elements = h ( 'div.monaco-diff-editor.side-by-side' , { style : { position : 'relative' , height : '100%' } } , [
@@ -479,6 +481,71 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
479
481
if ( ! diffModel ) { return ; }
480
482
await diffModel . waitForDiff ( ) ;
481
483
}
484
+
485
+ switchSide ( ) : void {
486
+ const isModifiedFocus = this . _editors . modified . hasWidgetFocus ( ) ;
487
+ const source = isModifiedFocus ? this . _editors . modified : this . _editors . original ;
488
+ const destination = isModifiedFocus ? this . _editors . original : this . _editors . modified ;
489
+
490
+ const sourceSelection = source . getSelection ( ) ;
491
+ if ( sourceSelection ) {
492
+ const mappings = this . _diffModel . get ( ) ?. diff . get ( ) ?. mappings . map ( m => isModifiedFocus ? m . lineRangeMapping . flip ( ) : m . lineRangeMapping ) ;
493
+ if ( mappings ) {
494
+ const newRange1 = translatePosition ( sourceSelection . getStartPosition ( ) , mappings ) ;
495
+ const newRange2 = translatePosition ( sourceSelection . getEndPosition ( ) , mappings ) ;
496
+ const range = Range . plusRange ( newRange1 , newRange2 ) ;
497
+ destination . setSelection ( range ) ;
498
+ }
499
+ }
500
+ destination . focus ( ) ;
501
+ }
502
+ }
503
+
504
+ function translatePosition ( posInOriginal : Position , mappings : LineRangeMapping [ ] ) : Range {
505
+ const mapping = findLast ( mappings , m => m . originalRange . startLineNumber <= posInOriginal . lineNumber ) ;
506
+ if ( ! mapping ) {
507
+ // No changes before the position
508
+ return Range . fromPositions ( posInOriginal ) ;
509
+ }
510
+
511
+ if ( mapping . originalRange . endLineNumberExclusive <= posInOriginal . lineNumber ) {
512
+ const newLineNumber = posInOriginal . lineNumber - mapping . originalRange . endLineNumberExclusive + mapping . modifiedRange . endLineNumberExclusive ;
513
+ return Range . fromPositions ( new Position ( newLineNumber , posInOriginal . column ) ) ;
514
+ }
515
+
516
+ if ( ! mapping . innerChanges ) {
517
+ // Only for legacy algorithm
518
+ return Range . fromPositions ( new Position ( mapping . modifiedRange . startLineNumber , 1 ) ) ;
519
+ }
520
+
521
+ const innerMapping = findLast ( mapping . innerChanges , m => m . originalRange . getStartPosition ( ) . isBeforeOrEqual ( posInOriginal ) ) ;
522
+ if ( ! innerMapping ) {
523
+ const newLineNumber = posInOriginal . lineNumber - mapping . originalRange . startLineNumber + mapping . modifiedRange . startLineNumber ;
524
+ return Range . fromPositions ( new Position ( newLineNumber , posInOriginal . column ) ) ;
525
+ }
526
+
527
+ if ( innerMapping . originalRange . containsPosition ( posInOriginal ) ) {
528
+ return innerMapping . modifiedRange ;
529
+ } else {
530
+ const l = lengthBetweenPositions ( innerMapping . originalRange . getEndPosition ( ) , posInOriginal ) ;
531
+ return Range . fromPositions ( addLength ( innerMapping . modifiedRange . getEndPosition ( ) , l ) ) ;
532
+ }
533
+ }
534
+
535
+ function lengthBetweenPositions ( position1 : Position , position2 : Position ) : LengthObj {
536
+ if ( position1 . lineNumber === position2 . lineNumber ) {
537
+ return new LengthObj ( 0 , position2 . column - position1 . column ) ;
538
+ } else {
539
+ return new LengthObj ( position2 . lineNumber - position1 . lineNumber , position2 . column - 1 ) ;
540
+ }
541
+ }
542
+
543
+ function addLength ( position : Position , length : LengthObj ) : Position {
544
+ if ( length . lineCount === 0 ) {
545
+ return new Position ( position . lineNumber , position . column + length . columnCount ) ;
546
+ } else {
547
+ return new Position ( position . lineNumber + length . lineCount , length . columnCount + 1 ) ;
548
+ }
482
549
}
483
550
484
551
function toLineChanges ( state : DiffState ) : ILineChange [ ] {
0 commit comments