Skip to content

Commit f9a7fef

Browse files
committed
feature: support to copy selected line(s) as patch in text diff viewer
Signed-off-by: leo <longshuang@msn.cn>
1 parent 4e0a723 commit f9a7fef

4 files changed

Lines changed: 49 additions & 0 deletions

File tree

src/Resources/Locales/en_US.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@
306306
<x:String x:Key="Text.ConventionalCommit.Type" xml:space="preserve">Type of Change:</x:String>
307307
<x:String x:Key="Text.Copy" xml:space="preserve">Copy</x:String>
308308
<x:String x:Key="Text.CopyAllText" xml:space="preserve">Copy All Text</x:String>
309+
<x:String x:Key="Text.CopyAsPatch" xml:space="preserve">Copy as Patch</x:String>
309310
<x:String x:Key="Text.CopyFullPath" xml:space="preserve">Copy Full Path</x:String>
310311
<x:String x:Key="Text.CopyPath" xml:space="preserve">Copy Path</x:String>
311312
<x:String x:Key="Text.CreateBranch" xml:space="preserve">Create Branch...</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@
310310
<x:String x:Key="Text.ConventionalCommit.Type" xml:space="preserve">类型:</x:String>
311311
<x:String x:Key="Text.Copy" xml:space="preserve">复制</x:String>
312312
<x:String x:Key="Text.CopyAllText" xml:space="preserve">复制全部文本</x:String>
313+
<x:String x:Key="Text.CopyAsPatch" xml:space="preserve">复制为补丁</x:String>
313314
<x:String x:Key="Text.CopyFullPath" xml:space="preserve">复制完整路径</x:String>
314315
<x:String x:Key="Text.CopyPath" xml:space="preserve">复制路径</x:String>
315316
<x:String x:Key="Text.CreateBranch" xml:space="preserve">新建分支 ...</x:String>

src/Resources/Locales/zh_TW.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@
310310
<x:String x:Key="Text.ConventionalCommit.Type" xml:space="preserve">類型:</x:String>
311311
<x:String x:Key="Text.Copy" xml:space="preserve">複製</x:String>
312312
<x:String x:Key="Text.CopyAllText" xml:space="preserve">複製全部內容</x:String>
313+
<x:String x:Key="Text.CopyAsPatch" xml:space="preserve">複製為修補檔</x:String>
313314
<x:String x:Key="Text.CopyFullPath" xml:space="preserve">複製完整路徑</x:String>
314315
<x:String x:Key="Text.CopyPath" xml:space="preserve">複製路徑</x:String>
315316
<x:String x:Key="Text.CreateBranch" xml:space="preserve">新增分支...</x:String>

src/Views/TextDiffView.axaml.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)