How to run 'Cleanup Code' for all Pending Changes.

I recently switched from Regionerate to the ReSharper way of reordering type members for C# code.

It works well and I'm happy with it. However, when I was using regionerate I was able to run it for just the files that had been checked out.

I don't see such a possibility for ReSharper.

I have to filter my solution explorer to just pending changes and then select them all and then use the ReSharper menu to run the cleanup.


I know I can right click on the solution node and run the cleanup from there, but it cleans up the entire solution, which is mostly okay because TFS ignores the files that didn't change, but my solution is huge and running the cleanup for the whole thing takes 10 minutes.

Is there some other way I'm not seeing of running the cleanup for the files that have pending changes?

Thanks,
Brian

9 comments

Hi Brian,

I'm not sure, but possibly it can be done via custom plugin for VS/R#. I've moved the topic into ReSharper API / SDK community.
Thanks.

0

Hi Brian. There isn't a plugin that currently does this, but I think you could write something. You'd need to walk through the solution, into projects and call cleanup on each file, but before calling cleanup, you can see if it's writeable, which you can do by calling IEnsureWritableHandler.QueryIsWritable. This will check with VS to see if the file is under source control, and if it is, if it's checked out and can be edited (interestingly, I don't know how this will work with a tool like git, where you don't need to check out your files before modifying).

Hope this helps
Matt

0

Thanks for the ideas....

I haven't had time to look into writing a plugin. Good point about git ... that's also going to be true for TFS 2012 where they have local workspaces and all of the files are writable.

I might take a stab at it when I've got some "extra" time.

0

How would you go about callling cleanup code on a file? I've tried doing:

DTE2 dte = PendingCheckin.GetService(typeof(DTE)) as DTE2;
dte.ExecuteCommand("ReSharper_SilentCleanupCode")

with no luck as it seems to do unexpected things to Visual Studio.

0

You can call a ReSharper action using the ActionManager class. Calling the command via Visual Studio's DTE will work the same as executing the menu item. To do this programmatically from a plugin, you would need to get the ActionManager class, by injecting it as a constructor parameter into one of your plugin's component classes. From this, you can get the action that represents the silent clean up:

var action = actionManager.GetExecutableAction("SilentCleanupCode");


You need to create a data context that represents the code range that you want to run over, e.g. to run on a single file, you could call:

var dataContext = projectFile.ToDataContext()


And then you can execute this action:

actionManager.ExecuteActionIfAvailable(action, dataContext);

0

This doesnt work. ToDataContext method doesnt return IDataContext. How do we get data context of project file?

0

Right. ToDataContext returns a func that can be used to create an IDataContext. You can call this func with:

var dataContextCreator = projectElement.ToDataContext();
var dataContext = dataContextCreator(lifetime, dataContexts);


where lifetime is in an instance of Lifetime, and dataContexts is an instance of DataContexts, which you can inject into your component via the constructor.

Alternatively, you can get an IDataContext with a single function:

public IDataContext ToDataContext(Lifetime lifetime, DataContexts dataContexts, IProjectModelElement[] elements)

{

  return dataContexts.CreateWithDataRules(lifetime, DataRules.AddRule(“ContextFromProjectElements”,

    DataConstants.PROJECT_MODEL_ELEMENTS, elements));

}


Again, you need to pass in a Lifetime, and DataContexts.

0

Here is my action.execute code that works:

void IActionHandler.Execute(IDataContext context, DelegateExecute nextExecute)
    {
      // Get pending check in files. Look into RecursiveProjectVisitor for this
      var elements = CollectFiles(context);

      var dataContexts = context.GetComponent<DataContexts>();
      var cleanupcodeAction = _actionmanager.GetExecutableAction("SilentCleanupCode");

      Lifetimes.Using(li =>
      {
        // create Context that only has the pending check in files
        var checkinContext = ToDataContext(li, dataContexts, elements);

        _actionmanager.ExecuteActionIfAvailable(cleanupcodeAction, checkinContext);
      });
    }

you can get _actionmanager in the constructor

public CustomAction(ActionManager actionmanager) { _actionmanager = actionmanager; }

Hope this helps

0

Thanks Viranya and Matt.

@Viranya Do you have any plans to publish that as an extension? Is it already published? I was trying to write similar extension.

Thanks,
Ershad

0

Please sign in to leave a comment.