diff --git a/packages/server/src/VDF/Popfile/PopfileTextDocument.ts b/packages/server/src/VDF/Popfile/PopfileTextDocument.ts index e6672781..d07e18bb 100644 --- a/packages/server/src/VDF/Popfile/PopfileTextDocument.ts +++ b/packages/server/src/VDF/Popfile/PopfileTextDocument.ts @@ -25,9 +25,14 @@ export class PopfileTextDocument extends VDFTextDocument { + if (documentSymbol.children != undefined && path.length == 2 && path.at(-1)!.key.toLowerCase() == "Templates".toLowerCase()) { + return { + key: documentSymbol.key, + keyRange: documentSymbol.nameRange, + } + } + } }, reference: { keys: new Set(["Template".toLowerCase()]), @@ -37,9 +42,18 @@ export class PopfileTextDocument extends VDFTextDocument { + if (documentSymbol.children != undefined && path.length == 2 && documentSymbol.key.toLowerCase() == "WaveSpawn".toLowerCase() && path.at(-1)!.key.toLowerCase() == "Wave".toLowerCase()) { + const name = documentSymbol.children.find((documentSymbol) => documentSymbol.key.toLowerCase() == "Name".toLowerCase()) + if (name && name.detail != undefined) { + return { + key: name.detail, + keyRange: documentSymbol.nameRange, + nameRange: name.detailRange, + } + } + } + } }, reference: { keys: new Set([ diff --git a/packages/server/src/VDF/VDFTextDocument.ts b/packages/server/src/VDF/VDFTextDocument.ts index 5c24a596..ade91b75 100644 --- a/packages/server/src/VDF/VDFTextDocument.ts +++ b/packages/server/src/VDF/VDFTextDocument.ts @@ -69,21 +69,7 @@ export interface VDFTextDocumentSchema { values: Record }> definitionReferences: { type: symbol - definition: { - directParentKeys: string[] - children: boolean - key: { - /** - * @example "fieldName" - * @example "name" - */ - name: string, - /** - * Whether to override documentSymbol.key - */ - priority: boolean - } | null - } | null + definition: DefinitionMatcher | null reference?: { keys: Set match: ((string: string) => boolean) | null @@ -125,6 +111,16 @@ export interface VDFTextDocumentSchema { } } +export interface DefinitionMatcher { + match(documentSymbol: VDFDocumentSymbol, path: VDFDocumentSymbol[]): DefinitionResult | void +} + +export interface DefinitionResult { + key: string + keyRange: VDFRange + nameRange?: VDFRange +} + export abstract class VDFTextDocument, TDependencies> extends TextDocumentBase { public readonly configuration: VDFTextDocumentConfiguration @@ -310,43 +306,18 @@ export abstract class VDFTextDocument i.key.toLowerCase() == definition.key!.name && i.detail != undefined) - if (keyDocumentSymbol) { - key = documentSymbol.key - keyRange = documentSymbol.nameRange - nameRange = keyDocumentSymbol.detailRange! - } - else if (!definition.key.priority) { - // If key does not need priority, fall back to documentSymbol.key, used for VGUI elements that don't have a fieldName - key = documentSymbol.key - keyRange = documentSymbol.nameRange - nameRange = undefined - } - else { - key = undefined - keyRange = undefined - nameRange = undefined - } - } - else { - key = documentSymbol.key - keyRange = documentSymbol.nameRange - nameRange = undefined - } - - if (key && keyRange && ArrayEndsWithArray(path, definition.directParentKeys, (a, b,) => a.key.toLowerCase() == b.toLowerCase()) && ((definition.children ? documentSymbol.children : documentSymbol.detail) != undefined)) { - definitionReferences.definitions.add(type, key, { + const result = definition.match(documentSymbol, path) + if (result) { + definitionReferences.definitions.add(type, result.key, { uri: this.uri, - key: key, + key: result.key, range: documentSymbol.range, - keyRange: keyRange, - nameRange: nameRange, + keyRange: result.keyRange, + nameRange: result.nameRange, detail: documentSymbol.detail }) + + return } } diff --git a/packages/server/src/VDF/VGUI/schemas/ClientSchemeSchema.ts b/packages/server/src/VDF/VGUI/schemas/ClientSchemeSchema.ts index 519659cb..d043a5c6 100644 --- a/packages/server/src/VDF/VGUI/schemas/ClientSchemeSchema.ts +++ b/packages/server/src/VDF/VGUI/schemas/ClientSchemeSchema.ts @@ -1,5 +1,19 @@ +import type { VDFDocumentSymbol } from "vdf-documentsymbols" import { CompletionItemKind } from "vscode-languageserver" -import type { VDFTextDocumentSchema } from "../../VDFTextDocument" +import type { DefinitionMatcher, DefinitionResult, VDFTextDocumentSchema } from "../../VDFTextDocument" + +class SchemeDefinitionMatcher implements DefinitionMatcher { + + constructor(private readonly type: string, private readonly children: boolean) { } + match(documentSymbol: VDFDocumentSymbol, path: VDFDocumentSymbol[]): DefinitionResult | undefined { + if (path.length == 2 && (documentSymbol.children != undefined) == this.children && path[0].key.toLowerCase() == "Scheme".toLowerCase() && path[1].key.toLowerCase() == this.type.toLowerCase()) { + return { + key: documentSymbol.key, + keyRange: documentSymbol.nameRange, + } + } + } +} export const ClientSchemeSchema: VDFTextDocumentSchema = { keys: {}, @@ -22,14 +36,7 @@ export const ClientSchemeSchema: VDFTextDocumentSchema = { definitionReferences: [ { type: Symbol.for("color"), - definition: { - directParentKeys: [ - "Scheme".toLowerCase(), - "Colors".toLowerCase(), - ], - children: false, - key: null, - }, + definition: new SchemeDefinitionMatcher("Colors", false), reference: { keys: new Set("color"), match: null @@ -50,14 +57,7 @@ export const ClientSchemeSchema: VDFTextDocumentSchema = { }, { type: Symbol.for("color"), - definition: { - directParentKeys: [ - "Scheme".toLowerCase(), - "BaseSettings".toLowerCase(), - ], - children: false, - key: null, - }, + definition: new SchemeDefinitionMatcher("BaseSettings", false), reference: { keys: new Set("color"), match: null @@ -78,14 +78,7 @@ export const ClientSchemeSchema: VDFTextDocumentSchema = { }, { type: Symbol.for("border"), - definition: { - directParentKeys: [ - "Scheme".toLowerCase(), - "Borders".toLowerCase(), - ], - children: true, - key: null, - }, + definition: new SchemeDefinitionMatcher("Borders", true), reference: { keys: new Set(), match: null @@ -94,14 +87,7 @@ export const ClientSchemeSchema: VDFTextDocumentSchema = { }, { type: Symbol.for("font"), - definition: { - directParentKeys: [ - "Scheme".toLowerCase(), - "Fonts".toLowerCase(), - ], - children: true, - key: null, - }, + definition: new SchemeDefinitionMatcher("Fonts", true), reference: { keys: new Set(), match: null diff --git a/packages/server/src/VDF/VGUI/schemas/LanguageTokensSchema.ts b/packages/server/src/VDF/VGUI/schemas/LanguageTokensSchema.ts index 275235ea..037ff2d3 100644 --- a/packages/server/src/VDF/VGUI/schemas/LanguageTokensSchema.ts +++ b/packages/server/src/VDF/VGUI/schemas/LanguageTokensSchema.ts @@ -8,12 +8,14 @@ export const LanguageTokensSchema: VDFTextDocumentSchema = { { type: Symbol.for("string"), definition: { - directParentKeys: [ - "lang", - "Tokens".toLowerCase() - ], - children: false, - key: null, + match: (documentSymbol, path) => { + if (path.length == 2 && documentSymbol.detail != undefined && path[0].key.toLowerCase() == "lang".toLowerCase() && path[1].key.toLowerCase() == "Tokens".toLowerCase()) { + return { + key: documentSymbol.key, + keyRange: documentSymbol.nameRange, + } + } + } }, toReference: (value) => `#${value}`, toCompletionItem: (definition) => ({ kind: CompletionItemKind.Text, insertText: `#${definition.key}` }) diff --git a/packages/server/src/VDF/VGUI/schemas/VGUISchema.ts b/packages/server/src/VDF/VGUI/schemas/VGUISchema.ts index 47a7708b..23b76bc4 100644 --- a/packages/server/src/VDF/VGUI/schemas/VGUISchema.ts +++ b/packages/server/src/VDF/VGUI/schemas/VGUISchema.ts @@ -11,9 +11,15 @@ export const VGUISchema: VDFTextDocumentSchema = { { type: Symbol.for("element"), definition: { - directParentKeys: [], - children: true, - key: { name: "fieldName".toLowerCase(), priority: false } + match: (documentSymbol, path) => { + if (documentSymbol.children != undefined && path.length != 0) { + return { + key: documentSymbol.key, + keyRange: documentSymbol.nameRange, + nameRange: documentSymbol.children?.find((i) => i.key.toLowerCase() == "fieldName".toLowerCase() && i.detail != undefined)?.detailRange + } + } + } }, reference: { keys: new Set([