Extending Intellisense: Namespace lookup with a macro
Namespaces in .NET are great! But how many times do you find yourself typing "Private r As xmlreader", and then noticing that there is no Imports/using statement for the System.Xml Namespace? Then you would have to scroll to the top of your document and add the Imports/using statement by hand. Alternatively you could choose to add the namespace to your declaration: "Private r As System.Xml.XmlReader". Since we are all developers, why not develop something to help developers with this tedious task of namespace lookups?
I've created the macro below that does the namespace lookup trick. The macro has 3 public methods you can assign for example to a shortcut key:
-
AddNamespace
This method will search the corresponding namespace for the typename you've just typed in your code, and add it to your type. So if you type for example "textreader", the macro will convert it to "System.IO.TextReader". -
AddImports
This method will search the corresponding namespace for the typename you've just typed in your code and add an Imports statement at the top of your code. So, if you've typed "textreader", the marco will add "Imports System.IO" at the top of your code. Additionaly the "textreader" will by replaced by "TextReader". -
AddUsing
This method is the same as the AddImports method, but can be used for the C# "using" keyword.
Since this is the first version of the macro, I would
appriciate if you can give some feedback if you find it
usefull, or if there are any bugs/problems! Here is the
complete source code (I suggest you create a new macro
module for it, and call it TypeFinder):
Imports
EnvDTE
Imports System.Diagnostics
Imports System
Public Module TypeFinder
Private Function
SearchTypeInAssembly(ByVal typename As String, ByVal ass As
Reflection.Assembly)
DTE.StatusBar.Text =
"Searching for '" & typename & "' " &
ass.GetName.Name & "..."
Dim t As Type
For Each t In ass.GetTypes
If
t.Name.ToLower = typename Then
Return
t
End If
Next
End
Function
Private Function SearchType(ByVal typename
As String) As Type
typename =
typename.ToLower
Dim projs As System.Array =
DTE.ActiveSolutionProjects
Dim ass As
Reflection.Assembly =
Reflection.Assembly.LoadWithPartialName("mscorlib")
Dim t As Type = SearchTypeInAssembly(typename, ass)
If Not t Is Nothing Then Return t
Dim proj As
Project
For Each proj In projs
Dim o As VSLangProj.VSProject = proj.Object
Dim ref As VSLangProj.Reference
For Each
ref In o.References
ass =
Reflection.Assembly.LoadFile(ref.Path)
t = SearchTypeInAssembly(typename, ass)
If Not t Is Nothing Then Return t
Next
Next
DTE.StatusBar.Text = "Could not find type
'" & typename & "' in the referenced libraries."
DTE.StatusBar.Highlight(True)
Return Nothing
End Function
Public Sub AddNamespace()
Dim text As TextSelection = DTE.ActiveDocument.Selection
text.WordLeft(True)
Dim t As Type =
SearchType(text.Text)
If Not t Is Nothing
Then
text.Text = t.FullName
text.EndOfLine()
DTE.StatusBar.Text =
"Ready"
End If
End Sub
Public
Sub AddImports()
Dim text As TextSelection =
DTE.ActiveDocument.Selection
text.WordLeft(True)
Dim t As Type =
SearchType(text.Text)
If Not t Is Nothing
Then
Dim line As Integer =
text.AnchorPoint.Line
text.Text = t.Name
text.StartOfDocument()
text.Insert("Imports
" & t.Namespace & vbCrLf)
text.MoveToLineAndOffset(line + 1, 1)
text.EndOfLine()
DTE.StatusBar.Text =
"'Imports " & t.Namespace & "' added to the
document."
DTE.StatusBar.Highlight(True)
End If
End Sub
Public Sub AddUsing()
Dim text As TextSelection = DTE.ActiveDocument.Selection
text.WordLeft(True)
Dim t As Type =
SearchType(text.Text)
If Not t Is Nothing
Then
Dim line As Integer =
text.AnchorPoint.Line
text.Text = t.Name
text.StartOfDocument()
text.Insert("using "
& t.Namespace & ";" & vbCrLf)
text.MoveToLineAndOffset(line + 1, 1)
text.EndOfLine()
DTE.StatusBar.Text =
"'using " & t.Namespace & ";' added to the
document."
DTE.StatusBar.Highlight(True)
End If
End Sub
End Module