|
|
Accessing Values From Tools Options Window With An Add-inTextEditor Formatting Options | | 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.

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. |  |
|
|