KnowDotNet Visual Organizer

Accessing Values From Tools Options Window With An Add-in

TextEditor Formatting Options

by Les Smith
Print this Article Discuss in Forums

How do I access the formatting options of the TextEditor in an add-in?  How do I know the values to use in referencing DTE.Properties?

One of the "great mysteries" of Visual Studio Extensibility has been to discover the values to be used when specifying String Parameters to access DTE.Properties.  Specifically, where can I find the strings to be used in accessing the values of the Tools, Options Dialog?  Although they are not meant to be hidden from the Add-In Developer, most of the time these values are not easily discovered.  The serious add-in developer will have to work to develop industrial-strength add-ins that people are willing to pay money for.  At KnowDotNet, we give away a lot of knowledge, answer questions and try to help folks on the forums, and from time to time freely give away code that took us much work to produce.

Anytime you see us come out with a new product, in the form of an add-in, you can rest assured that we have spent litterly hundreds of hours in producing an add-in that, on the surface, may have only a few or a great number of features.  You might think that an add-in, such as the forth-coming Visual Class Organizer, which basically does one major thing with several ways of doing it, couldn't really be a huge undertaking, since it "only does one thing";  It allows the developer to visually organize classes.  But, under the cover, there is a lot of research and trial and error, and ingenuity in discovering ways to extend the Visual Studio IDE.

Such is the case with the
CSharpCompleter add-in, which automatically adds curly braces upon completion of a line of C# code.  Different developers have different styles of programming.  I think this is especially true when dealing with C# developers and their use of curly braces or squigglies ({}).  For example some prefer to have braces lined up and on new lines such as the following code snippet.  All though this tends to create a lot more white space and spread the code vertically more than the next example, it simply is my preference.

Figure 1 - Braces on New Lines.

      private int Testing3(int j, string a)
      {
        
int k = 0;
        
if (j == 1)
         {
            j = 3;
            a =
"A";
         }
        
else
         {
            k = 3;
            a =
"B";
         }
        
return k;
      }

Other developers, on the other hand, prefer to put as much on a single line as possible and keep their code more compact, as shown below.  

Figure 2 - Braces on Same Line.

      private int Testing2(int j, ref string a) {
        
int k = 0;
        
if (j == 1) { k = 1; } else { k = 2; a = "A"; }
        
return k;
      }

Although that style certainly has less white space, to me it is not necessarily harder to harder to follow, but over the long haul doesn't look as clean to me.   However, this is all a matter of preference and not the subject of this article.

But because there are different styles of coding, Microsoft has provided options in the IDE to accommodate both styles.  The options are found in the Tools, Options Dialog, as shown in Figure 3 below.

Figure 3 - Tool Options Dialog.

NewLine Braces


Now, the subject of the article is how to access these values from an add-in.  I need to do that so that I can programitically determine the preferred style of development that the developer uses.  The line that allows you to access these options looks like the following line of Macro code.

        Dim bracesType As Integer = DTE.Properties("TextEditor", _
          
"CSharp-Specific").Item("NewLines_Braces_Type").Value

The problem is how to determine the string values used in the statement shown above.  Let me tell you quickly that you cannot do it by looking at Figure 3 above.  You won't get close!  So how do you do it?  First, your favorite search engine is your friend.  The greatest time-saver for a developer to learn is to go to the search engines before you go to the forums or user-groups.  Undoubtedly, somone has seen the problem you are experiencing before you have.  So that's what I did.  I put "extensibility TextEditor PlainText Tabsize" into my favorite search engine and found
this link.  Among other things, it had this information on it.  "These names are stored in the Windows registry hive, HKLM\SOFTWARE\Microsoft\VisualStudio\8.0\AutomationProperties."

I went to Regedit, chased down the property and found that to get to TextEditor, C#, Formatting, New Lines, I needed to use the string "CSharp-Specific".  I was almost there, but not quite.  I still needed to know how to reference "New Lines", and you guessed it, "New Lines" is not the string.  

I found
another link, that gave me the following Macro code.  It lists all of the property names for CSharp Formatting properties.

    Sub PropertiesExample()
        
' Create and initialize a variable to represent the C#
        ' Formatting text editor options page.
        Dim txtEdCSFormat As EnvDTE.Properties = _
        DTE.Properties(
"TextEditor", "CSharp - Formatting")
        
Dim prop As EnvDTE.Property
        
Dim msg As String

        ' Loop through each item in the C# Formatting Options page.
        For Each prop In txtEdCSFormat
            msg += (
"PROP NAME: " & prop.Name & "   VALUE: " & _
            prop.Value) & vbCr
        
Next
        Debug.Print(msg)
    
End Sub

The only problem is that "CSharp - Formatting") yields an "Invalid Index" exception.  So I need to look at the registry entry to determine that the real access string is "CSharp-Specific".  Close does not count in this area, as in all areas of software development.  Having replaced the former value with the latter value, I got the following listing of "CSharp-Speific" properties.

Figure 4 - C# Text Editor Options Values.
PROP NAME: AutoComment   VALUE: 1
PROP NAME: BraceMatchingRectangle   VALUE: 1
PROP NAME: BringUpOnEventHookup   VALUE: 1
PROP NAME: BringUpOnIdentifier   VALUE: 1
PROP NAME: BringUpOnOverride   VALUE: 1
PROP NAME: BringUpOnSpace   VALUE: 1
PROP NAME: CodeDefinitionWindow_DocumentationComment_IndentBase   VALUE: 1
PROP NAME: CodeDefinitionWindow_DocumentationComment_IndentOffset   VALUE: 2
PROP NAME: CodeDefinitionWindow_DocumentationComment_WrapLength   VALUE: 80
PROP NAME: CollapseInactiveBlocksOnOpen   VALUE: 1
PROP NAME: CollapseRegionBlocksOnOpen   VALUE: 1
PROP NAME: Colorize   VALUE: 1
PROP NAME: ColorizeBoundTypes   VALUE: 1
PROP NAME: CompleteOnNewline   VALUE: 1
PROP NAME: CompleteOnSpace   VALUE: 1
PROP NAME: CompletionCommitCharacters   VALUE: {}[]().,:;+-*/%&|^!~=<>?@#'"\
PROP NAME: DelayBeforeShowingErrors   VALUE: 1500
PROP NAME: EditAndContinueEnabled   VALUE: 1
PROP NAME: EditAndContinueReportEnterBreakStateFailure   VALUE: 1
PROP NAME: Enabled   VALUE: 1
PROP NAME: EnableProgressDialogOnWaitForBackground   VALUE: 1
PROP NAME: EncapsulateField_PreviewReferenceChanges   VALUE: 1
PROP NAME: EncapsulateField_SearchInComments   VALUE: 0
PROP NAME: EncapsulateField_SearchInStrings   VALUE: 0
PROP NAME: EncapsulateField_UpdateAllReferences   VALUE: 0
PROP NAME: EnterOutliningModeOnOpen   VALUE: 1
PROP NAME: ExtractInterface_SelectAll   VALUE: 0
PROP NAME: FilterKeywordsContextually   VALUE: 1
PROP NAME: FilterToAllowableTypes   VALUE: 1
PROP NAME: Formatting_TriggerOnBlockCompletion   VALUE: 1
PROP NAME: Formatting_TriggerOnPaste   VALUE: 1
PROP NAME: Formatting_TriggerOnStatementCompletion   VALUE: 1
PROP NAME: GenerateStub   VALUE: 1
PROP NAME: ImplementInterface   VALUE: 1
PROP NAME: ImplementInterface_InsertRegionTags   VALUE: 1
PROP NAME: Indent_BlockContents   VALUE: 1
PROP NAME: Indent_Braces   VALUE: 0
PROP NAME: Indent_CaseContents   VALUE: 1
PROP NAME: Indent_CaseLabels   VALUE: 1
PROP NAME: Indent_FlushLabelsLeft   VALUE: 0
PROP NAME: Indent_UnindentLabels   VALUE: 1
PROP NAME: InsertNewlineOnEnterWithWholeWord   VALUE: 0
PROP NAME: NeverShowBuildWarningDialog   VALUE: 0
PROP NAME: NewLines_Braces_AnonymousMethod   VALUE: 1
PROP NAME: NewLines_Braces_ArrayInitializer   VALUE: 0
PROP NAME: NewLines_Braces_ControlFlow   VALUE: 1
PROP NAME: NewLines_Braces_Method   VALUE: 1
PROP NAME: NewLines_Braces_Type   VALUE: 0
PROP NAME: NewLines_Keywords_Catch   VALUE: 1
PROP NAME: NewLines_Keywords_Else   VALUE: 1
PROP NAME: NewLines_Keywords_Finally   VALUE: 1
PROP NAME: OnlyScanFirstTypeInFileForDesignerAttribute   VALUE: 0
PROP NAME: ProgressDialogDelaySeconds   VALUE: 2
PROP NAME: QuickInfo_ShowAllExceptions   VALUE: 1
PROP NAME: RefactorNotifyRenameEnabled   VALUE: 1
PROP NAME: RemoveParameters_PreviewReferenceChanges   VALUE: 1
PROP NAME: Rename   VALUE: 1
PROP NAME: Rename_Comments   VALUE: 0
PROP NAME: Rename_Overloads   VALUE: 0
PROP NAME: Rename_Preview   VALUE: 1
PROP NAME: Rename_Strings   VALUE: 0
PROP NAME: ReorderParameters_PreviewReferenceChanges   VALUE: 1
PROP NAME: ShowHiddenItems   VALUE: 0
PROP NAME: ShowKeywords   VALUE: 1
PROP NAME: ShowSnippets   VALUE: 1
PROP NAME: SignatureChange   VALUE: 1
PROP NAME: Space_AfterBasesColon   VALUE: 1
PROP NAME: Space_AfterCast   VALUE: 0
PROP NAME: Space_AfterComma   VALUE: 1
PROP NAME: Space_AfterDot   VALUE: 0
PROP NAME: Space_AfterMethodCallName   VALUE: 0
PROP NAME: Space_AfterMethodDeclarationName   VALUE: 0
PROP NAME: Space_AfterSemicolonsInForStatement   VALUE: 1
PROP NAME: Space_AroundBinaryOperator   VALUE: 1
PROP NAME: Space_BeforeBasesColon   VALUE: 1
PROP NAME: Space_BeforeComma   VALUE: 0
PROP NAME: Space_BeforeDot   VALUE: 0
PROP NAME: Space_BeforeOpenSquare   VALUE: 0
PROP NAME: Space_BeforeSemicolonsInForStatement   VALUE: 0
PROP NAME: Space_BetweenEmptyMethodCallParentheses   VALUE: 0
PROP NAME: Space_BetweenEmptyMethodDeclarationParentheses   VALUE: 0
PROP NAME: Space_BetweenEmptySquares   VALUE: 0
PROP NAME: Space_InControlFlowConstruct   VALUE: 1
PROP NAME: Space_Normalize   VALUE: 0
PROP NAME: Space_WithinCastParentheses   VALUE: 0
PROP NAME: Space_WithinExpressionParentheses   VALUE: 0
PROP NAME: Space_WithinMethodCallParentheses   VALUE: 0
PROP NAME: Space_WithinMethodDeclarationParentheses   VALUE: 0
PROP NAME: Space_WithinOtherParentheses   VALUE: 0
PROP NAME: Space_WithinSquares   VALUE: 0
PROP NAME: Squiggles   VALUE: 1
PROP NAME: TrackMostRecentlyUsed   VALUE: 1
PROP NAME: UnboundItem   VALUE: 1
PROP NAME: UnboundItem_ExactMatches   VALUE: 5
PROP NAME: Watson_DeferSendingUntilLater   VALUE: 0
PROP NAME: Watson_MaxExceptionsToReport   VALUE: 1
PROP NAME: Watson_ReportExceptions   VALUE: 1
PROP NAME: Wrapping_IgnoreSpacesAroundBinaryOperators   VALUE: 0
PROP NAME: Wrapping_KeepStatementsOnSingleLine   VALUE: 1
PROP NAME: Wrapping_PreserveSingleLine   VALUE: 1
Looking for New Lines, I found the lines highlighted in Red above. It was the one that I was looking for.  Placing the values in the macro shown below, I can set the corresponding values in the Tools Options Dialog to checked or unchecked by changing the value of the of the "checked" constant.  Setting it to 0 will uncheck the dialog options.  Setting it to 1 will check the options.

    Sub SetCSPropertiesExample()
        
Const checked = 1 ' 0 for unchecked, 1 for checked
        DTE.Properties("TextEditor", _
          
"CSharp-Specific").Item("NewLines_Braces_AnonymousMethod").Value = checked
        DTE.Properties(
"TextEditor", _
          
"CSharp-Specific").Item("NewLines_Braces_ControlFlow").Value = checked
        DTE.Properties(
"TextEditor", _
          
"CSharp-Specific").Item("NewLines_Braces_Method").Value = checked
        DTE.Properties(
"TextEditor", _
          
"CSharp-Specific").Item("NewLines_Braces_Type").Value = checked
        DTE.Properties(
"TextEditor", _
          
"CSharp-Specific").Item("NewLines_Keywords_Catch").Value = checked
        DTE.Properties(
"TextEditor", _
          
"CSharp-Specific").Item("NewLines_Keywords_Else").Value = checked
        DTE.Properties(
"TextEditor", _
          
"CSharp-Specific").Item("NewLines_Keywords_Finally").Value = checked
    
End Sub


By using the macro shown below, I can retrieve the values that I need to make an enhancement to the
CSharpCompleter add-in that I was updating.  This allows me to determine which style of C# braces the developer is using without having to make them tell me again in a redundant setup dialog in the add-in.

    Sub RetrieveCSPropertiesExample()
        
Dim bracesAnonymousMethod As Integer = DTE.Properties("TextEditor", _
          
"CSharp-Specific").Item("NewLines_Braces_AnonymousMethod").Value
        
Dim bracesControlFlow As Integer = DTE.Properties("TextEditor", _
          
"CSharp-Specific").Item("NewLines_Braces_ControlFlow").Value
        
Dim bracesMethod As Integer = DTE.Properties("TextEditor", _
          
"CSharp-Specific").Item("NewLines_Braces_Method").Value
        
Dim bracesType As Integer = DTE.Properties("TextEditor", _
          
"CSharp-Specific").Item("NewLines_Braces_Type").Value
        
Dim newlinesCatch As Integer = DTE.Properties("TextEditor", _
          
"CSharp-Specific").Item("NewLines_Keywords_Catch").Value
        
Dim newlinesElse As Integer = DTE.Properties("TextEditor", _
          
"CSharp-Specific").Item("NewLines_Keywords_Else").Value
        
Dim newlinesFinally As Integer = DTE.Properties("TextEditor", _
          
"CSharp-Specific").Item("NewLines_Keywords_Finally").Value
    
End Sub

I hope this will not only give you some well hidden information, but also help you to learn how to solve some of the inherent mysteries in Extensibility in the future.

Ask a Question, or give your feedback on my articles or products by going to the KnowDotNet Forum or by clicking on My Blog.
  




Writing Add-Ins for Visual Studio .NET
Writing Add-ins for Visual Studio .NET
by Les Smith
Apress Publishing