' Written by Roland Weigelt
' (http://weblogs.asp.net/rweigelt/archive/2003/07/06/9741.aspx)

Imports EnvDTE
Imports System.Diagnostics
' Macros for improving keyboard support for "#region ... #endregion"

Public Module RegionTools
    ' Toggles the current region surrounding the cursor
    Sub ToggleParentRegion()
        Dim objSelection As TextSelection
        objSelection = DTE.ActiveDocument.Selection
        Dim objPosition As EnvDTE.TextPoint
        objPosition = objSelection.AnchorPoint
        objSelection.SelectLine()
        If (InStr(objSelection.Text.ToLower(), "#region") <> 0) Then  'Updated 14.08.2003
            objSelection.MoveToPoint(objPosition)
            DTE.ExecuteCommand("Edit.ToggleOutliningExpansion")

            DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn)
        ElseIf (objSelection.FindText("#region", vsFindOptions.vsFindOptionsBackwards)) Then

            DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn)
            DTE.ExecuteCommand("Edit.ToggleOutliningExpansion")

            DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn)
        Else
            objSelection.MoveToPoint(objPosition)
        End If
    End Sub

    ' Expands all regions in the current document
    Sub ExpandAllRegions()

        Dim objSelection As TextSelection ' Our selection object

        DTE.SuppressUI = True ' Disable UI while we do this
        objSelection = DTE.ActiveDocument.Selection() ' Hook up to the ActiveDocument() 's selection
        objSelection.StartOfDocument() ' Shoot to the start of the Document()

        ' Loop through the document finding all instances of #region. This action has the side benefit
        ' of actually zooming us to the text in question when it is found and ALSO expanding it since it
        ' is an outline.
        Do While objSelection.FindText("#region", vsFindOptions.vsFindOptionsMatchInHiddenText)
            ' This next command would be what we would normally do *IF* the find operation didn't do it for us.
            'DTE.ExecuteCommand("Edit.ToggleOutliningExpansion")
        Loop
        objSelection.StartOfDocument() ' Shoot us back to the start of the(Document)
        DTE.SuppressUI = False ' Reenable the UI

        objSelection = Nothing ' Release our object

    End Sub

    ' Collapses all regions in the current document
    Sub CollapseAllRegions()

        Dim objSelection As TextSelection ' Our selection object

        ExpandAllRegions() ' Force the expansion of all regions

        DTE.SuppressUI = True ' Disable UI while we do this
        objSelection = DTE.ActiveDocument.Selection() ' Hook up to the ActiveDocument() 's selection
        objSelection.EndOfDocument() ' Shoot to the end of the document

        ' Find the first occurence of #region from the end of the document to the start of the document. Note:
        ' Note: Once a #region is "collapsed" .FindText only sees it's "textual descriptor" unless
        ' vsFindOptions.vsFindOptionsMatchInHiddenText is specified. So when a #region "My Class" is collapsed,
        ' .FindText would subsequently see the text 'My Class' instead of()
        ' #region "My Class"' for the subsequent
        ' passes and skip any regions already collapsed.
        Do While (objSelection.FindText("#region", vsFindOptions.vsFindOptionsBackwards))
            DTE.ExecuteCommand("Edit.ToggleOutliningExpansion") 'Collapse this #region
            objSelection.EndOfDocument() ' Shoot back to the end of the document for
            ' another pass.
        Loop
        objSelection.StartOfDocument() ' All done, head back to the start of the doc
        DTE.SuppressUI = False ' Reenable the UI

        objSelection = Nothing ' Release our object

    End Sub

End Module
