diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceElementNode.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceElementNode.cs
index 3f45a5bd72..0528d28623 100644
--- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceElementNode.cs
+++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceElementNode.cs
@@ -141,8 +141,7 @@ protected ResourceElementNode(ITreeNodeGroup treeNodeGroup, ResourceElement reso
public virtual void WriteShort(IDecompilerOutput output, IDecompiler decompiler, bool showOffset) {
decompiler.WriteCommentBegin(output, true);
output.WriteOffsetComment(this, showOffset);
- const string LTR = "\u200E";
- output.Write(NameUtilities.CleanName(Name) + LTR, this, DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, BoxedTextColor.Comment);
+ output.Write(IdentifierEscaper.Escape(Name), this, DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, BoxedTextColor.Comment);
output.Write($" = {ValueString}", BoxedTextColor.Comment);
decompiler.WriteCommentEnd(output, true);
output.WriteLine();
diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceNode.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceNode.cs
index c1ffeee831..ecab03626b 100644
--- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceNode.cs
+++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/ResourceNode.cs
@@ -46,7 +46,7 @@ public abstract class ResourceNode : DocumentTreeNodeData, IResourceNode {
///
protected sealed override void WriteCore(ITextColorWriter output, IDecompiler decompiler, DocumentNodeWriteOptions options) {
- output.WriteFilename(Resource.Name);
+ output.WriteFilenameIdentifier(Resource.Name);
if ((options & DocumentNodeWriteOptions.ToolTip) != 0) {
output.WriteLine();
WriteFilename(output);
@@ -149,8 +149,7 @@ protected void Save() =>
public virtual void WriteShort(IDecompilerOutput output, IDecompiler decompiler, bool showOffset) {
decompiler.WriteCommentBegin(output, true);
output.WriteOffsetComment(this, showOffset);
- const string LTR = "\u200E";
- output.Write(NameUtilities.CleanName(Name) + LTR, this, DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, BoxedTextColor.Comment);
+ output.Write(IdentifierEscaper.Escape(Name), this, DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, BoxedTextColor.Comment);
string? extra = null;
switch (Resource.ResourceType) {
case ResourceType.AssemblyLinked:
diff --git a/dnSpy/dnSpy.Contracts.Logic/Text/ITextColorWriterExtensions.cs b/dnSpy/dnSpy.Contracts.Logic/Text/ITextColorWriterExtensions.cs
index 3e3c11e11c..a0ae606a18 100644
--- a/dnSpy/dnSpy.Contracts.Logic/Text/ITextColorWriterExtensions.cs
+++ b/dnSpy/dnSpy.Contracts.Logic/Text/ITextColorWriterExtensions.cs
@@ -208,5 +208,38 @@ public static T WriteFilename(this T output, string? filename) where T : ITex
}
return output;
}
+
+ ///
+ /// Writes a filename, escaping the filename and directory parts using
+ ///
+ /// Writer type
+ /// Output
+ /// Filename
+ ///
+ public static T WriteFilenameIdentifier(this T output, string? filename) where T : ITextColorWriter {
+ if (filename is null)
+ return output;
+ var s = filename.Replace('\\', '/');
+ var parts = s.Split('/');
+ int slashIndex = 0;
+ for (int i = 0; i < parts.Length - 1; i++) {
+ output.Write(BoxedTextColor.DirectoryPart, IdentifierEscaper.Escape(parts[i]));
+ slashIndex += parts[i].Length;
+ output.Write(BoxedTextColor.Text, filename[slashIndex].ToString());
+ slashIndex++;
+ }
+ var fn = parts[parts.Length - 1];
+ int index = fn.LastIndexOf('.');
+ if (index < 0)
+ output.Write(BoxedTextColor.FileNameNoExtension, IdentifierEscaper.Escape(fn));
+ else {
+ string ext = fn.Substring(index + 1);
+ fn = fn.Substring(0, index);
+ output.Write(BoxedTextColor.FileNameNoExtension, IdentifierEscaper.Escape(fn));
+ output.Write(BoxedTextColor.Text, ".");
+ output.Write(BoxedTextColor.FileExtension, ext);
+ }
+ return output;
+ }
}
}