语法 Colorizing (托管包结构)
语法着色是一个源文件错误引起一种编程语言的不同组件显示不同的颜色和样式的功能。 若要支持此功能,您需要提供可识别词法元素或标记的类型文件中的分析器或扫描仪。 许多语言通过 colorizing 它们区分关键字、分隔符 (例如括号或大括号) 和注释以不同的方式。
实现
若要支持着色,托管包框架 (MPF)包括 Colorizer 类,该类实现 IVsColorizer 接口。 此类与 IScanner 确定标记和颜色。 有关扫描仪的更多信息,请参见 语言服务分析器和扫描仪 (托管包结构)。 Colorizer 类然后指示标记的每个字符与颜色信息并将该信息返回到显示源文件的编辑器。
颜色信息返回到编辑器是索引到可着色项列表。 每个可着色项指定颜色值和设置字体属性,例如粗体或删除线。 编辑器提供设置语言服务中使用的默认可着色项。 您需要做的所有工作是每个标记类型的指定适当的染料索引。 但是,您可以提供为标记提供的设置自定义可着色项和索引,并且引用限制列表可着色项 (而不是默认的。 还必须设置 RequestStockColors 注册表项到 0 (或根本不指定 RequestStockColors 项) 支持自定义颜色。 可以设置一个命名参数的此注册表项。 ProvideLanguageServiceAttribute 用户定义的特性。 有关注册语言服务并将其选项的更多信息,请参见 注册语言服务 (托管包结构)。
自定义可着色项
若要提供拥有自定义可着色项,必须重写 GetItemCount 和 GetColorableItem 方法在 LanguageService 类。 第一种方法返回语言服务支持自定义可着色项的数目,第二个按索引获取该自定义可着色项。 您创建默认的自定义可着色项。 在语言服务的构造函数,则需要做的所有工作是对每个可着色项会将名称。 自动 Visual Studio 处理用例用户选择其他设置可着色项的位置。 此名称是什么出现在 选项 对话框的 字体和颜色 属性页 (可从 Visual Studio 工具 菜单),并且此名称确定哪种颜色用户重写。 用户的选择在注册表中。缓存存储并按颜色名称访问的。 字体和颜色 属性页按字母顺序列出所有颜色名称,因此,您可以为自定义通过对于每种颜色名称为与语言名称的组;例如, “TestLanguage- 注释”和 “TestLanguage- 关键字”。 也可以按类型分组可着色项, “注释 (TestLanguage)”和 “关键字 (TestLanguage)”。 (按语言名称首选方法。
警告
强烈建议您在可着色项名称包括语言名称就避免了与现有可着色项名称的冲突。
备注
在开发过程中,如果更改名称的一种颜色,必须重新设置首次创建颜色的 Visual Studio 捕获的缓存。可以通过运行从 Visual Studio SDK 程序菜单的 重置实验项 命令执行此操作。
监视可着色项列表中的第一项从不引用。 Visual Studio 始终提供默认的文本颜色和属性该项目中。 最简单的方法将该将提供占位符可着色项作为第一项。
深颜色可着色项
可着色项可以通过 IVsHiColorItem 接口还支持 24 位或深颜色值。 MPF ColorableItem 类支持 IVsHiColorItem 接口,而 24 位颜色在构造函数中指定与常规的颜色。 有关详细信息 ColorableItem 参见类。 在下面的示例显示了如何设置关键字和注释的 24 位颜色。 24 位颜色,将 24 位颜色在用户的桌面时,支持使用;否则,使用常规文本颜色。
请记住,这些是该语言的默认颜色;用户可以更改这些颜色改为与他们希望。
示例
使用 ColorableItem 类,此示例演示一种声明和填充数组自定义可着色项。 使用 24 位颜色,此示例将关键字和注释颜色。
using Microsoft.VisualStudio.Package;
using Microsoft.VisualStudio.TextManager.Interop;
namespace TestLanguagePackage
{
public class TestLanguageService : LanguageService
{
private ColorableItem[] m_colorableItems;
TestLanguageService() : base()
{
m_colorableItems = new ColorableItem[] {
new ColorableItem("TestLanguage – Text",
"Text",
COLORINDEX.CI_SYSPLAINTEXT_FG,
COLORINDEX.CI_SYSPLAINTEXT_BK,
System.Drawing.Color.Empty,
System.Drawing.Color.Empty,
FONTFLAGS.FF_DEFAULT),
new ColorableItem("TestLanguage – Keyword",
"Keyword",
COLORINDEX.CI_MAROON,
COLORINDEX.CI_SYSPLAINTEXT_BK,
System.Drawing.Color.FromArgb(192,32,32),
System.Drawing.Color.Empty,
FONTFLAGS.FF_BOLD),
new ColorableItem("TestLanguage – Comment",
"Comment",
COLORINDEX.CI_DARKGREEN,
COLORINDEX.CI_LIGHTGRAY,
System.Drawing.Color.FromArgb(32,128,32),
System.Drawing.Color.Empty,
FONTFLAGS.FF_DEFAULT)
// ...
// Add as many colorable items as you want to support.
};
}
}
}
Colorizer 类和扫描仪
基础 LanguageService 类有一个 GetColorizer 的方法 instantiantes Colorizer 类。 从 GetScanner 方法返回的扫描仪传递给 Colorizer 类构造函数。
您必须在的 GetScanner 方法拥有 LanguageService 类的版本。 Colorizer 类使用扫描仪获取所有标记颜色信息。
扫描仪需要填写找到每个标记的一 TokenInfo 结构。 此结构包含信息 (如该标记占用的大小,染料索引使用,类型为标记和标记触发器 (请参见 TokenTriggers)。 仅大小和染料索引为着色是必需的。 Colorizer 类。
在 TokenInfo 结构存储的染料索引通常是从 TokenColor 枚举的值,提供了很多人名索引与各种语言元素对应如关键字和运算符。 如果自定义可着色项列表与 TokenColor 枚举存在的项目,则可以使用枚举作为颜色为每个标记。 但是,因此,如果您有不同的可着色项或不希望按照这个顺序使用现有值,可以使自定义可着色项列表交互需求,并返回相应的索引。该列表。 请,当将其存储在 TokenInfo 结构时,请确保将索引。 TokenColor ; Visual Studio 只显示索引。
示例
下面的示例演示扫描程序如何标识三个标记类型:数字、标点符号和标识符 (不是数字和标点) 的任何名称。 此示例仅用于说明目的是和不表示一个完整的分析器和扫描仪实现。 假定,具有返回字符串的 GetNextToken() 方法的 Lexer 类。
using Microsoft.VisualStudio.Package;
using Microsoft.VisualStudio.TextManager.Interop;
namespace TestLanguagePackage
{
private Lexer lex;
public class TestScanner : IScanner
{
public bool ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo,
ref int state)
{
bool foundToken = false;
string token = lex.GetNextToken();
if (token != null)
{
char firstChar = token[0];
if (Char.IsPunctuation(firstChar))
{
tokenInfo.Type = TokenType.Operator;
tokenInfo.Color = TokenColor.Keyword;
}
else if (Char.IsNumber)
{
tokenInfo.Type = TokenType.Literal;
tokenInfo.Color = TokenColor.Number;
}
else
{
tokenInfo.Type = TokenType.Identifier;
tokenInfo.Color = TokenColor.Identifier;
}
}
return foundToken;
}