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; + } } }