Kahua XML Links ExtensionA powerful Visual Studio Code extension that provides intelligent navigation, completion, and cross-file symbol resolution for Kahua XML files. Navigate seamlessly between definitions and references across multiple files with support for imports, file references, and recursive symbol loading. Features🎯 Core Navigation
🌐 Cross-File Symbol Resolution
🔧 Advanced Pattern Matching
InstallationFrom VSIX (Recommended)
From Source
Quick Start
ConfigurationThe extension is configured via two main settings in your VS Code 1. Symbol Links (
|
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Unique identifier for this link type |
def |
[string, string, string?] | ⬜ | Definition pattern: [element, attribute, condition?] |
ref |
[[string, string, matchType?]] | ⬜ | Array of reference patterns: [[element, attribute, matchType?]] |
sym |
[string, string] | ⬜ | Symmetric pattern: [element, attribute] (both def and ref) |
Note: Each link must have at least one of: def, ref, or sym.
Advanced Configuration Options
Attribute Matching (refAttrMatch)
Control how reference attribute names are matched:
{
"id": "label",
"def": ["Label", "Key"],
"ref": [["*", "Label"]],
"refAttrMatch": "contains"
}
Match Types:
"exact"(default) – Attribute name must match exactly"contains"– Attribute name must contain the pattern (e.g.,HeaderLabelmatchesLabel)"startsWith"– Attribute name must start with the pattern"endsWith"– Attribute name must end with the pattern
Value Extraction (valueExtract)
Extract values from special formats:
{
"id": "label",
"def": ["Label", "Key"],
"ref": [["*", "Label"]],
"refAttrMatch": "contains",
"valueExtract": "brackets"
}
Extraction Types:
"brackets"– Extract content from[value](e.g.,Label="[MyKey]"→MyKey)
Cross-File Imports (imports)
Load definitions from files listed in an import declaration:
{
"id": "label",
"def": ["Label", "Key"],
"ref": [["*", "Label"]],
"refAttrMatch": "contains",
"valueExtract": "brackets",
"imports": {
"element": "Cultures",
"attribute": "ImportCultures",
"fileRefId": "kahuaFile",
"separator": ","
}
}
How it works: When the extension finds:
<Cultures ImportCultures="kahua_Core,kahua_WorkflowLabels">
It automatically loads all Label definitions from kahua_Core.xml and kahua_WorkflowLabels.xml.
Import Fields:
| Field | Type | Required | Description |
|---|---|---|---|
element |
string | ✅ | Element containing the import declaration |
attribute |
string | ✅ | Attribute containing comma-separated file names |
fileRefId |
string | ✅ | ID of file reference config to use for resolving files |
separator |
string | ⬜ | Separator character (default: ",") |
Cross-File References (crossFileRef)
Load definitions from files referenced by specific attributes:
{
"id": "function",
"sym": ["Function", "Name"],
"crossFileRef": {
"patterns": [
["PartsReference", "Properties.AppName"],
["App", "Extends"]
],
"fileRefId": "kahuaFile"
}
}
How it works: When the extension finds:
<PartsReference Properties.AppName="kahua_Contract" />
or
<App Extends="kahua_Base" />
It automatically loads all Function definitions from those referenced files.
CrossFileRef Fields:
| Field | Type | Required | Description |
|---|---|---|---|
patterns |
[[string, string]] | ✅ | Array of [element, attribute] patterns that reference files |
fileRefId |
string | ✅ | ID of file reference config to use for resolving files |
Conditional Definitions (hasDescendant)
Require elements to have specific descendants:
{
"id": "functionDef",
"def": ["Function", "Name", "hasDescendant=Function.Directives"],
"ref": [["Function", "Name"]]
}
How it works:
Only treats <Function Name="..."> as a definition if it contains a <Function.Directives> child element.
2. File References (kahuaXml.fileReferences)
Defines patterns for navigating to other files and configures search paths.
{
"kahuaXml.fileReferences": [
{
"id": "kahuaFile",
"pattern": ["App", "Extends"],
"searchPaths": [
"${workspaceFolder}/xml",
"G:/OneDrive/Documents/vscode projects/xml_files",
"C:/Kahua/Config"
],
"fileExtension": ".xml"
}
]
}
Fields:
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Unique identifier referenced by imports/crossFileRef |
pattern |
[string, string] | ✅ | Pattern identifying file references: [element, attribute] |
searchPaths |
string[] | ✅ | Ordered list of directories to search for files |
fileExtension |
string | ⬜ | File extension to append (default: ".xml") |
Path Variables:
${workspaceFolder}– Root directory of your workspace
Search Behavior: Files are searched in the order listed. The first match wins.
Complete Configuration Example
Here's a full example with all features enabled:
{
"kahuaXml.fileReferences": [
{
"id": "kahuaFile",
"pattern": ["App", "Extends"],
"searchPaths": [
"${workspaceFolder}/xml",
"G:/OneDrive/Documents/vscode projects/kahua_xml"
],
"fileExtension": ".xml"
}
],
"kahuaXml.links": [
{
"id": "directiveSet",
"def": ["DirectiveSet", "Name"],
"ref": [["Directives", "Set"]],
"crossFileRef": {
"patterns": [
["PartsReference", "Properties.AppName"],
["App", "Extends"]
],
"fileRefId": "kahuaFile"
}
},
{
"id": "function",
"sym": ["Function", "Name"],
"crossFileRef": {
"patterns": [
["PartsReference", "Properties.AppName"],
["App", "Extends"]
],
"fileRefId": "kahuaFile"
}
},
{
"id": "onEvent",
"def": ["OnEvent", "Name"],
"ref": [["OnEvent", "Event"]],
"crossFileRef": {
"patterns": [
["PartsReference", "Properties.AppName"],
["App", "Extends"]
],
"fileRefId": "kahuaFile"
}
},
{
"id": "label",
"def": ["Label", "Key"],
"ref": [["*", "Label"], ["*", "Description"]],
"refAttrMatch": "contains",
"valueExtract": "brackets",
"imports": {
"element": "Cultures",
"attribute": "ImportCultures",
"fileRefId": "kahuaFile",
"separator": ","
},
"crossFileRef": {
"patterns": [
["PartsReference", "Properties.AppName"],
["App", "Extends"]
],
"fileRefId": "kahuaFile"
}
}
]
}
Usage Examples
Example 1: Navigate to DirectiveSet
File: workflow.xml
<DirectiveSet Name="ValidateLinearLocation">
<!-- definition -->
</DirectiveSet>
<Step.Commands>
<Directives Set="ValidateLinearLocation" />
<!-- Press F12 on "ValidateLinearLocation" to jump to the definition -->
</Step.Commands>
Example 2: Cross-File Function Reference
File: app_extension.xml
<App Extends="kahua_Base">
<Function Name="MyFunction" />
<!-- References kahua_Base.xml -->
</App>
File: kahua_Base.xml
<Function Name="BaseFunction" />
<!-- This function is now available in app_extension.xml -->
When you type <Function Name=" in app_extension.xml, autocomplete will suggest both MyFunction and BaseFunction.
Example 3: Label Imports
File: my_app.xml
<Cultures ImportCultures="kahua_Core,kahua_WorkflowLabels">
<Culture Code="en">
<Labels>
<Label Key="MyCustomLabel">My Label</Label>
</Labels>
</Culture>
</Cultures>
<Field Label="[MyCustomLabel]" />
<!-- Also can reference labels from kahua_Core and kahua_WorkflowLabels -->
Press F12 on MyCustomLabel to jump to the definition, even if it's in an imported file.
Example 4: Cross-File Parts Reference
File: contract.xml
<PartsReference Properties.AppName="kahua_FundSource_Parts" />
<!-- All symbols from kahua_FundSource_Parts.xml are now available -->
How It Works
Symbol Resolution Flow
- Document Opens → Extension parses the XML
- Local Symbols → Extracts definitions and references from current file
- Import Processing → If
importsconfigured, loads symbols from imported files - Cross-File References → If
crossFileRefconfigured, loads symbols from referenced files - Recursive Loading → Recursively processes imports/references in loaded files
- Cycle Detection → Prevents infinite loops from circular references
- Index Building → Merges all symbols and builds position information
- Navigation Ready → F12, Shift+F12, and autocomplete now work across all files
File Resolution
When resolving a file name like "kahua_Core":
- Append file extension:
"kahua_Core.xml" - Search through
searchPathsin order - Return first match found
- Cache result for performance
Development
Building
npm install
npm run compile
Testing
npm test
All tests use the Mocha framework with TypeScript support.
Packaging
Create a distributable VSIX file:
npm run package
Or using vsce directly:
vsce package
Troubleshooting
Symbols not found across files
Check:
searchPathsare correctly configured inkahuaXml.fileReferences- File names match exactly (case-sensitive on some systems)
- Check the Output panel (View → Output → Kahua XML Links) for error messages
Autocomplete not showing cross-file symbols
Verify:
- The file reference pattern is correctly configured
importsorcrossFileRefis properly set on the link configuration- Referenced files exist in the configured search paths
Extension not activating
The extension activates automatically for XML files. If it's not working:
- Ensure the file has
.xmlextension - Check VS Code's language mode (bottom right) shows "XML"
- Reload window (Ctrl+Shift+P → "Reload Window")
Performance Considerations
- File Caching – Resolved file paths are cached to avoid repeated filesystem lookups
- Lazy Loading – Cross-file symbols are only loaded when needed
- Cycle Detection – Each file is processed only once per import chain
- Incremental Updates – Only affected files are re-indexed on save
Limitations
- Navigation is currently limited to the active workspace
- Large import chains (50+ files) may take a few seconds to index
- Changes in referenced files require re-opening the referencing file to reflect
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass (
npm test) - Submit a pull request
License
This project is licensed under the MIT License. See LICENSE for details.
Changelog
Version 1.0.1
- ✨ Added cross-file symbol resolution with
importssupport - ✨ Added cross-file reference resolution with
crossFileRef - ✨ Added file reference navigation
- ✨ Added advanced attribute matching modes
- ✨ Added value extraction for bracket notation
- ✨ Added recursive loading with cycle detection
- 🐛 Fixed test infrastructure to work without vscode module
- 📚 Comprehensive documentation and examples
Version 1.0.0
- 🎉 Initial release
- ✨ Basic symbol navigation (definitions, references, symmetric)
- ✨ Conditional definitions with
hasDescendant - ✨ Configurable link patterns