Skip to content

Commit d1ac27e

Browse files
Merge pull request #3045 from ltrzesniewski/colored-copy
2 parents 397661b + 617742f commit d1ac27e

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

ILSpy/TextView/DecompilerTextView.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
using System.IO;
2626
using System.Linq;
2727
using System.Reflection.Metadata;
28+
using System.Text;
2829
using System.Threading;
2930
using System.Threading.Tasks;
3031
using System.Windows;
@@ -77,6 +78,7 @@ public sealed partial class DecompilerTextView : UserControl, IDisposable, IHave
7778
readonly List<VisualLineElementGenerator?> activeCustomElementGenerators = new List<VisualLineElementGenerator?>();
7879
readonly BracketHighlightRenderer bracketHighlightRenderer;
7980
RichTextColorizer? activeRichTextColorizer;
81+
RichTextModel? activeRichTextModel;
8082
FoldingManager? foldingManager;
8183
ILSpyTreeNode[]? decompiledNodes;
8284
Uri? currentAddress;
@@ -146,6 +148,8 @@ public DecompilerTextView()
146148
textEditor.TextArea.TextView.SetResourceReference(ICSharpCode.AvalonEdit.Rendering.TextView.CurrentLineBackgroundProperty, ResourceKeys.CurrentLineBackgroundBrush);
147149
textEditor.TextArea.TextView.SetResourceReference(ICSharpCode.AvalonEdit.Rendering.TextView.CurrentLineBorderProperty, ResourceKeys.CurrentLineBorderPen);
148150

151+
DataObject.AddSettingDataHandler(textEditor.TextArea, OnSettingData);
152+
149153
this.DataContextChanged += DecompilerTextView_DataContextChanged;
150154
}
151155

@@ -714,10 +718,12 @@ void ShowOutput(AvalonEditTextOutput textOutput, IHighlightingDefinition? highli
714718
textEditor.SyntaxHighlighting = highlighting;
715719
textEditor.Options.EnableEmailHyperlinks = textOutput.EnableHyperlinks;
716720
textEditor.Options.EnableHyperlinks = textOutput.EnableHyperlinks;
721+
activeRichTextModel = null;
717722
if (activeRichTextColorizer != null)
718723
textEditor.TextArea.TextView.LineTransformers.Remove(activeRichTextColorizer);
719724
if (textOutput.HighlightingModel != null)
720725
{
726+
activeRichTextModel = textOutput.HighlightingModel;
721727
activeRichTextColorizer = new RichTextColorizer(textOutput.HighlightingModel);
722728
textEditor.TextArea.TextView.LineTransformers.Insert(highlighting == null ? 0 : 1, activeRichTextColorizer);
723729
}
@@ -1176,6 +1182,58 @@ Task<AvalonEditTextOutput> SaveToDiskAsync(DecompilationContext context, string
11761182
}
11771183
#endregion
11781184

1185+
#region Clipboard
1186+
private void OnSettingData(object sender, DataObjectSettingDataEventArgs e)
1187+
{
1188+
if (e.Format == DataFormats.Html && e.DataObject is DataObject dataObject)
1189+
{
1190+
e.CancelCommand();
1191+
HtmlClipboard.SetHtml(dataObject, CreateHtmlFragmentFromSelection());
1192+
}
1193+
}
1194+
1195+
private string CreateHtmlFragmentFromSelection()
1196+
{
1197+
var options = new HtmlOptions(textEditor.TextArea.Options);
1198+
var highlighter = textEditor.TextArea.GetService(typeof(IHighlighter)) as IHighlighter;
1199+
var html = new StringBuilder();
1200+
1201+
foreach (var segment in textEditor.TextArea.Selection.Segments)
1202+
{
1203+
var line = textEditor.Document.GetLineByOffset(segment.StartOffset);
1204+
1205+
while (line != null && line.Offset < segment.EndOffset)
1206+
{
1207+
if (html.Length > 0)
1208+
html.AppendLine("<br>");
1209+
1210+
var s = GetOverlap(segment, line);
1211+
var highlightedLine = highlighter?.HighlightLine(line.LineNumber) ?? new HighlightedLine(textEditor.Document, line);
1212+
1213+
if (activeRichTextModel is not null)
1214+
{
1215+
var richTextHighlightedLine = new HighlightedLine(textEditor.Document, line);
1216+
foreach (HighlightedSection richTextSection in activeRichTextModel.GetHighlightedSections(s.Offset, s.Length))
1217+
richTextHighlightedLine.Sections.Add(richTextSection);
1218+
highlightedLine.MergeWith(richTextHighlightedLine);
1219+
}
1220+
1221+
html.Append(highlightedLine.ToHtml(s.Offset, s.Offset + s.Length, options));
1222+
line = line.NextLine;
1223+
}
1224+
}
1225+
1226+
return html.ToString();
1227+
1228+
static (int Offset, int Length) GetOverlap(ISegment segment1, ISegment segment2)
1229+
{
1230+
int start = Math.Max(segment1.Offset, segment2.Offset);
1231+
int end = Math.Min(segment1.EndOffset, segment2.EndOffset);
1232+
return (start, end - start);
1233+
}
1234+
}
1235+
#endregion
1236+
11791237
internal ReferenceSegment? GetReferenceSegmentAtMousePosition()
11801238
{
11811239
if (referenceElementGenerator.References == null)

0 commit comments

Comments
 (0)