创建Visual Studio主题特定语法突出显示

时间:2014-06-25 09:06:11

标签: visual-studio visual-studio-2012 syntax-highlighting visual-studio-extensions vspackage

我想在Visual Studio 2012中创建一个语法荧光笔(及以上)支持不同的主题(深色,浅色,蓝色)。

Visual Studio的编辑器分类器项目模板说明了如何使用Microsoft.VisualStudio.Text.Classification.ClassificationFormatDefinition在环境中创建自己的颜色。它工作得很好......

...直到您意识到Visual Studio 2012(及更高版本)中存在不同的主题,并且您并不真正支持它们。在黑暗的主题环境中,浅色主题上漂亮的深蓝色标识符变得难以辨认。

根据我的理解,如果您在工具/选项/字体&中更改 ClassificationFormatDefinition 给定主题中的颜色(例如:Light)它不会影响不同主题中的相同 ClassificationFormatDefinition (例如:Dark)。不同主题的颜色似乎是独立的。

这很好。但如何定义相同的 ClassificationFormatDefinition (例如:MyKeywords),它们在所有主题中具有相同的名称,但为它们提供了不同的颜色?就像Visual Studio&# 39;拥有"标识符",在Light主题上默认为黑色,在黑色主题上为默认值。

我知道Microsoft.VisualStudio.PlatformUI.VSColorTheme.ThemeChanged事件可以让我在更改颜色主题时收到通知。我是否必须使用此功能并以某种方式获取现有的 ClassificationFormatDefinition 并根据新主题为其分配新颜色?但这也提出了一个问题:这些修改后的颜色是否会持久保存到环境中,即如果我重新启动Visual Studio,下次在所有不同的主题中我的更改是否会存在。

我还没有找到任何属性可以说明 ClassificationFormatDefinition 支持哪个主题,也找不到有关该主题的有用文章。

任何帮助表示感谢。

3 个答案:

答案 0 :(得分:2)

好的,这是我找到的解决方法。它远非完美,但它一样好。

诀窍是在定义自己的分类类型时使用另一个基本定义。这将使用不同主题的默认颜色。重要的是,您不能在MyKeywordsFormatDefinition中定义自己的颜色,因为这会在主题之间切换时禁用默认行为。因此,尝试找到与您的颜色匹配的基本定义。在此处查找预定义的分类类型:Microsoft.VisualStudio.Language.StandardClassification.PredefinedClassificationTypeNames

internal static class Classifications
{
    // ...
    public const string MyKeyword = "MyKeyword";
    // ...
}

[Export(typeof(EditorFormatDefinition))]
[ClassificationType(ClassificationTypeNames = Classifications.MyKeyword)]
[Name("MyKeywords")]
[DisplayName("My Keywords")]
[UserVisible(true)]
internal sealed class MyKeywordsFormatDefinition: ClassificationFormatDefinition
{
    // Don't set the color here, as it will disable the default color supporting themes
}

[Export(typeof(ClassificationTypeDefinition))]
[Name(Classifications.MyKeyword)]
[BaseDefinition(PredefinedClassificationTypeNames.Keyword)]
internal static ClassificationTypeDefinition MyKeywordsTypeDefinition;

我希望它对你们中的一些人有用。当你可以在不重复使用现有颜色定义的情况下实际设置自己的颜色时,甚至可以帮助改进适当的解决方案。

答案 1 :(得分:2)

这可能对您有帮助,来自F#Power Tools的代码似乎正在侦听ThemeChanged事件并更新分类器 - https://github.com/fsprojects/VisualFSharpPowerTools/blob/a7d7aa9dd3d2a90f21c6947867ac7d7163b9f99a/src/FSharpVSPowerTools/SyntaxConstructClassifierProvider.cs

答案 2 :(得分:0)

还有另一种更清洁的方式是使用VS SDK随附的VsixColorCompiler

首先,照常创建ClassificationTypeDefinitionClassificationFormatDefinition。这将在所有主题中定义默认颜色:

public static class MyClassifications
{
    public const string CustomThing = "MyClassifications/CustomThing";

    [Export]
    [Name(CustomThing)]
    public static ClassificationTypeDefinition CustomThingType = null;

    [Export(typeof(EditorFormatDefinition))]
    [ClassificationType(ClassificationTypeNames = CustomThing)]
    [UserVisible(true)]  // Note: must be user-visible to be themed!
    [Name(CustomThing)]
    public sealed class CustomThingFormatDefinition : ClassificationFormatDefinition
    {
        public CustomThingFormatDefinition()
        {
            ForegroundColor = Color.FromRgb(0xFF, 0x22, 0x22);  // default colour in all themes
            DisplayName = "Custom Thing";  // appears in Fonts and Colors options
        }
    }
}

接下来,创建一个colours.xml文件。这将使我们可以覆盖特定主题的颜色:

<!-- Syntax described here: https://docs.microsoft.com/en-us/visualstudio/extensibility/internals/vsix-color-compiler -->
<Themes>
  <Theme Name="Light" GUID="{de3dbbcd-f642-433c-8353-8f1df4370aba}">
  </Theme>
  <Theme Name="Dark" GUID="{1ded0138-47ce-435e-84ef-9ec1f439b749}">
    <!-- MEF colour overrides for dark theme -->
    <Category Name="MEFColours" GUID="{75A05685-00A8-4DED-BAE5-E7A50BFA929A}">
      <Color Name="MyClassifications/CustomThing">
        <Foreground Type="CT_RAW" Source="FF2222FF" />
      </Color>
    </Category>
  </Theme>
</Themes>

现在,编辑您的.csproj,使其包含一个后生成命令,以将XML编译为常规包.pkgdef(此处显示VS2015 SDK)旁边的.pkgdef:

<Target Name="AfterBuild">
  <Message Text="Compiling themed colours..." Importance="high" />
  <Exec Command="&quot;$(VSSDK140Install)\VisualStudioIntegration\Tools\Bin\VsixColorCompiler.exe&quot; /noLogo &quot;$(ProjectDir)colours.xml&quot; &quot;$(OutputPath)\MyPackage.Colours.pkgdef&quot;" />
</Target>

每当进行更改时,请确保在内部版本之间clear the MEF cache进行强制更新。此外,以下注册表项也可能需要删除:

HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0\FontAndColors\Cache\{75A05685-00A8-4DED-BAE5-E7A50BFA929A}
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0Exp\FontAndColors\Cache\{75A05685-00A8-4DED-BAE5-E7A50BFA929A}