Sunday, 21 August 2011

Baby Steps: CodeRush Plugin Development

    I mentioned in my previous post that I’ve grown quite some interest in CodeRush from DevExpress, and part of that is because of the plug-in model they have in place, which is pretty powerful, yet simple to tap into and develop refactorings, code-providers, etc.

    In this post, I’m going to talk about the first CodeRush plugin I’ve ever wrote! It has a funny story, actually, where I was watching this recording of a CodeRush Feature Workshop, and at some point in the webinar, an attendee asked a question about how would a particular refactoring be implemented. Rory, started talking about that, and how easy it would be, then Mark Miller said: “Well, I almost wanna right that right now! It's like, so easy to do”. I thought to myself: “why not?!, this is my chance! :D”, and I just stopped the recording right away, opened Visual Studio and started developing my first Plugin! :) Just to be honest, as Mark suggested, this is very basic, and simple. But, heck, it got me hooked! 

    The basic idea for the plugin is that, sometimes, you have a portion of code that you want to change. However, you want to keep the current code maybe for reference, or just in case you needed it (or a part of it) back. To do it manually, you would select that portion, copy it, comment your selection (using Ctrl+k,Ctrl+c if you’re a true keyboarder :P) and then paste the code you copied. Something like this:

image

    So, why don’t we write a CodeRush Action that does just that? Simple enough? let’s get started…

    To create a CodeRush Plugin, you’ll need to have DXCore installed, which is an Add-in for visual studio that gives you the building blocks for developing your plug-in. If you have CodeRush or CodeRush eXpress installed, you already have DXCore. (if you don’t, stop right here, go to http://www.devexpress.com/crx and download CodeRush Xpress, don’t argue! just go!!… but remember to come back ;) )

    Once you have that installed, you’ll have a new Menu called “DevExpress”, and from there, starts the fun :D. Click the menu, and choose “New Plugin

image

UPDATE:    if you're using CodeRush eXpress, you'll not be able to see the DevExpress menu. Please check this post by Alex on how to enable it ;)
    doing that, you’ll get the following window, which allows you to select your Language (we’ll use C#), Plug-in Type (we’ll use the standard), and information about the project (as in any VS project: Name, Location and Solution name)

image
   
    by clicking OK, the wizard will give you the following screen for more options that you might want to set for your project:

image

You should click OK on this screen as well, and you’ll be all set.

PS: I have deliberately omitted to go into detail on the options that you can set in this wizard. However, if you want to delve into that, I recommend the following posts by Alex Skorkin ( a lead developer on CodeRush):
PS2: There is another way to create a plugin, which is via the File->New Project and look for DXCore -> Standard Plug-in (refer to the second post by Alex Skorkin for more info)

    Visual Studio will set up your project, and add a “Plugin” element to it, which is kind of a surface where you can put the components of your plugin

image
    You’ll get this Visual Studio designer which allows you to add components (DXCore components, in our case) to your plugin (PlugIn1.cs).

image

    For the purpose of this plugin, we’ll add an “Action”, which is simply as the name suggests, an “action” that you can start via a keyboard shortcut (which you’ll need to set in the options, more on that later), or a menu command. for more on Actions visit this post by Alex Skorkin.

    Se, we add an Action, and set some properties on it, like the component name, the Action Name (which will appear in the shortcut settings page), and a description.

image

    now, click on the Events icon, and double click on “Execute”  to create and wire up its event handler in the code behind file.

And now we get to the CODE!

    So, the steps here are pretty simple. Get the selected portion of text from the active text editor window, make a copy and comment it out, and add the commented part to the top of the selection.

    We start off by getting the ActiveTextView, which simply represents the code editor window you’re currently in when trying to execute the plugin. We can find this in CodeRush.Documents. And one thing to note here is that, the "CodeRush” object is a key part of the API, it’s basically THE Central object that you’ll end up using all around in your plugins. It is pretty discoverable, and (most of the time) you can find your way around it, for more advanced stuff, check the documentation (or search it) ;).

    So, we get the CodeRush.Documents.ActiveTextDocument and put it in a local variable. We then check if we really have an “Active Text Document”, by doing a null check on our variable.

image

    Our activeTextDocument has a particular property that we’re interested in, and that is “ActiveViewSelection”, so we grab that into a variable, and call an nice little method on it called “ExtendToWholeLines()” which, naturally enough, extends our selection to whole lines.

image

    You might be wondering, “well, why ‘ActiveViewSelection’? aren’t we already in the active View?”, and the answer is that, we’re in the active TextDocument, which can have 2 Views, when you split your editor like this:

image

and you can achieve this by dragging this little icon in your editor’s top right corner

image

That was a long tangent, but I thought it would be useful :)

    Moving on. After we get the selection, we iterate though its “Lines” and make a comment from each line, and then concatenate that in a variable (commentedSelection). Now, to do that, we could directly add the “//” for a single line comment in C#, but CodeRush has a more intelligent way to do it, in a language agnostic manner, and that is through the CodeRush.Language.GetComment(string text) method, which creates a comment from a piece of text in the current language (of the active text document) like so:

image

    After that, all is left to do is actually replacing the active selection with the “commentedSelection” that we just generated, followed by the selection itself:

image

    And... that’s pretty much about it! just hit F5 to run! this will launch a new instance of Visual Studio with the plugin that you created loaded into it. When the new instance is up, open/create a project and open a code file.

    Now, you might be thinking: "ah, OK, now what?!”, well, remember what we said earlier about “Actions”? we didn’t set ours to show as a Menu command, so we’ll need to set a shortcut for it. Go to the DevExpress menu and then to Options. In here, click on “Shortcuts”, in this page, click “add a new Keyboard Shortcut”, set the key combination, select “CautiousChange” (or whatever you named your action) from the Command dropdown, and then, set the Context for this action from the TreeView below that to “Any Selection”, then hit OK to save the changes & exit. The following screenshot illustrates the process:

image

    Now, select a bunch of text, and hit the key combination (Ctrl+Shift+Alt+C, in my case), and see your plugin in action!

image

    Pretty awesome! isn’t it?! And all that was what? 15 lines of code? Speaking of which, here’s the full code for the only method we wrote:

private void actCautiousChange_Execute(ExecuteEventArgs ea)
{
    var activeTextDocument = CodeRush.Documents.ActiveTextDocument;
    if (activeTextDocument == null)
        return;

    var selection = activeTextDocument.ActiveViewSelection;
    selection.ExtendToWholeLines();

    var commentedSelection = Environment.NewLine + CodeRush.Language.GetComment("Old code");
    foreach (var line in selection.Lines)
        commentedSelection += CodeRush.Language.GetComment(line);
    commentedSelection += CodeRush.Language.GetComment("--------------");

    selection.Text = commentedSelection + selection.Text;

    if(selection.AnchorIsAtEnd)
        selection.SwapPoints();
    selection.Clear();
}
    As an exercise for you, dear reader, try figuring out what the last two instructions do ;)

    And here is the link for the project on my Github (which is actually my first time using GitHub! :D)
   
    Alright, I hope this made some sense to you. It’s my first tutorial in a looong time, so it might be “rough on the edges”, but I’ll try to get back my writing skills by time ;)

Here are a few useful links for you:
    In the end, make sure you follow @RoryBecker (DevExpress Community Guy), @MillerMark (the CodeRush Guru), @AlexSkorkin (the CodeRush Dev Lead), and of course, @AbdouMoumen (the CodeRush N00b, and yeah, that’s me :P)

No comments:

Post a Comment