locked
VS2012 FontAndColors text editor category for language service colors RRS feed

  • Question

  • Hi All,

    I've been fighting for several hours trying to force font and color settings to update in VS2012 on a newly installed package with a language service. This does not appear to happen automatically with either a package install or a VSIX install. The suggested code I've found recommends clearing and/or refreshing the cache for the text editor category (using IVsFontAndColorManager.ClearCache and/or RefreshCache). If colors have not been verified for an installed revision of my package (as recorded in a user registry setting), I search IVsFontAndColorStorage for the required colors, then call ClearCache as needed.

    This works fine against the text editor category in VS2010 (category guid {A27B4E24-A735-4d1d-B8E7-9716E1E3D8E0}). However, in VS2012 the code had no effect in updating the options dialog or actually producing colors for my language service.

    After digging through the registry I found a text editor subcategory called either 'Text Editor Language Service Items' or just 'Language Service Items'. Using the associated category identifier (category {E0187991-B458-4F7E-8CA9-42C9A573B56C}) actually forces the language service to be asked for its colorable items.

    So, while I can use the text editor category to get cached items, I cannot use the same text editor category to clear the cache. I need to explicitly use the subcategory.

    I would like some verification or an official name for this magic category id. The text editor category id is in Microsoft.Visualtudio.Shell.Interop.FontsAndColorsCategory.TextEditor and can also be found in the SDK .idl and .h files, but I'm not finding this other id anywhere.

      • Does this magic new category id have a name?
      • Can it be found in the SDK?
      • Can you verify the behavior I'm seeing?

    Thanks,

    -Matt

    PS This whole area has gotten progressively less stable moving from VS2005/08/10/12. In 2010 the language service would show colors that were not represented in the cache or options dialog. In 2012, you just get default text, so forcing the cache to reset is suddenly pri 1 (no coloring at all) instead of pri 3 (can't view and customize colors).

    Tuesday, October 9, 2012 2:43 AM

All replies

  • Hi Matt,

    >Does this magic new category id have a name?

    Do you mean the color Category?

    The Category is the non-localized name of the category

    Here is an article about How to: Access the Built-in Fonts and Color Scheme:

    http://msdn.microsoft.com/en-us/library/bb165737.aspx

    Is it helpful to you?

    Best regards,


    Ego [MSFT]
    MSDN Community Support | Feedback to us

    Wednesday, October 10, 2012 6:55 AM
  • Hi Ego,

    While that is related--I also do custom color categories for other parts of the package--I don't think those topics address the issue here, which is specifically related to the text editor category, which is managed by the vs core.

      • I have a language service that implements IVsProvideColorableItems. The editor is created with VsCodeWindowClass.
      • The customization of these items occurs through the 'Text Editor' category in the 'Fonts and Colors' page.
      • The list of text editor colors is not updated automatically on devenv /setup or a vsix install.
      • To verify that the colors are correct the first time my tool window is displayed, I use IVsFontAndColorStorage to see if my colors are available.
      • If the colors are not available, I use the IVsFontAndColorCacheManager.ClearCache method (sorry, I spelled the interface wrong in the first message) to clear the cache, which forces the colors to be requested from my language service.

    In VS2010 (and earlier), I use the Microsoft.VisualStudio.Shell.Interop.FontsAndColorsCategory.TextEditor guid as the category for steps four and five. Also note in this environment that my colors display correctly in my editor even if they are not visible in the options dialog.

    In VS2012 I get no color support if the items are not in the cache, so getting the colors into the cache is a critical issue. However, while step 4 works with the original guid, step 5 has no effect.

    Digging through the registry, I found that HKCU\Software\Microsoft\VisualStudio\11.0\FontAndColors\Cache\{A27B4E24-A735-4d1d-B8E7-9716E1E3D8E0}\@SubcategoryGuid0={E0187991-B458-4F7E-8CA9-42C9A573B56C} differs from the correspond VisualStudio\10.0 registry structure. The value guid is also a key in the cache with a name of Language Service Items, and this guid also appears as the category value in HKCU\Software\Microsoft\VisualStudio\11.0_Confi\FontAndColors\Text Editor Language Service Items.

    From here I guessed that if I used this new guid {E018...} as my category instead of the primary text editor category that step 5 (clear the cache and force color retrieval from my language service) would work correctly, which indeed it does.

    So, my question is: does the new category guid, which apparently represents all text editor colors retrieved from language services, have a name, and is it officially documented in the SDK?

    Of course, if you could provide a way to get these colors to install (and uninstall) correctly without jumping through the hoops on load then that would be nice as well.

    -Matt


    • Edited by Matt Curland Wednesday, October 10, 2012 9:12 PM
    Wednesday, October 10, 2012 9:11 PM
  • Our fonts and colors expert it on vacation until next week, so I doubt anyone with a deep knowledge could take a look / suggest best practices until he returns.
    Wednesday, October 10, 2012 9:57 PM
  • I am experiencing these exact same issues. I have been working around it by deleting the Cache in the Registry during the MSI installation of our language service, but that doesn't work 100% of the time. Is there any reply from Microsoft that is not in this thread? Or have you found a better solution?

    -Chris


    -Chris

    Friday, February 1, 2013 8:45 PM
  • Hi Chris,

    I haven't gotten any additional feedback from Microsoft, but my solution has been working to my satisfaction.

    I don't want to repeatedly verify the cache contents--once in the initial session is plenty--so in GetColorizer on the language service I check a user registry key to see if colors have been checked for the current version of my tool (based on the assembly revision number from the language service type). If the colors have not been checked, then I first verify that each of my current colors is cached. I proceed to clear the cache only if I find a missing color. I also added setup code to rip the 'I've already checked the cache for this revision of the tool' on uninstall. Getting fingers directly into the VS cache during installation is scary and likely much harder and more expensive than it sounds, so I avoided the problem.

    The relevant code is shown here (some of the data structures are mine, but most are general use). If you want to see additional context, this is from the trunk/ORMModel/Shell/FactEditor/FactEditorLanguageService.cs file in the code repository at orm.sf.net (around line 290 in GetColorizer). FactEditorFontsAndColors.cs in the same directory is related as well.

    object[] customAttributes = this.GetType().Assembly.GetCustomAttributes(typeof(AssemblyFileVersionAttribute), false);
    int expectedRevisionNumber = customAttributes.Length != 0 ? new Version(((AssemblyFileVersionAttribute)customAttributes[0]).Version).Revision : 0;
    if (null == (objVal = userKey.GetValue(REGISTRYVALUE_FACTEDITORCOLORSCHECKEDFORREVISION, 0)) ||
    	!(objVal is int) ||
    	expectedRevisionNumber != (int)objVal)
    {
    	userKey.SetValue(REGISTRYVALUE_FACTEDITORCOLORSCHECKEDFORREVISION, expectedRevisionNumber, RegistryValueKind.DWord);
    	IVsFontAndColorStorage storage;
    	Guid textMgrIID = new Guid(
    #if VISUALSTUDIO_11_0
    		"{E0187991-B458-4F7E-8CA9-42C9A573B56C}" /* 'Text Editor Language Services Items' category discovered in the registry. Resetting TextEditor has no effect. */
    #else
    		FontsAndColorsCategory.TextEditor
    #endif
    	);
    	if (null != (storage = GetService(typeof(IVsFontAndColorStorage)) as IVsFontAndColorStorage) &&
    		VSConstants.S_OK == storage.OpenCategory(ref textMgrIID, (uint)(__FCSTORAGEFLAGS.FCSF_READONLY | __FCSTORAGEFLAGS.FCSF_LOADDEFAULTS)))
    	{
    		bool missingColor = false;
    		try
    		{
    			DefaultColorSetting[] colorSettings = myDefaultColorSettings;
    			ColorableItemInfo[] info = new ColorableItemInfo[1];
    			for (int i = 0; i < colorSettings.Length; ++i)
    			{
    				if (ErrorHandler.Failed(storage.GetItem(ResourceStrings.GetColorNameString(colorSettings[i].LocalizedNameId), info)))
    				{
    					missingColor = true;
    					break;
    				}
    			}
    		}
    		finally
    		{
    			storage.CloseCategory();
    		}
    		if (missingColor)
    		{
    			IOleServiceProvider oleProvider;
    			// The service and interface guids are different, so we need to go to the OLE layer to get the service
    			Guid iid = typeof(IVsFontAndColorCacheManager).GUID;
    			Guid sid = typeof(SVsFontAndColorCacheManager).GUID;
    			IntPtr pCacheManager;
    			if (null != (oleProvider = GetService(typeof(IOleServiceProvider)) as IOleServiceProvider) &&
    				VSConstants.S_OK == oleProvider.QueryService(ref sid, ref iid, out pCacheManager) &&
    				pCacheManager != IntPtr.Zero)
    			{
    				try
    				{
    					IVsFontAndColorCacheManager cacheManager = (IVsFontAndColorCacheManager)Marshal.GetObjectForIUnknown(pCacheManager);
    					cacheManager.ClearCache(ref textMgrIID);
    				}
    				finally
    				{
    					Marshal.Release(pCacheManager);
    				}
    			}
    		}
    	}
    }

    Note to the Microsoft 'fonts and colors expert' (hopefully back from vacation after four months): this is much harder than it should be, and is a big problem in VS2012 because you get no coloring at all if the items are not cached. It needs to be documented for VS2012 and fixed in VNext so that installing a language service with devenv /setup or VSIX automatically populates the color cache. This is not an edge case. It appears to affect all language services with custom colors.

    -Matt

    Friday, February 1, 2013 10:46 PM
  • I'm having the same issue. I deleted HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0\FontAndColors\Cache locally to get past the issue, but this isn't practical for distribution and as far as I'm aware VSIX aren't allowed to do that kind of action.

    I'd very much appreciate a response to the original poster's question.

    • Edited by ColinCren Tuesday, October 22, 2013 9:07 PM
    Tuesday, October 22, 2013 8:45 PM