@@ -649,8 +649,18 @@ private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs
649649 ev . Handled = true ;
650650 } ;
651651
652+ var copyAsPatch = new MenuItem ( ) ;
653+ copyAsPatch . Header = App . Text ( "CopyAsPatch" ) ;
654+ copyAsPatch . Icon = this . CreateMenuIcon ( "Icons.Copy" ) ;
655+ copyAsPatch . Click += async ( _ , ev ) =>
656+ {
657+ await CopyAsPatchAsync ( ) ;
658+ ev . Handled = true ;
659+ } ;
660+
652661 var menu = new ContextMenu ( ) ;
653662 menu . Items . Add ( copy ) ;
663+ menu . Items . Add ( copyAsPatch ) ;
654664 menu . Open ( TextArea . TextView ) ;
655665
656666 e . Handled = true ;
@@ -896,6 +906,42 @@ private async Task CopyWithoutIndicatorsAsync()
896906 await this . CopyTextAsync ( builder . ToString ( ) ) ;
897907 }
898908
909+ private async Task CopyAsPatchAsync ( )
910+ {
911+ if ( DataContext is not ViewModels . TextDiffContext { Data : { } diff , Option : { } option } ctx )
912+ return ;
913+
914+ var selection = TextArea . Selection ;
915+ var startPosition = selection . StartPosition ;
916+ var endPosition = selection . EndPosition ;
917+
918+ if ( startPosition . Location > endPosition . Location )
919+ ( startPosition , endPosition ) = ( endPosition , startPosition ) ;
920+
921+ var maxIdx = GetLines ( ) . Count - 1 ;
922+ var startIdx = Math . Min ( startPosition . Line - 1 , maxIdx ) ;
923+ var endIdx = Math . Min ( endPosition . Line - 1 , maxIdx ) ;
924+ var isCombined = true ;
925+ if ( ctx is ViewModels . TwoSideTextDiff twoSides )
926+ {
927+ isCombined = false ;
928+ twoSides . GetCombinedRangeForSingleSide ( ref startIdx , ref endIdx , IsOld ) ;
929+ }
930+
931+ var tmpFile = Path . GetTempFileName ( ) ;
932+ var patch = new Models . PatchGenerator ( tmpFile , option , diff ) ;
933+ var succ = patch . Generate ( startIdx , endIdx , isCombined , IsOld , false ) ;
934+ if ( ! succ )
935+ {
936+ Models . Notification . Send ( null , "You should select at lease one changed line!" , true ) ;
937+ return ;
938+ }
939+
940+ var patchText = File . ReadAllText ( tmpFile ) ;
941+ File . Delete ( tmpFile ) ;
942+ await this . CopyTextAsync ( patchText ) ;
943+ }
944+
899945 private bool _execSizeChanged ;
900946 private TextMate . Installation _textMate ;
901947 private TextLocation _lastSelectStart = TextLocation . Empty ;
0 commit comments