- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用标准模板,我设法制作了一个自定义荧光笔,它将所有出现的字符串“Archive??????Key”(其中 ???? 是变量名称中允许的任何字符集合)变成粉红色。然而,我真正想要的是“存档”和“关键”部分变成粉红色,而“????”部分变成栗色。据我了解 VSIX 荧光笔(我真的不了解)这意味着定义两个 ClassificationFormatDefinition
,但每次尝试都会破坏项目。
我的 GetClassificationSpans
方法(这是与标准模板的唯一显着差异)如下所示:
public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span)
{
List<ClassificationSpan> spans = new List<ClassificationSpan>();
string text = span.GetText();
int idx0 = 0;
int idx1;
while (true)
{
idx0 = text.IndexOf(keyPrefix, idx0);
if (idx0 < 0)
break;
idx1 = text.IndexOf(keySuffix, idx0 + 6);
if (idx1 < 0)
break;
// TODO: make sure the prefix and suffix are part of the same object identifier.
string name = text.Substring(idx0 + lengthPrefix, idx1 - idx0 - lengthPrefix);
string full = text.Substring(idx0, idx1 - idx0 + keySuffix.Length);
SnapshotSpan span0 = new SnapshotSpan(span.Start + idx0, idx1 - idx0 + lengthSuffix);
SnapshotSpan span1 = new SnapshotSpan(span.Start + idx0 + lengthPrefix, idx1 - idx0 - lengthPrefix);
SnapshotSpan span2 = new SnapshotSpan(span.Start + idx1, lengthSuffix);
spans.Add(new ClassificationSpan(span0, classificationType));
spans.Add(new ClassificationSpan(span1, classificationType)); // I'd like to assign a different IClassificationType to this span.
spans.Add(new ClassificationSpan(span2, classificationType));
idx0 = idx1 + 5;
}
return spans;
}
span1
是我要分配不同样式的地方。我不明白执行这一(!)事情所需的分类器、格式、提供者和定义类如何相互关联,以及哪些可以了解多种样式。
最佳答案
模板很适合入门,但通常一旦您知道自己的前进方向,更直接地重新实现所有内容会更简单。
以下是所有部分如何组合在一起:
IClassificationTag
标记器)根据需要为文本缓冲区的给定部分生成分类标记跨度。ClassificationFormatDefinition
s)通过 MEF(作为 EditorFormatDefinition
s)导出,以便 VS 可以发现它们并将它们用于具有关联分类的颜色范围类型。它们还(可选)出现在“字体和颜色”选项中。因此,您需要的是定义和导出分别与两种分类类型关联的两种分类格式定义的代码。然后你的分类器需要相应地产生两种类型的标签。这是一个示例(未经测试):
public static class Classifications
{
// These are the strings that will be used to form the classification types
// and bind those types to formats
public const string ArchiveKey = "MyProject/ArchiveKey";
public const string ArchiveKeyVar = "MyProject/ArchiveKeyVar";
// These MEF exports define the types themselves
[Export]
[Name(ArchiveKey)]
private static ClassificationTypeDefinition ArchiveKeyType = null;
[Export]
[Name(ArchiveKeyVar)]
private static ClassificationTypeDefinition ArchiveKeyVarType = null;
// These are the format definitions that specify how things will look
[Export(typeof(EditorFormatDefinition))]
[ClassificationType(ClassificationTypeNames = ArchiveKey)]
[UserVisible(true)] // Controls whether it appears in Fonts & Colors options for user configuration
[Name(ArchiveKey)] // This could be anything but I like to reuse the classification type name
[Order(After = Priority.Default, Before = Priority.High)] // Optionally include this attribute if your classification should
// take precedence over some of the builtin ones like keywords
public sealed class ArchiveKeyFormatDefinition : ClassificationFormatDefinition
{
public ArchiveKeyFormatDefinition()
{
ForegroundColor = Color.FromRgb(0xFF, 0x69, 0xB4); // pink!
DisplayName = "This will display in Fonts & Colors";
}
}
[Export(typeof(EditorFormatDefinition))]
[ClassificationType(ClassificationTypeNames = ArchiveKeyVar)]
[UserVisible(true)]
[Name(ArchiveKeyVar)]
[Order(After = Priority.Default, Before = Priority.High)]
public sealed class ArchiveKeyVarFormatDefinition : ClassificationFormatDefinition
{
public ArchiveKeyVarFormatDefinition()
{
ForegroundColor = Color.FromRgb(0xB0, 0x30, 0x60); // maroon
DisplayName = "This too will display in Fonts & Colors";
}
}
}
提供商:
[Export(typeof(ITaggerProvider))]
[ContentType("text")] // or whatever content type your tagger applies to
[TagType(typeof(ClassificationTag))]
public class ArchiveKeyClassifierProvider : ITaggerProvider
{
[Import]
public IClassificationTypeRegistryService ClassificationTypeRegistry { get; set; }
public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag
{
return buffer.Properties.GetOrCreateSingletonProperty(() =>
new ArchiveKeyClassifier(buffer, ClassificationTypeRegistry)) as ITagger<T>;
}
}
最后,标注器本身:
public class ArchiveKeyClassifier : ITagger<ClassificationTag>
{
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
private Dictionary<string, ClassificationTag> _tags;
public ArchiveKeyClassifier(ITextBuffer subjectBuffer, IClassificationTypeRegistryService classificationRegistry)
{
// Build the tags that correspond to each of the possible classifications
_tags = new Dictionary<string, ClassificationTag> {
{ Classifications.ArchiveKey, BuildTag(classificationRegistry, Classifications.ArchiveKey) },
{ Classifications.ArchiveKeyVar, BuildTag(classificationRegistry, Classifications.ArchiveKeyVar) }
};
}
public IEnumerable<ITagSpan<ClassificationTag>> GetTags(NormalizedSnapshotSpanCollection spans)
{
if (spans.Count == 0)
yield break;
foreach (var span in spans) {
if (span.IsEmpty)
continue;
foreach (var identSpan in LexIdentifiers(span)) {
var ident = identSpan.GetText();
if (!ident.StartsWith("Archive") || !ident.EndsWith("Key"))
continue;
var varSpan = new SnapshotSpan(
identSpan.Start + "Archive".Length,
identSpan.End - "Key".Length);
yield return new TagSpan<ClassificationTag>(new SnapshotSpan(identSpan.Start, varSpan.Start), _tags[Classifications.ArchiveKey]);
yield return new TagSpan<ClassificationTag>(varSpan, _tags[Classifications.ArchiveKeyVar]);
yield return new TagSpan<ClassificationTag>(new SnapshotSpan(varSpan.End, identSpan.End), _tags[Classifications.ArchiveKey]);
}
}
}
private static IEnumerable<SnapshotSpan> LexIdentifiers(SnapshotSpan span)
{
// Tokenize the string into identifiers and numbers, returning only the identifiers
var s = span.GetText();
for (int i = 0; i < s.Length; ) {
if (char.IsLetter(s[i])) {
var start = i;
for (++i; i < s.Length && IsTokenChar(s[i]); ++i);
yield return new SnapshotSpan(span.Start + start, i - start);
continue;
}
if (char.IsDigit(s[i])) {
for (++i; i < s.Length && IsTokenChar(s[i]); ++i);
continue;
}
++i;
}
}
private static bool IsTokenChar(char c)
{
return char.IsLetterOrDigit(c) || c == '_';
}
private static ClassificationTag BuildTag(IClassificationTypeRegistryService classificationRegistry, string typeName)
{
return new ClassificationTag(classificationRegistry.GetClassificationType(typeName));
}
}
还有一点要注意:为了加速启动,VS保留了一个MEF导出的缓存。但是,这个缓存通常没有在应该失效的时候失效。此外,如果您更改现有分类格式定义的默认颜色,您的更改很可能不会被拾取,因为 VS 将以前的值保存在注册表中。为了减轻这种情况,最好在编译之间运行批处理脚本,以便在任何与 MEF 或格式相关的更改以清除内容时运行。下面是 VS2013 和 Exp 根后缀的示例(测试 VSIXes 时默认使用):
@echo off
del "%LOCALAPPDATA%\Microsoft\VisualStudio\12.0Exp\ComponentModelCache\Microsoft.VisualStudio.Default.cache" 2> nul
rmdir /S /Q "%LOCALAPPDATA%\Microsoft\VisualStudio\12.0Exp\ComponentModelCache" 2> nul
reg delete HKCU\Software\Microsoft\VisualStudio\12.0Exp\FontAndColors\Cache\{75A05685-00A8-4DED-BAE5-E7A50BFA929A} /f
关于c# - VSIX IClassifier 分配多个 ClassificationTypes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37579509/
我正在尝试自定义 Visual Studio 2010 的起始页。我已从 Microsoft 下载了自定义起始页项目模板来执行此操作。 http://visualstudiogallery.msdn.
我正在为我的项目创建自定义测试运行器。所以我创建了一个可以在 Visual Studio 中注册的测试 vsix 项目。 我也知道我通过 F5 加载了扩展,然后加载了 Visual Studio 的实
标题说明了一切:如何“提取”一个 .vsix 文件? 我正在遵循教程并将其声明为步骤,但我不理解它并且它不容易用谷歌搜索。 最佳答案 将文件扩展名重命名为 .zip,瞧,就像普通的 zip 一样解压它
当用户安装我的扩展程序但未安装最新的 Visual Studio 更新时,扩展程序无法解析 Microsoft.CodeAnalysis.CSharp.dll 带有以下消息: Could not lo
我已经通过 Code Refactoring (CodeRefactoringProvider) roslyn 项目创建了一个具有一些不错的重构功能的 Visual Studio 扩展,但是在添加工具
说明 我开发了一个 Visual Studio 扩展(VSPackage),它向 Visual Studio 添加了一个新的项目类型(使用 CPS Project System)。我还向 VSPack
我正在为我公司的 MVC 4 应用程序创建自定义 VSTemplate,它使用的向导与创建新 MVC4 应用程序时出现的向导相当。我有两个模板之一,我想在开发人员创建此类新应用时应用,如下所示: 这两
我需要 issgin CTRL+F12 和 CTRL+G 此代码不起作用 但是这段代码有效 为什么不工作? 如何分配 CTRL+F12 和 CTRL+G? 最佳答案 使用代码设置绑
我有安装了 SP1 的 VS2010。我仍然没有在“新建项目”对话框中获得 VSIX 项目模板。 我也提到了以下问题,但没有运气 Can't find VSIX Project Type in VS
我正在尝试创建一个 Visual Studio 2017 扩展,只是为了好玩并了解 VS 扩展性的工作原理。 我的扩展必须可以从“解决方案资源管理器”选项卡中用作上下文菜单按钮,但我想将它包含在非根菜
我刚刚在我的计算机上安装了 VS 2013 SDK,它在 VisualStudio 2013 ultimate 旁边运行 Windows 7。 所以我在“添加项目”对话框中列出了所有可扩展性项目模板。
我已经创建了一个 ItemTemplate 项目。我想将其安装到自定义文件夹中。当我手动将从项目构建的 zip 文件添加到 ItemTemplates 中我命名的文件夹时,这工作正常。 我现在使用两个
我在 visual studio 2019 中下载了扩展,但在安装时出现错误。 安装日志是这样的: 4/25/2021 8:41:33 PM - Microsoft VSIX Installer
我最近下载了Visual Studio 2012的主题,文件以.vsix结尾。我在Internet上进行了检查,但是找不到程序名称Vsix Installer。有人可以告诉我如何安装.vsix文件吗?
我尝试在 Visual Studio 2017 社区离线安装 objc-syntax-highlighting.vsix。我无法解决它。我从 https://github.com/Microsoft/
是否可以在 VSIX 容器中包含一些预定义的文件,然后通过扩展访问它们? 最佳答案 在 .vsixmanifest 设计器中选择 Assets - New - Select type and file
我正在编写一个 VSIX 项目,我希望代码能够确定更新是否可用。 我知道 Visual Studio 能够检查更新,但是,我希望扩展能够更详细地提示用户(开发人员)。 我想知道如何让扩展从包 list
我已经为 Visual Studio 开发了一个 VSPackage。我遵循了这些演练中的所有说明: Part 1 - Creating a Basic Project System Part 2 -
由于 R# 不支持 Roslyn 早期预览版 C# 6.0 功能,因此代码看起来非常乏味... 我想使用分类器 VSIX 为代码着色。是否可以从 Roslyn 语言服务获取当前文档的语义模型? 最佳答
安装 Visual Studio 2017 后,我可以在这个 Vs 包上工作一个月左右,直到第一次更新。现在,在我重建此 Visual Studio 包并尝试安装 VSIX 后,我收到一条消息,指出它
我是一名优秀的程序员,十分优秀!