|
| 1 | +# Copilot Instructions for Markdown Table Prettifier VS Code Extension |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +This is a **VS Code extension** that formats and prettifies Markdown tables to make them more readable. The extension is also available as an **NPM package**, **CLI tool**, and **Docker image**. |
| 6 | + |
| 7 | +### Key Features |
| 8 | +- Formats Markdown tables with proper alignment and spacing |
| 9 | +- Supports column alignment (left, center, right) using `:` markers |
| 10 | +- Handles table borders intelligently (adds/removes as needed) |
| 11 | +- Supports indented tables and empty columns |
| 12 | +- Provides configurable column padding |
| 13 | +- Available as VS Code extension, CLI tool, NPM package, and Docker image |
| 14 | + |
| 15 | +## Architecture Overview |
| 16 | + |
| 17 | +The codebase follows a **layered architecture** with clear separation of concerns: |
| 18 | + |
| 19 | +### Core Layers |
| 20 | +1. **Models** (`src/models/`) - Core data structures (Table, Row, Cell, Alignment) |
| 21 | +2. **Model Factories** (`src/modelFactory/`) - Create and transform models from raw text |
| 22 | +3. **View Models** (`src/viewModels/`) - Presentation layer models (TableViewModel, RowViewModel) |
| 23 | +4. **View Model Factories** (`src/viewModelFactories/`) - Convert models to view models |
| 24 | +5. **Writers** (`src/writers/`) - Convert view models to formatted strings |
| 25 | +6. **Prettyfiers** (`src/prettyfiers/`) - Main formatting orchestration |
| 26 | + |
| 27 | +### Key Components |
| 28 | +- **MultiTablePrettyfier**: Finds and formats multiple tables in a document |
| 29 | +- **SingleTablePrettyfier**: Formats individual tables |
| 30 | +- **TableFactory**: Parses raw text into Table models |
| 31 | +- **TableValidator**: Validates table structure |
| 32 | +- **TableFinder**: Locates tables within documents |
| 33 | +- **PadCalculators**: Handle column padding and alignment |
| 34 | + |
| 35 | +## File Structure Guidelines |
| 36 | + |
| 37 | +### Source Code Organization |
| 38 | +- `src/extension/` - VS Code extension integration |
| 39 | +- `src/models/` - Core domain models |
| 40 | +- `src/modelFactory/` - Model creation and transformation |
| 41 | +- `src/viewModels/` - Presentation models |
| 42 | +- `src/viewModelFactories/` - View model creation |
| 43 | +- `src/writers/` - String output generation |
| 44 | +- `src/prettyfiers/` - Main formatting logic |
| 45 | +- `src/padCalculation/` - Column padding calculations |
| 46 | +- `src/tableFinding/` - Table detection logic |
| 47 | +- `src/diagnostics/` - Logging and diagnostics |
| 48 | +- `cli/` - Command-line interface |
| 49 | +- `test/` - Unit and system tests |
| 50 | + |
| 51 | +### Test Organization |
| 52 | +- `test/unitTests/` - Unit tests mirroring source structure |
| 53 | +- `test/systemTests/` - End-to-end tests with input/expected files |
| 54 | +- `test/stubs/` - Test doubles and mocks |
| 55 | + |
| 56 | +## Coding Standards |
| 57 | + |
| 58 | +### TypeScript Guidelines |
| 59 | +- Use **strict TypeScript** with proper typing |
| 60 | +- Prefer **composition over inheritance** |
| 61 | +- Use **dependency injection** patterns |
| 62 | +- Follow **SOLID principles** |
| 63 | +- Use **readonly** for immutable data |
| 64 | +- Prefer **private readonly** for dependencies |
| 65 | + |
| 66 | +### Class Design Patterns |
| 67 | +```typescript |
| 68 | +// Example class structure |
| 69 | +export class ExampleClass { |
| 70 | + constructor( |
| 71 | + private readonly _dependency: IDependency, |
| 72 | + private readonly _logger: ILogger |
| 73 | + ) { } |
| 74 | + |
| 75 | + public method(): ReturnType { |
| 76 | + // Implementation |
| 77 | + } |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +### Error Handling |
| 82 | +- Use **descriptive error messages** |
| 83 | +- Validate inputs at public method boundaries |
| 84 | +- Use **null checks** for critical operations |
| 85 | +- Log errors appropriately based on context |
| 86 | + |
| 87 | +### Naming Conventions |
| 88 | +- Use **descriptive names** for classes and methods |
| 89 | +- Private fields prefixed with `_` |
| 90 | +- Interfaces prefixed with `I` when needed |
| 91 | +- Test methods describe behavior: `"methodName() with condition returns expected result"` |
| 92 | + |
| 93 | +## Testing Guidelines |
| 94 | + |
| 95 | +### Unit Tests |
| 96 | +- Use **Mocha** with **TDD style** (`suite`/`test`) |
| 97 | +- Use **TypeMoq** for mocking dependencies |
| 98 | +- Test structure: **Arrange, Act, Assert** |
| 99 | +- One assertion per test when possible |
| 100 | +- Use descriptive test names explaining the scenario |
| 101 | + |
| 102 | +### Test Patterns |
| 103 | +```typescript |
| 104 | +suite("ClassName tests", () => { |
| 105 | + let _mockDependency: IMock<IDependency>; |
| 106 | + |
| 107 | + setup(() => { |
| 108 | + _mockDependency = Mock.ofType<IDependency>(); |
| 109 | + }); |
| 110 | + |
| 111 | + test("methodName() with valid input returns expected result", () => { |
| 112 | + // Arrange |
| 113 | + const sut = createSut(); |
| 114 | + const input = "test input"; |
| 115 | + const expected = "expected output"; |
| 116 | + _mockDependency.setup(m => m.method(input)).returns(() => expected); |
| 117 | + |
| 118 | + // Act |
| 119 | + const result = sut.method(input); |
| 120 | + |
| 121 | + // Assert |
| 122 | + assert.strictEqual(result, expected); |
| 123 | + _mockDependency.verify(m => m.method(input), Times.once()); |
| 124 | + }); |
| 125 | + |
| 126 | + function createSut(): ClassName { |
| 127 | + return new ClassName(_mockDependency.object); |
| 128 | + } |
| 129 | +}); |
| 130 | +``` |
| 131 | + |
| 132 | +### System Tests |
| 133 | +- Test files in `test/systemTests/resources/` |
| 134 | +- Input files: `testname-input.md` |
| 135 | +- Expected files: `testname-expected.md` |
| 136 | +- Tests both CLI and VS Code formatter |
| 137 | + |
| 138 | +## VS Code Extension Patterns |
| 139 | + |
| 140 | +### Extension Structure |
| 141 | +- **Extension activation**: `src/extension/extension.ts` |
| 142 | +- **Command registration**: Document formatters and commands |
| 143 | +- **Configuration**: Use VS Code workspace configuration |
| 144 | +- **Factory pattern**: `prettyfierFactory.ts` creates instances |
| 145 | + |
| 146 | +### Key Extension Files |
| 147 | +- `extension.ts` - Entry point and activation |
| 148 | +- `prettyfierFactory.ts` - Dependency injection container |
| 149 | +- `tableDocumentPrettyfier.ts` - Document formatting provider |
| 150 | +- `tableDocumentRangePrettyfier.ts` - Range formatting provider |
| 151 | +- `tableDocumentPrettyfierCommand.ts` - Manual command execution |
| 152 | + |
| 153 | +## Configuration |
| 154 | + |
| 155 | +### VS Code Settings |
| 156 | +- `markdownTablePrettify.maxTextLength` - Size limit for formatting |
| 157 | +- `markdownTablePrettify.extendedLanguages` - Additional language support |
| 158 | +- `markdownTablePrettify.columnPadding` - Extra column spacing |
| 159 | +- `markdownTablePrettify.showWindowMessages` - UI message control |
| 160 | + |
| 161 | +### CLI Options |
| 162 | +- `--check` - Validate formatting without changes |
| 163 | +- `--columnPadding=N` - Set column padding |
| 164 | + |
| 165 | +## Performance Considerations |
| 166 | + |
| 167 | +### Size Limits |
| 168 | +- Default 1M character limit for VS Code extension |
| 169 | +- No limits for CLI/NPM usage |
| 170 | +- Use `SizeLimitChecker` implementations |
| 171 | + |
| 172 | +### Caching |
| 173 | +- Cache factory instances in VS Code extension |
| 174 | +- Invalidate cache on configuration changes |
| 175 | + |
| 176 | +### Benchmarking |
| 177 | +- Performance tests in `test/systemTests/benchmarkRunner.ts` |
| 178 | +- Measure factory creation and document formatting |
| 179 | +- Results stored in `benchmark-results-*.json` |
| 180 | + |
| 181 | +## Common Patterns |
| 182 | + |
| 183 | +### Dependency Injection |
| 184 | +Classes receive dependencies via constructor injection: |
| 185 | +```typescript |
| 186 | +constructor( |
| 187 | + private readonly _tableFactory: TableFactory, |
| 188 | + private readonly _validator: TableValidator, |
| 189 | + private readonly _logger: ILogger |
| 190 | +) { } |
| 191 | +``` |
| 192 | + |
| 193 | +### Factory Pattern |
| 194 | +Use factories to create complex object graphs: |
| 195 | +```typescript |
| 196 | +export function getDocumentPrettyfier(): vscode.DocumentFormattingEditProvider { |
| 197 | + return new TableDocumentPrettyfier(getMultiTablePrettyfier()); |
| 198 | +} |
| 199 | +``` |
| 200 | + |
| 201 | +### Strategy Pattern |
| 202 | +Use strategies for different behaviors (alignment, padding): |
| 203 | +```typescript |
| 204 | +export class PadCalculatorSelector { |
| 205 | + public getCalculator(alignment: Alignment): BasePadCalculator { |
| 206 | + // Return appropriate calculator based on alignment |
| 207 | + } |
| 208 | +} |
| 209 | +``` |
| 210 | + |
| 211 | +## Build and Distribution |
| 212 | + |
| 213 | +### Build Scripts |
| 214 | +- `npm run compile` - TypeScript compilation |
| 215 | +- `npm run test` - Run all tests |
| 216 | +- `npm run benchmark` - Performance benchmarks |
| 217 | +- `npm run dist` - Create NPM distribution |
| 218 | + |
| 219 | +### Multi-Target Distribution |
| 220 | +- **VS Code Extension**: Published to marketplace |
| 221 | +- **NPM Package**: Core logic for Node.js/web |
| 222 | +- **CLI Tool**: Standalone command-line interface |
| 223 | +- **Docker Image**: Containerized CLI |
| 224 | + |
| 225 | +## Common Operations |
| 226 | + |
| 227 | +### Adding New Features |
| 228 | +1. Create models in `src/models/` if needed |
| 229 | +2. Add business logic in appropriate layer |
| 230 | +3. Update factories for dependency injection |
| 231 | +4. Add unit tests mirroring source structure |
| 232 | +5. Add system tests with input/expected files |
| 233 | +6. Update configuration if needed |
| 234 | + |
| 235 | +### Adding New Tests |
| 236 | +1. Create test file in matching `test/unitTests/` directory |
| 237 | +2. Use TypeMoq for mocking dependencies |
| 238 | +3. Follow naming convention: `className.test.ts` |
| 239 | +4. For system tests, add input/expected file pairs |
| 240 | + |
| 241 | +### Debugging |
| 242 | +- Use VS Code debugger with TypeScript source maps |
| 243 | +- Check logs via `ILogger` implementations |
| 244 | +- Use system tests for end-to-end verification |
| 245 | + |
| 246 | +## Integration Points |
| 247 | + |
| 248 | +### VS Code APIs |
| 249 | +- `vscode.languages.registerDocumentFormattingEditProvider` |
| 250 | +- `vscode.languages.registerDocumentRangeFormattingEditProvider` |
| 251 | +- `vscode.commands.registerTextEditorCommand` |
| 252 | +- `vscode.workspace.getConfiguration` |
| 253 | + |
| 254 | +### NPM Package |
| 255 | +- Entry point: `cli/cliPrettify.js` |
| 256 | +- Exports `CliPrettify` class with static methods |
| 257 | +- Supports both CommonJS and ES modules |
| 258 | + |
| 259 | +### CLI Interface |
| 260 | +- Entry point: `cli/index.ts` |
| 261 | +- Argument parsing: `cli/argumentsParser.ts` |
| 262 | +- Stdin/stdout handling: `cli/inputReader.ts` |
0 commit comments