✨ feat(vscode): 代码阅读契约加命令规则(按命令名注册、读一条命令)、按位置的参数 / 输出 / 返回、解释器和选项块、分情况 / 命令 / 管道种类、常量色;模板引擎加节点读法;没有定义、高亮提供者的语言用语言插件认的同一文件里的名字跳转、高亮

This commit is contained in:
cruldra committed 2026-09-28 00:44:46 +08:00
1 parent cf09c24730
commit ff2a44f080
17 files changed
+555 -60

No files matched your search

+12 -2
View File
@@ -1,5 +1,5 @@
import type { Disposable, Event, Memento } from 'vscode'
import type { CodeReaderApi, LanguageAdapter, LibraryRule, Translator } from './contract'
import type { CodeReaderApi, CommandRule, LanguageAdapter, LibraryRule, Translator } from './contract'
/** globalState 里按 languageId 记选中的翻译插件 id:Record<languageId, translatorId>。 */
export const TRANSLATOR_CHOICE_KEY = 'superpowers.codeReader.translatorByLanguage'
@@ -7,13 +7,14 @@ export const TRANSLATOR_CHOICE_KEY = 'superpowers.codeReader.translatorByLanguag
interface Entry<T> { value: T }
/**
* 语言插件、翻译插件、库规则的注册表。内置实现和其他扩展都通过它注册(它本身就是对外的 CodeReaderApi)。
* 语言插件、翻译插件、库规则、命令规则的注册表。内置实现和其他扩展都通过它注册(它本身就是对外的 CodeReaderApi)。
* 不依赖 vscode 运行时:Disposable 和事件都是结构兼容的普通对象,便于单元测试。
*/
export class CodeReaderRegistry implements CodeReaderApi {
private readonly adapters: Entry<LanguageAdapter>[] = []
private readonly translators: Entry<Translator>[] = []
private readonly rules: Entry<LibraryRule>[] = []
private readonly commands: Entry<CommandRule>[] = []
private readonly listeners = new Set<() => void>()
constructor(private readonly state: Pick<Memento, 'get' | 'update'>) {}
@@ -41,6 +42,10 @@ export class CodeReaderRegistry implements CodeReaderApi {
return this.add(this.rules, rule)
}
registerCommandRule(rule: CommandRule): Disposable {
return this.add(this.commands, rule)
}
/** 当前语言插件覆盖的全部 languageId(去重、排序),给 when 子句用。 */
languageIds(): string[] {
return [...new Set(this.adapters.flatMap(entry => entry.value.languageIds))].sort()
@@ -61,6 +66,11 @@ export class CodeReaderRegistry implements CodeReaderApi {
return this.rules.map(entry => entry.value).filter(rule => rule.languageIds.includes(languageId))
}
/** 某 languageId 的命令规则,按注册顺序:几条规则都管同一个命令名时先注册的算。 */
commandRulesFor(languageId: string): CommandRule[] {
return this.commands.map(entry => entry.value).filter(rule => rule.languageIds.includes(languageId))
}
/** 注册着的全部库规则,按注册顺序:查规则标的引用时按 id 找。 */
libraryRules(): LibraryRule[] {
return this.rules.map(entry => entry.value)