2012-07-16 104 views
0

如果我有這樣的:的Visual Studio宏崩潰定製節點

namespace SomeNameSpace 
{ 
    #region Usings 

    using System.Collections.Generic; 
    using System.Security; 

    #endregion 

    /// <summary> Implements a dictionary with several keys.        </summary> 
    /// <typeparam name="Value"> What type of elements we will be storing in the dictionary</typeparam> 
    public class MultiKeyDic<Value> 
    { 

     /// <summary> a very long summary that can be 
     /// collapsed and expanded. </summary> 
     public int SomeInt {get;set;} 


     public void someMethod() 
     { 

     } 
    } 
} 

如何創建一個宏,將找到所有可以擴充(節點)的地方。如果我想摺疊所有節點,我將不得不折疊節點的順序爲someMethod(),summary of SomeInt,class MultiKeyDic,summary of class MultiKeyDic,#region Usings,最後是namespace

我知道命令CTRL +中號 + Ø倒塌的一切,但我不想崩潰的一切。例如,我可能不想摺疊評論。如果我摺疊一切,然後展開擴展父節點的註釋。


到目前爲止,我已經創造了這個宏,會發現大部分的節點:

Sub VisitAllNodes() 
    Dim i As Integer 
    Dim fileCM As FileCodeModel 
    Dim elts As EnvDTE.CodeElements 
    Dim elt As EnvDTE.CodeElement 

    fileCM = DTE.ActiveDocument.ProjectItem.FileCodeModel 
    elts = fileCM.CodeElements 
    For i = 1 To elts.Count 
     elt = elts.Item(i) 
     CollapseE(elt, elts, i) 
    Next 
End Sub 

'' Helper to OutlineCode. Recursively outlines members of elt. 
'' 
Sub CollapseE(ByVal elt As EnvDTE.CodeElement, ByVal elts As EnvDTE.CodeElements, ByVal loc As Integer) 
    Dim epStart As EnvDTE.EditPoint 
    Dim epEnd As EnvDTE.EditPoint 

    epStart = elt.GetStartPoint(vsCMPart.vsCMPartWholeWithAttributes).CreateEditPoint() 
    epEnd = elt.GetEndPoint(vsCMPart.vsCMPartWholeWithAttributes).CreateEditPoint() ' Copy it because we move it later. 
    epStart.EndOfLine() 
    If ((elt.IsCodeType()) And (elt.Kind <> EnvDTE.vsCMElement.vsCMElementDelegate)) Then 
     Dim i As Integer 
     Dim mems As EnvDTE.CodeElements 

     mems = elt.Members 
     For i = 1 To mems.Count 

      Dim temp As EnvDTE.CodeElement = mems.Item(i) 
      Dim t As String = [Enum].GetName(GetType(EnvDTE.vsCMElement), temp.Kind) 
      MsgBox("Found member (" & t & ") at line# " & temp.StartPoint.Line) 

      CollapseE(mems.Item(i), mems, i) 
     Next 
    ElseIf (elt.Kind = EnvDTE.vsCMElement.vsCMElementNamespace) Then 
     Dim i As Integer 
     Dim mems As EnvDTE.CodeElements 

     mems = elt.Members 
     For i = 1 To mems.Count 

      Dim temp As EnvDTE.CodeElement = mems.Item(i) 
      Dim t As String = [Enum].GetName(GetType(EnvDTE.vsCMElement), temp.Kind) 
      MsgBox("Found member (" & t & ") at line# " & temp.StartPoint.Line) 

      CollapseE(mems.Item(i), mems, i) 
     Next 
    End If 

    'Return 
    ' collapse the element 

    If (epStart.LessThan(epEnd)) Then 
     loc = loc + 1 
     If (loc <= elts.Count) Then 
      epEnd.MoveToPoint(elts.Item(loc).GetStartPoint(vsCMPart.vsCMPartHeader)) 
      epEnd.LineUp() 
      epEnd.EndOfLine() 
     End If 
     epStart.OutlineSection(epEnd) 
    End If 
End Sub 

它看起來比它是什麼更復雜。它運行在任何文件上,它會顯示所有屬性,類,枚舉等,但由於某種原因,沒有找到意見也不區域。

回答

0

第一功能IncludeMember用於確定排除什麼類型的構件。例如,在這個例子中,我不塌陷的命名空間和使用指令:

' filter some mebers. for example using statemets cannot be collapsed so exclude them. 
    Function IncludeMember(ByVal member As EnvDTE.CodeElement) 

     If member.Kind = vsCMElement.vsCMElementIDLImport Then 
      Return False 
     ElseIf member.Kind = vsCMElement.vsCMElementNamespace Then 
      Return False ' I do not want to colapse enums 
     End If 

     Return True 

    End Function 

    Sub CollapseNodes() 

     ' activate working window 
     DTE.Windows.Item(DTE.ActiveDocument.Name).Activate() 

     ' expand everything to start 

     Try 
      DTE.ExecuteCommand("Edit.StopOutlining") 
     Catch 
     End Try 

     Try 
      DTE.ExecuteCommand("Edit.StartAutomaticOutlining") 
     Catch 
     End Try 


     ' get text of document and replace all new lines with \r\n 
     Dim objTextDoc As TextDocument 
     Dim objEditPt As EnvDTE.EditPoint 
     Dim text As String 
     ' Get a handle to the new document and create an EditPoint. 
     objTextDoc = DTE.ActiveDocument.Object("TextDocument") 
     objEditPt = objTextDoc.StartPoint.CreateEditPoint 
     ' Get all Text of active document 
     text = objEditPt.GetText(objTextDoc.EndPoint) 
     text = System.Text.RegularExpressions.Regex.Replace(_ 
         text, _ 
         "(\r\n?|\n\r?)", ChrW(13) & ChrW(10) _ 
        ) 

     ' add new line to text so that lines of visual studio match with index of array 
     Dim lines As String() = System.Text.RegularExpressions.Regex.Split(vbCrLf & text, vbCrLf) 

     ' list where whe will place all colapsable items 
     Dim targetLines As New System.Collections.Generic.List(Of Integer) 

     ' regex that we will use to check if a line contains a #region 
     Dim reg As New System.Text.RegularExpressions.Regex(" *#region(|$)") 

     Dim i As Integer 
     For i = 1 To lines.Length - 1 

      If reg.Match(lines(i)).Success Then 
       targetLines.Add(i) 
      End If 

     Next 


     Dim fileCM As FileCodeModel 
     Dim elts As EnvDTE.CodeElements 
     Dim elt As EnvDTE.CodeElement 

     Dim projectItem = DTE.ActiveDocument.ProjectItem 

     Dim temp = projectItem.Collection.Count 

     Dim b = DirectCast(DirectCast(projectItem.Document, EnvDTE.Document).ActiveWindow, EnvDTE.Window).ContextAttributes 

     fileCM = projectItem.FileCodeModel 
     elts = fileCM.CodeElements 
     For i = 1 To elts.Count 
      elt = elts.Item(i) 
      CollapseE(elt, elts, i, targetLines) 
     Next 

     ' now that we have the lines that we will plan to collapse sort them. it is important to go in order 
     targetLines.Sort() 

     ActivateWorkingWindow() 

     ' go in reverse order so that we can collapse nested regions 
     For i = targetLines.Count - 1 To 0 Step -1 


      DTE.ExecuteCommand("Edit.Goto", targetLines(i)) 

      DTE.ExecuteCommand("Edit.ToggleOutliningExpansion") 

     Next 


    End Sub 

    '' Helper to OutlineCode. Recursively outlines members of elt. 
    '' 
    Sub CollapseE(ByVal elt As EnvDTE.CodeElement, ByVal elts As EnvDTE.CodeElements, ByVal loc As Integer, ByRef targetLines As System.Collections.Generic.List(Of Integer)) 
     Dim epStart As EnvDTE.EditPoint 
     Dim epEnd As EnvDTE.EditPoint 

     epStart = elt.GetStartPoint(vsCMPart.vsCMPartWholeWithAttributes).CreateEditPoint() 
     epEnd = elt.GetEndPoint(vsCMPart.vsCMPartWholeWithAttributes).CreateEditPoint() ' Copy it because we move it later. 
     epStart.EndOfLine() 
     If ((elt.IsCodeType()) And (elt.Kind <> EnvDTE.vsCMElement.vsCMElementDelegate) Or elt.Kind = EnvDTE.vsCMElement.vsCMElementNamespace) Then 
      Dim i As Integer 
      Dim mems As EnvDTE.CodeElements 

      mems = elt.Members 
      For i = 1 To mems.Count 

       CollapseE(mems.Item(i), mems, i, targetLines) 

      Next 

     End If 


     If (epStart.LessThan(epEnd)) Then 
      If IncludeMember(elt) Then 
       targetLines.Add(epStart.Line) 
      End If 
     End If 



    End Sub