Friday, May 4, 2007

MonoDevelop Refactoring

Have you ever wanted to rename a variable in a source file and have all of the references to that variable be renamed as well? I'm sure you have. If you are a typical Linux developer, the only option you've ever had available to you would be to perform a Search & Replace action in your editor (bound to Alt-% in my Emacs editor).

...But this solution is hardly perfect. Search & Replace might match substrings you wouldn't want to replace, so you'd have to examine each substring match manually to accept the change, but this is prone to mistakes. Using a regex Search & Replace might help minimize mistakes in that you might be able to eliminate substring matches that were part of other identifiers, but you'd still have to manually examine each change if you re-used variable names in different scopes or different functions/methods within the same file.

...Which brings us to the next problem: editors historically used by programmers on Linux have never offered to update source files that depend on the current buffer, so programmers would have to manually update the other source files as well.

Welcome... to the Future.

This past week I've been working on a feature allowing MonoDevelop users to rename local variables, classes, interfaces, class members, methods, events, properties, etc and have all the appropriate code in the entire project auto-magically updated, no matter where you invoke the rename action (whether it be in the base class, inner class, some other section of code that uses the class, etc).

Just another example of Mono bringing improvements to Linux developers everywhere.

6 comments:

Anonymous said...

"Just another example of Mono bringing improvements to Linux developers everywhere."

I think this is an overstatement in this particular case.

Don´t take me wrong as I really appreciate this effort to be able to achieve this using Mono but there are already refactoring engines for JAVA in Linux that do this so this is nothing new to existing Linux programmers.

Also, this feature is not thanks to Mono but to monodevelop, as this feature can be achieved in any language as long as there is someone who is bothered to code it.

I would also like to thank you for this improvement to MonoDevelop which I will most likely use very soon.

Jeffrey Stedfast said...

Nod, I know it exists in Java IDE's (e.g. Eclipse which is amazing) and that it's nothing new, but to the vast majority of Linux developers, it is something they do not have available today (kinda sad, actually) for their language.

(I suspect Smalltalk has this feature as well? Not sure).

But yea.

And you're welcome :)

I hope to add more refactoring methods to MonoDevelop as time goes on.

Iñigo said...

Trying to rename a class, changes the name of the class, the name of the constructor, name of the type on declaring properties.... but when instantiating, the constructor isn't getting renamed. For example:

NameOfClass class = new NameOfClass();

is renamed to:

OtherName class = new NameOfClass();

Good work after all!

Anonymous said...

You probably also want to selectively (eg. let the user choose) rename in comments and in strings. Eg. a windows component might be initialized like:

//
// fooBar1
//
FooBar fooBar1 = new FooBar();
fooBar1.Location = new Location(7,42);
fooBar1.Name = "fooBar1";
foobar1.Bar = BarStyle.Very;

when doing the rename from fooBar1 to myFooBar you really also want the comment and the Name-property value to change.

David said...

:D

This is great !!

Ross_Ylitalo said...

I too have been enjoying the Refactor->rename functionality in Monodevelop. Thank you for your work to make this happen.

I have encountered what looks like a bug, or perhaps a problem with my system:

consider the following code:

for (int i = 0; i < _cols; i++) {
for (int j = 0; j < _rows; j++) {

If I use the right-click menu to rename the variable 'i' to 'r', I have been seeing one of two results:

The first is that it runs very quickly, and becomes:

for (rnt i = 0; r < _cols; r++) {
for (int j = 0; j < _rows; j++) {

That is, it replaced the i in the int declaritive, with r, and left the first instance if 'i' unmodified.

The second result is that it appears to go into an infinate loop, reving my cpu up to high gear, full speed ahead. I haven't let it run too long, it begins prompting me with "Monodevelop not responding" (Halt application) (Wait some more) type of messages. I just "halted" monodevelop.

Again, I have really been impressed, yea, amazed at the cooperative efforts that make mono and MonoDevelop possible, but I thought you may be interested to hear of this, in case its a bug. Of course it could be a problem with my system. Its a new installation of kubuntu, courtesy of wubi, which seems pretty solid but I've only been using it for a couple of days now.

Thank you again,

Ross Ylitalo

Code Snippet Licensing

All code posted to this blog is licensed under the MIT/X11 license unless otherwise stated in the post itself.