The other night I saw a tweet by Neal Culiner (@NCSoftware) regarding a plugin he’d like to see developed.
Shortly there was a response was a tweet by Matthew MacSuga (@csharpbydesign). He mentioned that he’s asked for something like this a while back.
What they’re after, is a way to preview the code of a method, without having to visit that method.
I feel a little guilty because I remember Matthew mentioning this a while back. I think I started a debate at the time on "what should trigger the functionality” and we (well probably I) got bogged down in the details. Sorry Matthew :(
This time I just thought .. “Sod This” - (Wasting time that is, not talking to Matthew and Neal) - “Let’s just get something out there, and we’ll see where it leads afterward”.
So after a quick vote on the name of said plugin (Where Neal suggested the name and we all agreed :D) I was off to build a new plugin.
Where to start?
So I created a basic plugin and dropped an action in place. (For details please see a previous post)
From here I needed 2 things:
- A function to determine which method to preview.
- A function to actually do the preview.
There are some complexities in the original brief that I didn’t feel comfortable with initially.
- “Select method based on method call under cursor”.      - I have elected to use caret position in this first version.
 
- “Hold a key down to see Preview”      - I have elected to use a toggleable action in this first version.          
 
- I have elected to use a toggleable action in this first version.          
Which Method?
So the first thing to do is to work out which method to display a preview for.
Some Terminology:    
Given the sample… 
Public Sub Method1()
Call Method2()
End Sub
- “Method2” is known as the MethodReferenceExpression
- “Call Method2()” is the MethodCall.
I would like this plugin to function from either of these 2 locations, so I need to return the declaration of the method to which either refers.
------------------------------------------------------------- 
  
    Private Function GetMethod(ByVal Element As LanguageElement) As Method 
  
        Dim Method As Method = Nothing 
  
        Select Case Element.ElementType 
  
            Case LanguageElementType.MethodCall 
  
                Method = TryCast(Element, MethodCall).GetDeclaration 
  
            Case LanguageElementType.MethodReferenceExpression 
  
                Method = TryCast(Element, MethodReferenceExpression).GetDeclaration 
  
        End Select 
  
        Return Method 
  
    End Function 
  
-------------------------------------------------------------
To this method, I can pass CodeRush.Source.GetNodeAt(CodeRush.Caret.SourcePoint)
Later I can replace this with something which passes the element under the cursor, and I won’t have to change much at all.
Next we need to determine the code behind the Method in question. 
  
------------------------------------------------------------- 
  
Dim TheCode as String = CodeRush.CodeMod.GenerateCode(Method) 
  
------------------------------------------------------------- 
  
And now we have the code we’d like to render in our preview window. So lets crack on and create the preview itself. 
  
The Preview Window
Building a preview window is easy… (Isn’t everything with the DXCore? :P)
The following function accepts the code and a location for the preview and builds the preview accordingly. It also places the preview on screen.
(The code to hide the preview has been omitted here but is even simpler.)
------------------------------------------------------------- 
  
Private mPreviewWindow As CodePreviewWindow 
  
  
Private Sub ShowCodePreview(ByVal Code As String, ByVal insertionPoint As SourcePoint) 
  
    mPreviewWindow = New CodePreviewWindow(CodeRush.Documents.ActiveTextView, insertionPoint) 
  
    mPreviewWindow.AddCode(Code) 
  
    mPreviewWindow.ShowPreview() 
  
End Sub 
  
------------------------------------------------------------- 
  
  
And so things come together in the main ToggleMethodPreview_Execute() as… 
  
  
------------------------------------------------------------- 
  
Private mShowingPreview As Boolean = False 
  
  
Private Sub ToggleMethodPreview_Execute(ByVal ea As DevExpress.CodeRush.Core.ExecuteEventArgs) Handles ToggleMethodPreview.Execute 
  
    If mShowingPreview Then 
  
        Call HideCodePreview() 
  
    Else 
  
        Dim Method As Method = GetMethod(CodeRush.Source.GetNodeAt(CodeRush.Caret.SourcePoint)) 
  
        If Not Method Is Nothing Then 
  
            Call ShowMethodPreview(Method, CodeRush.Caret.SourcePoint) 
  
            mShowingPreview = True 
  
        End If 
  
    End If 
  
End Sub 
  
-------------------------------------------------------------
Summary
That’s pretty much all there is to it.
To use this plugin, simply bind a key to the “ToggleMethodPreview” action and activate it when your caret is in a suitable location.
For this plugin I wrote all of 42 lines of code including signatures.
Proof once again, as if you needed it, that the DXCore makes plugin writing ridiculously easy.
So now we have a first draft of “CR_MethodPreview”… go play… see what you think… And we’ll see where it goes from there.
------------------------------------------------------------- 
  
For more DevExpress news, check out their Facebook page 
  
-------------------------------------------------------------

 
 
 Posts
Posts
 
 
5 comments:
There might be a possibility here for a plugin, no?
http://stackoverflow.com/questions/1273085/attribute-to-add-to-an-interface-for-the-default-concrete-class
Indeed. :) I have asked for a little more info and made an offer :)
you da man!
Visual Studio has the "Code Definition Window" for this for in C#. I've be wanting the same thing for VB. And this plug-in does it. Thanks!
You're quite welcome. :)
Post a Comment