I was asked recently if I knew of any plugins for Coderush which would allow one to hit a key and inject a header into the current file.
The idea was that the header would be injected in a location within the existing file but not necessarily where the caret was currently residing.
My initial idea of “use a template” scuppered by this idea, as templates typically expand where your caret is.
But perhaps not.
I quickly rerouted my thinking an came up with the following idea.
What about a new Action (what is an action?) which would take a parameter of which template to expand. It could drop a marker at the current location… Jump to the top of the current file, Expand the template there, and then collect it’s marker… Perfect right ? :D
So how does one do that then…
See my previous Tutorials for how to create a simple action plugin.
The Action Properties
In this case we will simply set the properties differently….
…add some Parameters (via the Parameters property)….
… flesh out a few of their details…
…and write some different code in the execute routine of the Action.
As usual, the code is really what it’s all about:
The Code
What we need to do here is to drop a marker, Go inject the template text and then collect the marker.
The Main event looks like this:
-------------------------------------------------------------
Private Sub actExpandHeader_Execute(ByVal ea As DevExpress.CodeRush.Core.ExecuteEventArgs) Handles actExpandHeader.Execute
' Get Params Dim HeaderType As String = ea.Action.Parameters.Item("HeaderType").ValueAsStr
Dim FullTemplateNameAndPath As String = ea.Action.Parameters.Item("Template").ValueAsStr
' Drop Marker
CodeRush.Markers.Drop()
' Determine Insert Point
Dim InsertPoint = GetJumpLocation(HeaderType)
' Expand Template
Call ExpandTemplateAtSourcepoint(FullTemplateNameAndPath, InsertPoint)
' Collect Marker
CodeRush.Markers.Collect()
End Sub
-------------------------------------------------------------
Then we’ll need to determine the location at which to insert our header. This is based on a passed parameter.
-------------------------------------------------------------
Private Function GetJumpLocation(ByVal HeaderType As String) As SourcePoint
Dim ElementRange As SourceRange
Select Case HeaderType.ToLower
Case "file" ElementRange = CodeRush.Documents.ActiveTextDocument.Range
Case "type" ElementRange = CodeRush.Source.ActiveClassInterfaceStructOrModule.Range
Case "member", "method" ElementRange = CodeRush.Source.ActiveMember.Range
Case Else ElementRange = CodeRush.Documents.ActiveTextDocument.Range
End Select Return ElementRange.Start
End Function
-------------------------------------------------------------
…and finally we’ll need to actually inject the Header from the nominated Template…
-------------------------------------------------------------Private Sub ExpandTemplateAtSourcepoint(ByVal FullTemplateNameAndPath As String, ByVal InsertPoint As SourcePoint)
Dim TemplateName = FullTemplateNameAndPath.Split("\"c).Last
Dim TemplateCategory = FullTemplateNameAndPath.Substring(0, FullTemplateNameAndPath.Length - TemplateName.Length - 1)
Dim Template = CodeRush.Templates.FindTemplate(TemplateName, TemplateCategory, _
CodeRush.Documents.ActiveLanguage)
Dim FinalText = CodeRush.Strings.Expand(Template.FirstItemInContext.Expansion)
' Again this isn't the best as we loose links etc... But it was a prety quick turnaround right ? :P
CodeRush.Documents.ActiveTextDocument.InsertText(InsertPoint, FinalText)
End Sub
This last part expands the template into an in memory string which is then injected into the ActiveTextDocument at the previously calculated location. ...and we’re done.
1 comment:
Hey Rory, thanks for the posts on creating CR plug-ins. Trying my hand using your examples...
That said, I was wondering if you'd expand a bit on the header plug-in idea and specifically how/where you envision the header template to be located. Is that something that should just be set as part of the "Template" Action Param? Or is there a way to let the user specify this in an option file?
Thanks
Post a Comment