[Plugin development] Modify move to folder refactoring

Hi there,

I would appreciate any help with plugin development.

I would like to modify "move file to folder" refactoring. When using with Perforce, the move operation results in removing and adding new file in P4 tree. This is done without move command so the revision tree is lost.

I guess R# just asks Visual Studio to move the file. Is there any endpoint I can hook up in to customize how exactly are files moved? So I could instruct source control to do the move and then just modify the project files.

I went through the documentation and existing refactorings but it's very extensive.

Any help would be appreciated.


1 comment
Comment actions Permalink

I'm not sure if you can write a plugin to customise this behaviour. You can get change notifications that a project item has been removed, and another has been added, but you'd need to correllate the messages yourself and do something with it, but the move has already been performed at that point. As I understand it, ReSharper moves each declaration to a new folder, rather than moving the files. So if you have more than one type in a file, only the type you selected is moved. If the files are empty at the end of the refactor, they are (optionally) deleted, depending on the state of the checkbox when starting the refactor. This results in the remove + add pattern. I think the best you could do would be to fix up the source control bindings after the move. If you can correctly collate a move of a single file (rather than one file being expanded into multiple files) then presumably you could update the source control commands.

To get at the notifications, you need to use the change manager. This means making a class that implements IChangeProvider, and is marked with [SolutionComponent]. You need to have ChangeManager injected in your constructor, too. You can then register yourself as a change provider with the changeManager, and add a dependency - i.e. when a specific component publishes a change, you want to be notified. When you do get notified, your IChangeProvider.Execute is called with an instance of IChangeMap, from which you can get the data you're interested in. That will most likely be changeMap.GetChange<ProjectModelChange>(solution). You can then examine the project model change (it accepts a visitor class deriving from RecursiveProjectModelChangeDeltaVisitor allowing you to collect the information) and do your collation - if you get an appropriate match, fix up the source control.

To see where to register your change provider, you can run ReSharper in internal mode (/ReSharper.Internal on the command line to Visual Studio) and go to ReSharper -> Internal -> View Change Manager Graph. This creates a .graphml file, that you can view in the yEd graphing application (if you do, go to Layout -> Hierarchical to get a saner graph layout), and from here you can see how changes flow through the system, from the SolutionElement to the various parties that are interested in changes (and who then propogate different changes themselves to other interested parties).



Please sign in to leave a comment.