Skip to content

Commit

Permalink
Copy to clipboard with full color
Browse files Browse the repository at this point in the history
  • Loading branch information
ltrzesniewski committed Jul 27, 2023
1 parent 397661b commit 617742f
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions ILSpy/TextView/DecompilerTextView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
Expand Down Expand Up @@ -77,6 +78,7 @@ public sealed partial class DecompilerTextView : UserControl, IDisposable, IHave
readonly List<VisualLineElementGenerator?> activeCustomElementGenerators = new List<VisualLineElementGenerator?>();
readonly BracketHighlightRenderer bracketHighlightRenderer;
RichTextColorizer? activeRichTextColorizer;
RichTextModel? activeRichTextModel;
FoldingManager? foldingManager;
ILSpyTreeNode[]? decompiledNodes;
Uri? currentAddress;
Expand Down Expand Up @@ -146,6 +148,8 @@ public DecompilerTextView()
textEditor.TextArea.TextView.SetResourceReference(ICSharpCode.AvalonEdit.Rendering.TextView.CurrentLineBackgroundProperty, ResourceKeys.CurrentLineBackgroundBrush);
textEditor.TextArea.TextView.SetResourceReference(ICSharpCode.AvalonEdit.Rendering.TextView.CurrentLineBorderProperty, ResourceKeys.CurrentLineBorderPen);

DataObject.AddSettingDataHandler(textEditor.TextArea, OnSettingData);

this.DataContextChanged += DecompilerTextView_DataContextChanged;
}

Expand Down Expand Up @@ -714,10 +718,12 @@ void ShowOutput(AvalonEditTextOutput textOutput, IHighlightingDefinition? highli
textEditor.SyntaxHighlighting = highlighting;
textEditor.Options.EnableEmailHyperlinks = textOutput.EnableHyperlinks;
textEditor.Options.EnableHyperlinks = textOutput.EnableHyperlinks;
activeRichTextModel = null;
if (activeRichTextColorizer != null)
textEditor.TextArea.TextView.LineTransformers.Remove(activeRichTextColorizer);
if (textOutput.HighlightingModel != null)
{
activeRichTextModel = textOutput.HighlightingModel;
activeRichTextColorizer = new RichTextColorizer(textOutput.HighlightingModel);
textEditor.TextArea.TextView.LineTransformers.Insert(highlighting == null ? 0 : 1, activeRichTextColorizer);
}
Expand Down Expand Up @@ -1176,6 +1182,58 @@ Task<AvalonEditTextOutput> SaveToDiskAsync(DecompilationContext context, string
}
#endregion

#region Clipboard
private void OnSettingData(object sender, DataObjectSettingDataEventArgs e)
{
if (e.Format == DataFormats.Html && e.DataObject is DataObject dataObject)
{
e.CancelCommand();
HtmlClipboard.SetHtml(dataObject, CreateHtmlFragmentFromSelection());
}
}

private string CreateHtmlFragmentFromSelection()
{
var options = new HtmlOptions(textEditor.TextArea.Options);
var highlighter = textEditor.TextArea.GetService(typeof(IHighlighter)) as IHighlighter;
var html = new StringBuilder();

foreach (var segment in textEditor.TextArea.Selection.Segments)
{
var line = textEditor.Document.GetLineByOffset(segment.StartOffset);

while (line != null && line.Offset < segment.EndOffset)
{
if (html.Length > 0)
html.AppendLine("<br>");

var s = GetOverlap(segment, line);
var highlightedLine = highlighter?.HighlightLine(line.LineNumber) ?? new HighlightedLine(textEditor.Document, line);

if (activeRichTextModel is not null)
{
var richTextHighlightedLine = new HighlightedLine(textEditor.Document, line);
foreach (HighlightedSection richTextSection in activeRichTextModel.GetHighlightedSections(s.Offset, s.Length))
richTextHighlightedLine.Sections.Add(richTextSection);
highlightedLine.MergeWith(richTextHighlightedLine);
}

html.Append(highlightedLine.ToHtml(s.Offset, s.Offset + s.Length, options));
line = line.NextLine;
}
}

return html.ToString();

static (int Offset, int Length) GetOverlap(ISegment segment1, ISegment segment2)
{
int start = Math.Max(segment1.Offset, segment2.Offset);
int end = Math.Min(segment1.EndOffset, segment2.EndOffset);
return (start, end - start);
}
}
#endregion

internal ReferenceSegment? GetReferenceSegmentAtMousePosition()
{
if (referenceElementGenerator.References == null)
Expand Down

0 comments on commit 617742f

Please sign in to comment.