Create a VS Code extension that enables TypeScript language server features (error checking, type validation, IntelliSense) for TypeScript code embedded in YAML files - similar to how Markdown files handle code blocks.
-
Virtual Document Provider
- Custom URI scheme:
yamlscript-ts:// - Creates virtual TypeScript documents from YAML code blocks
- Manages document lifecycle (create, update, delete)
- Custom URI scheme:
-
Code Block Detection
- YAML AST parsing using the
yamllibrary - Regex-based fallback for malformed YAML
- Heuristic-based TypeScript detection
- Supports multiple code blocks per file
- YAML AST parsing using the
-
Diagnostic Mapping
- Listens to TypeScript language server diagnostics
- Maps errors from virtual documents back to YAML source
- Displays TypeScript errors inline in YAML files
- Custom diagnostic source: "TypeScript (in YAML)"
-
Real-time Updates
- Processes documents on open, change, and close
- Incremental updates as you type
- Automatic cleanup on document close
yamlscript/
├── src/
│ ├── extension.ts # Main extension logic (327 lines)
│ └── test/
│ └── extension.test.ts # Basic tests
├── package.json # Extension manifest
├── tsconfig.json # TypeScript config
├── esbuild.js # Build configuration
├── README.md # User documentation
├── DEVELOPMENT.md # Technical documentation
├── TUTORIAL.md # Usage tutorial
├── example.yaml # Demo file with examples
└── .vscodeignore # Package exclusions
class YamlTypeScriptVirtualDocumentProvider implements vscode.TextDocumentContentProvider {
// Provides content for virtual TypeScript documents
// Emits events when documents change
// Manages document content in memory
}Responsibilities:
- Detects YAML documents
- Extracts TypeScript code blocks
- Creates virtual documents
- Maps diagnostics
- Manages lifecycle
Key Methods:
extractCodeBlocks()- Parse YAML and find TS codelooksLikeTypeScript()- Heuristic detectionupdateDocument()- Process document changeshandleDiagnosticChanges()- Listen for TS errorsmapDiagnosticsToSource()- Map errors to YAML
The extension detects TypeScript code using:
- YAML Parsing: Walks AST looking for string values with TS syntax
- Key Patterns: Looks for keys like
code,script,handler, etc. - TypeScript Heuristics:
- Keywords:
const,let,function,interface,type,class - Type annotations:
: string,: number, etc. - Arrow functions:
=> - Imports/exports
- Generics:
<T>
- Keywords:
vscode: ^1.105.0 (VS Code API)yaml: ^2.8.1 (YAML parsing)typescript: ^5.9.3 (Dev dependency)
# Install dependencies
pnpm install
# Compile
pnpm run compile
# Watch mode
pnpm run watch
# Test
pnpm run test
# Package
pnpm run package- Open the project in VS Code
- Press
F5to launch Extension Development Host - Open
example.yamlin the new window - See TypeScript errors highlighted!
handler:
code: |
interface User {
id: number;
name: string;
}
// This will show an error
const user: User = {
id: 1
// Missing 'name' property
};┌─────────────────┐
│ YAML File │
└────────┬────────┘
│ onDidChangeTextDocument
▼
┌─────────────────┐
│ Extract Blocks │
│ - YAML Parse │
│ - Regex │
│ - Heuristics │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Virtual Docs │
│ yamlscript-ts://│
└────────┬────────┘
│
▼
┌─────────────────┐
│ TypeScript LS │
│ (built-in) │
└────────┬────────┘
│ Diagnostics
▼
┌─────────────────┐
│ Map to Source │
│ Adjust Lines │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Show in YAML │
│ (red squiggles)│
└─────────────────┘
-
Document Management
workspace.registerTextDocumentContentProvider()workspace.onDidOpenTextDocument()workspace.onDidChangeTextDocument()workspace.onDidCloseTextDocument()workspace.openTextDocument()
-
Diagnostics
languages.createDiagnosticCollection()languages.onDidChangeDiagnostics()languages.getDiagnostics()
-
URI Handling
- Custom scheme:
yamlscript-ts: - Unique URIs per code block:
file.yaml.block0.ts
- Custom scheme:
| Feature | Status | Notes |
|---|---|---|
| Error Detection | ✅ Implemented | Full TypeScript error support |
| Type Checking | ✅ Implemented | Complete type validation |
| Diagnostics Display | ✅ Implemented | Inline errors in YAML |
| Multi-block Support | ✅ Implemented | Multiple blocks per file |
| Real-time Updates | ✅ Implemented | Updates as you type |
| IntelliSense | TS server provides some support | |
| Go to Definition | ❌ Future | Not yet implemented |
| Refactoring | ❌ Future | Not yet implemented |
| Import Resolution | ❌ Future | Not yet implemented |
Currently the extension works out-of-the-box with no configuration needed!
The extension activates when:
- A YAML file is opened (
onLanguage:yaml) - A YML file is opened (
onLanguage:yml)
- Line Mapping: May be slightly off for deeply nested YAML
- Import Resolution: Imports in code blocks aren't resolved relative to YAML file
- Context: Code blocks are analyzed independently (no shared context)
- Performance: Very large YAML files may cause slowdown
- IntelliSense: Limited compared to standalone
.tsfiles
- Better line/column mapping for nested structures
- Configuration options for detection patterns
- Support for JavaScript (not just TypeScript)
- Performance optimizations
- Full IntelliSense support (completions, hover)
- Go to Definition across code blocks
- Import path resolution
- JSDoc documentation support
- Refactoring operations (rename, extract, etc.)
- Cross-file analysis
- Workspace-aware type checking
- Integration with tsconfig.json
- Support for other languages (Python, Rust, etc.)
- Open
example.yaml - Verify errors appear on:
- Type mismatches
- Missing properties
- Invalid values
Basic tests in src/test/extension.test.ts:
- Extension presence check
- YAML file activation
- Basic code detection
- README.md: User-facing documentation
- TUTORIAL.md: Step-by-step guide with examples
- DEVELOPMENT.md: Technical implementation details
- This file: Complete implementation summary
- Virtual Documents: Powerful pattern for extending language servers to embedded code
- Diagnostic Mapping: Careful line/column mapping is crucial
- Heuristics: TypeScript detection requires good heuristics
- Lifecycle Management: Proper cleanup prevents memory leaks
- YAML Complexity: YAML has many edge cases (multiline strings, indentation, etc.)
This extension is inspired by:
- VS Code's Markdown code block support
- Vue/Svelte language servers (virtual documents)
- Template string language services
For issues, questions, or contributions:
- Check the documentation
- Review
example.yamlfor examples - See
DEVELOPMENT.mdfor technical details - Open an issue on GitHub
Start Development: F5
Compile: pnpm run compile
Watch Mode: pnpm run watch
Package: pnpm run package
Test File: example.yaml
Main Code: src/extension.ts (327 lines)
Total Project: ~1000+ lines including docs
Status: ✅ Fully Functional - Ready for Testing and Feedback!
The extension successfully brings TypeScript language server capabilities to YAML files, making it easier to work with configuration files that contain embedded code.