Stride Shader 语法高亮 VSIX 完全指南:TextMate 语法生成与 Visual Studio 即时着色实现
游戏开发图形学VR【免费下载链接】strideStride (formerly Xenko), a free and open-source cross-platform C# game engine.项目地址https://gitcode.com/gh_mirrors/st/stride点击查看免费下载Stride原 Xenko作为一款跨平台 C# 游戏引擎其着色器文件以.sdslStride Shader Language与.sdfx效果定义两种扩展名存在于整个引擎与项目管线中。本指南以仓库内sources/tools/Stride.VisualStudio.Package.Shaders项目为对象系统讲解 Stride 如何通过一个仅包含内容content-only的经典 in-process VSIX为 Visual Studio 提供.sdsl/.sdfx的即时instant语法高亮并深入剖析其 TextMate 语法是如何从 Stride 自身的着色器词汇表自动生成、从而永不与语言定义脱节的。读完本文你将掌握为什么语法高亮不能交给 out-of-process 扩展或 LSP 完成、该 VSIX 内部每个文件各司其职的机制、以及如何一行命令重新生成并提交语法文件。项目定位一个只做一件事的迷你 VSIXStride 仓库中共有两个与 Visual Studio 相关的扩展项目主扩展sources/tools/Stride.VisualStudio.Package与本文的主角sources/tools/Stride.VisualStudio.Package.Shaders。两者的分工在 README 中说得非常直白A small, content-onlyclassicVSIX that gives Visual Studioinstantsyntax highlighting for Stride shader files (.sdsl/.sdfx).这是一个经典classicVSIX目标框架为net472见 Stride.VisualStudio.Package.Shaders.csproj且不携带任何业务代码——它只打包四类资产完成向 VS 注册 TextMate 语法这唯一一个任务文件作用Grammars/sdsl.tmLanguage.jsonTextMate 语法本体由生成器产出见下文sdsl-language-configuration.json注释、括号匹配与自动闭合行为stride-shaders.pkgdef将语法与语言配置注册进 VS 的 TextMate 引擎source.extension.vsixmanifest声明 pkgdef 为VsPackage资产这是让 VS 真正处理它的关键为什么需要一个独立的经典 VSIXout-of-process 扩展的硬限制主扩展Stride.VisualStudio.Package采用的是VisualStudio.Extensibility 的 out-of-process进程外模型。该模型有一个无法绕过的能力缺口它无法注册 TextMate 语法。原因在于 Visual Studio 的架构约束——TextMate 语法注册必须通过经典 in-process VSIX 清单中携带的Microsoft.VisualStudio.VsPackagepkgdef 资产来完成而 out-of-process 扩展的清单无法承载这种 pkgdef 资产。因此这个 companion 项目net472 VSSDK只补这一个洞用最小的经典扩展去注册语法让主扩展继续享受进程外模型的现代化收益。这一点在 csproj 注释中亦有印证Classic (in-process) content-only VSIX. Its sole job is to register the SDSL TextMate grammar via a .pkgdef asset, which the out-of-process Stride.VisualStudio.Package cant do. No commands, no language service — just the grammar language configuration, for instant .sdsl/.sdfx colorization.为什么不直接依赖 LSP仓库规划中的 LSPLanguage Server Protocol方案只能通过异步语义令牌async semantic tokens着色这在输入过程中存在延迟而 TextMate 语法提供的是同步基线synchronous baseline打开文件即可瞬时着色LSP 可以在此基础上做进一步细化。这就是本 VSIX 存在的根本价值——即时/离线着色而不是等待 LSP 异步返回。VSIX 内部机制逐层拆解1. pkgdef向 VS TextMate 引擎注册stride-shaders.pkgdef是整个注册的入口内容极简但语义清晰[$RootKey$\TextMate\Repositories] stride$PackageFolder$\Grammars [$RootKey$\TextMate\LanguageConfiguration\GrammarMapping] source.sdsl$PackageFolder$\sdsl-language-configuration.json第一段将$PackageFolder$\Grammars目录注册为 TextMate 仓库。.sdsl/.sdfx与语法的关联不依赖逐扩展名注册而是由语法文件自身的fileTypes字段完成。第二段以语法的scopeNamesource.sdsl为键把语言配置文件挂到该语法下从而获得注释/括号/自动闭合行为。2. 清单让 VS 真正处理 pkgdef 的两块拼图source.extension.vsixmanifest定义了扩展身份IdStride.VisualStudio.Package.ShadersVersion4.4.0DisplayName Stride Shader Language并声明了两个资产Asset TypeMicrosoft.VisualStudio.VsPackage Pathstride-shaders.pkgdef / Asset TypeMicrosoft.VisualStudio.MefComponent d:SourceProject d:ProjectName%CurrentProject% Path|%CurrentProject%| /VsPackage资产声明 pkgdef使 VS 在处理扩展时执行其中的注册项。这也是 out-of-process 清单无法携带、必须由经典 VSIX 承担的部分。MefComponent资产标记扩展包含编辑器组件从而让 VS激活该扩展并扫描 pkgdef 注册的 TextMate 仓库。注意其程序集本身没有任何 MEF 导出——该资产的存在本身即是意义csproj 注释与清单注释均明确说明The assembly has no MEF exports — the assets presence is what matters。安装目标为 VS Community/[17.0, 19.0)前置要求 VS Core Editor 组件与 .NET Framework 4.7.2。3. 语言配置注释、括号与自动闭合sdsl-language-configuration.json定义了编辑器行为{ comments: { lineComment: //, blockComment: [/*, */] }, brackets: [ [{, }], [[, ]], [(, )] ], autoClosingPairs: [ { open: {, close: } }, { open: [, close: ] }, { open: (, close: ) }, { open: \, close: \, notIn: [string] }, { open: /*, close: */, notIn: [string] } ], surroundingPairs: [ [{, }], [[, ]], [(, )], [\, \] ] }要点解读注释行注释//、块注释/* */与语法文件中的注释规则一一对应自动闭合{[(与/*均自动补全且与/*通过notIn: [string]避免了在字符串/注释内部重复触发surroundingPairs为选中文本包裹{}、[]、()、提供支持。4. 语法本体手写结构 生成词汇的组合拳Grammars/sdsl.tmLanguage.json采用手写结构规则 程序生成词汇匹配的混合策略顶层定义name为 Stride Shader LanguagescopeName为source.sdslfileTypes声明sdsl与sdfx主匹配顺序#comments→#strings→#numbers→#types→#keywords结构性规则手写模板行注释comment.line.double-slash.sdsl匹配//.*$块注释comment.block.sdsl匹配/*…*/字符串string.quoted.double.sdsl内部转义符\\\.归为constant.character.escape.sdsl数字constant.numeric.sdsl匹配十六进制、十进制与科学计数法并支持fFhHlLuU后缀如0x1F,1.5e-3f词汇规则程序生成#types以\b(...)\b边界匹配全部类型名scope 为storage.type.sdsl#keywords同样以词边界匹配保留字scope 为keyword.other.sdsl。从生成的语法可见类型覆盖面bool/float/half/int/uint/double/byte/sbyte/short/ushort/long/min10float/min16float/min12int/min16int/min16uint及其1..4标量、1x1..4x4矩阵全排列如float4、float4x4、min16float2x3关键词覆盖完整的 HLSL 风格保留字包括cbuffer/tbuffer、technique/technique10/technique11、各类 Buffer/Texture/Stream 类型RWStructuredBuffer、RWTexture2DArray、TriangleStream等、插值修饰符linear/nointerpolation/noperspective/centroid、存储类groupshared/uniform/static与流程控制if/for/foreach/while/switch/discard等。5. 配套主题scope → VS 分类的映射VS 以文件名基sdsl.tmLanguage.*将主题与语法配对Grammars/sdsl.tmLanguage.tmTheme用vsclassificationtype把语法 scopes 映射到 VS 分类scope按前缀匹配VS classificationkeyword,storage.typekeywordstring,constant.character.escapestringconstant.numericnumbercommentcomment该主题与语法同目录存放、由同一生成器产出保证映射不会与语法中的 scope 名称脱节。语法的单源真相从 Reserved.cs 自动生成词汇的真正来源语法中庞大的类型/关键词列表并非手写而是从 Stride 自身的着色器解析器反射而来。词汇源头在 Reserved.csStride.Shaders.Parsing.SDSL.Reserved属Stride.Shaders.Parsers项目TypeNames在静态构造函数中通过循环展开生成以 15 个基础标量类型为基底for i in 1..4生成${t}${i}标量再for j in 1..4生成${t}${i}x${j}矩阵——因此float2、float4x4、min16int3x3这类名字全都在运行时构造出来Keywords先包含全部TypeNames再叠加 100 余个 HLSL 风格保留字。生成器的工作机制generate-sdsl-grammar.cs是一个.NET 10 file-based 单文件程序无需项目文件即可dotnet run。它读取已构建的程序集而非解析源码来获取词汇通过Assembly.LoadFrom加载解析器 DLL反射读取Reserved类型上标记为internal的两个静态字段TypeNames、Keywords类型集合 TypeNames全量 其派生裸标量正则^(.*?)\d(x\d)?$剥离数字后缀后若裸名本身也是关键词则并入如float与float4并存以保持一致着色其余保留字全部归入keywordOnly用排序后的集合拼出\b(a|b|c)\b词边界匹配串写入Grammars/sdsl.tmLanguage.json同时生成配套Grammars/sdsl.tmLanguage.tmTheme。生成器在运行时打印词汇统计N types, M keywords并在找不到 DLL 时给出明确报错。从生成结果看当前语法共 400 类型含矩阵全排列与 180 关键词。语法文件的information_for_contributors字段也反复提醒类型/关键词匹配勿手改重跑生成器更新。如何重新生成并提交语法前置条件需要一个已构建的Stride.Shaders.Parsers.dll——任何一次较新的引擎构建都会产出它。默认搜索路径为sources/shaders/Stride.Shaders.Parsers/bin下最新的net10.0构建自动排除 Android、ref、refint目录。标准命令在仓库根目录执行dotnet run sources/tools/Stride.VisualStudio.Package.Shaders/generate-sdsl-grammar.cs指定解析器路径若自动定位失败可显式传入 DLL 路径dotnet run .../generate-sdsl-grammar.cs -- path-to-Stride.Shaders.Parsers.dll提交产物生成器会覆盖写入两个文件Grammars/sdsl.tmLanguage.json与Grammars/sdsl.tmLanguage.tmTheme。任何着色器词汇类型/关键词变更后都应重跑生成并提交重新生成的语法文件确保高亮与语言定义零漂移。注意generate-sdsl-grammar.cs本身在 csproj 中被排除出编译Compile Remove仅作为独立工具运行不进入 VSIX 产物。构建与调试一个可 F5 部署的 VSIX 项目Stride.VisualStudio.Package.Shaders.csproj的配置值得关注产物命名TargetVsixContainerName为StrideShaders.vsix输出到bin\StrideShaders.vsix并通过GetVsixOutputPath目标把路径返回给交付用的 nuspec以便与 out-of-process 的主Stride.vsix相邻打包SDK 风格 VSIX 搭建VSSDKBuildToolsAutoSetup启用CreateVsixContainer与现代部署路径ProjectCapability CreateVsixContainer让 VS 识别这是可部署的 VSIX 项目勾选 Deploy / F5 到实验实例GeneratePkgDefFilefalse不从程序集特性生成 pkgdef——本扩展没有 VS 注册特性/Package 类语法注册完全由手写的stride-shaders.pkgdef承担IncludeAssemblyInVSIXContainertrue随包携带否则为空的程序集供清单中的MefComponent资产引用F5 调试VsixDeployOnDebug使 F5 直接部署到 VS 实验实例/rootsuffix Exp——由于没有可断点的代码F5 的意义就是部署语法并打开实验实例让你打开一个.sdsl文件验证着色效果。四个内容文件pkgdef、语言配置、语法、主题均声明为Content且IncludeInVSIXtrue、CopyToOutputDirectoryPreserveNewest确保全部进入 VSIX 容器。小结一条不脱轨的高亮管线回顾整条链路Stride 的着色器高亮方案体现了清晰的工程取舍为什么独立——TextMate 语法注册是经典 in-process VSIX 的专属能力out-of-process 主扩展无法承载为什么即时——TextMate 语法提供同步着色基线LSP 的异步语义令牌仅作补充细化为什么不会漂移——语法词汇反射自Stride.Shaders.Parsers的Reserved运行时集合生成器一行命令即可重新产出语法与主题结构规则保持手写、词汇规则保持自动生成两者边界清晰为什么最小化——无代码、无命令、无语言服务只做注册语法这一件事且通过MefComponent资产激活机制让 VS 识别并扫描仓库。对于希望了解 Stride 编辑器工具链、或在自己的引擎/DSL 中复刻从语言词汇表生成 TextMate 语法模式的开发者sources/tools/Stride.VisualStudio.Package.Shaders是一个结构极简、机制完备的参考实现。赞分享游戏开发图形学VR【免费下载链接】strideStride (formerly Xenko), a free and open-source cross-platform C# game engine.项目地址https://gitcode.com/gh_mirrors/st/stride点击查看免费下载相关推荐ProCapNet 昇腾 NPU 精度验证实战CPU vs NPU 对比方法论max_abs_error0.001ProCapNet 昇腾 NPU 精度验证实战CPU vs NPU 对比方法论max_abs_error0.001 procapnet npu 让 Pr人工智能深度学习生物信息学Ascend本地部署基于 test.rst 配色夹具深度解读 reStructuredText 语法高亮从 TextMate 语法到着色回归测试基于 test.rst 配色夹具深度解读 reStructuredText 语法高亮从 TextMate 语法到着色回归测试 本篇技术指南以仓库中 exten代码编辑器开发工具AI Agent人工智能Visual Studio Code语言扩展语法高亮与语言配置Visual Studio Code语言扩展语法高亮与语言配置 引言代码编辑器的语言理解核心 你是否曾在编辑Markdown文件时惊叹于标题自动加粗、代码开发工具代码编辑器上一篇Himalaya 调试与故障排除从新手到专家的终极指南下一篇推荐使用React Native Markdown Display创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →