Skip to content

Commit

Permalink
Add Rename Member Command.
Browse files Browse the repository at this point in the history
  • Loading branch information
puff committed May 22, 2023
1 parent fbcbe56 commit 7f8de9d
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .run/[net6.0] dnSpy - EazSample.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value="net6.0-windows" />
<method v="2">
<option name="Build" />
<option name="Build" default="false" projectName="dnSpy.Extension.EasyRename" projectPath="file://$PROJECT_DIR$/dnSpy.Extension.EasyRename/dnSpy.Extension.EasyRename.csproj" />
</method>
</configuration>
</component>
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ A simple [dnSpy](https://github.com/dnSpyEx/dnSpy) extension for easily renaming

## Features
- [ ] Rename overridden methods automatically.
- [ ] Rename type when renaming constructor method.
- [x] Rename type when renaming a constructor method.

### Warnings
* There is no undo function when renaming with this extension.
* There is no `unsaved changes` prompt when you rename with this extension.

These are both part of the [AsmEditor](https://github.com/dnSpyEx/dnSpy/tree/master/Extensions/dnSpy.AsmEditor) extension, but the service used for these features is not public, so it cannot be implemented here.
78 changes: 78 additions & 0 deletions dnSpy.Extension.EasyRename/Commands/RenameMemberCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using System.ComponentModel.Composition;
using dnlib.DotNet;
using dnSpy.Contracts.App;
using dnSpy.Contracts.Documents.Tabs;
using dnSpy.Contracts.Documents.Tabs.DocViewer;
using dnSpy.Contracts.Menus;
using dnSpy.Contracts.TreeView;

namespace EasyRename.Commands;

[ExportMenuItem(Header = "Rename Member", Group = Constants.ContextMenuEditGroup, Order = 10)]
public sealed class RenameMemberCommand : MenuItemBase
{
private readonly IDocumentTabService _documentTabService;

[ImportingConstructor]
public RenameMemberCommand(IDocumentTabService documentTabService)
{
_documentTabService = documentTabService;
}

public override void Execute(IMenuItemContext context)
{
var member = GetMemberDef(context);
if (member is null) return;

var isConstructor = member is MethodDef { IsConstructor: true };
var defaultText = isConstructor ? member.DeclaringType.Name : member.Name;
var title = "Rename ";
if (member.IsEventDef)
title += "Event";
else if (member.IsFieldDef)
title += "Field";
else if (member.IsMethodDef && !isConstructor)
title += "Method";
else if (member.IsPropertyDef)
title += "Property";
else if (member.IsTypeDef || isConstructor)
title += "Type";

var newName = MsgBox.Instance.Ask<string?>("Name", defaultText, title,
null, s => string.IsNullOrEmpty(s) ? "Cannot be an empty string" : string.Empty);

if (string.IsNullOrEmpty(newName) || (isConstructor ? member.DeclaringType.Name : member.Name) == newName)
return;

if (isConstructor)
member.DeclaringType.Name = newName;
else
member.Name = newName;

var moduleDocNode = _documentTabService.DocumentTreeView.FindNode(member.Module)!;
_documentTabService.DocumentTreeView.TreeView.RefreshAllNodes();
_documentTabService.RefreshModifiedDocument(moduleDocNode.Document);
}

private static IMemberDef? GetMemberDef(IMenuItemContext context)
{
if (context.CreatorObject.Guid == new Guid(MenuConstants.GUIDOBJ_DOCUMENTVIEWERCONTROL_GUID))
return context.Find<TextReference>()?.Reference as IMemberDef;

if (context.CreatorObject.Guid == new Guid(MenuConstants.GUIDOBJ_DOCUMENTS_TREEVIEW_GUID))
{
var nodes = context.Find<TreeNodeData[]>();
if (nodes?.Length is not 1)
return null;

var node = nodes[0] as IMDTokenNode;
return node?.Reference as IMemberDef;
}
return null;
}

// Only show this if selecting a valid member definition
public override bool IsVisible(IMenuItemContext context) => GetMemberDef(context) is not null;
public override bool IsEnabled(IMenuItemContext context) => GetMemberDef(context) is not null;
}
6 changes: 6 additions & 0 deletions dnSpy.Extension.EasyRename/Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace EasyRename;

internal static class Constants
{
public const string ContextMenuEditGroup = "5050,EasyRename.ContextMenu.Rename";
}

0 comments on commit 7f8de9d

Please sign in to comment.