Skip to content

feat: JSON ↔ TOON bidirectional converter with syntax highlighting and validation#6

Open
akumarpalo wants to merge 16 commits into
toon-format:mainfrom
akumarpalo:feat/json-toon-converter
Open

feat: JSON ↔ TOON bidirectional converter with syntax highlighting and validation#6
akumarpalo wants to merge 16 commits into
toon-format:mainfrom
akumarpalo:feat/json-toon-converter

Conversation

@akumarpalo

@akumarpalo akumarpalo commented Jun 4, 2026

Copy link
Copy Markdown

Summary

Complete VS Code extension for bidirectional JSON/TOON conversion, built on top of the official @toon-format/toon library. This adds all core features to make the extension
production-ready for v0.1.0.

Features Introduced

  • Bidirectional conversion — Convert JSON/JSONC to TOON and back, losslessly
  • Selection-aware — Select text in any file type (.md, .txt, etc.) to convert just that fragment
  • Explorer context menu — Right-click .json → "Convert to TOON (Save As…)", .toon → "Convert to JSON (Save As…)"
  • Editor context menu — Right-click with selection for inline conversion
  • Keyboard shortcutsCmd+Alt+T / Ctrl+Alt+T (to TOON), Cmd+Alt+J / Ctrl+Alt+J (to JSON)
  • TextMate grammar — Full syntax highlighting for .toon files (keys, values, arrays, tabular headers, escape sequences)
  • Real-time validation — Diagnostics in the Problems panel with per-document debounced validation
  • Configurable — User settings for indent, delimiter, key folding, path expansion
  • JSONC support — Handles JSON with Comments (trailing commas, comments stripped before conversion)

Technical Details

  • Uses @toon-format/toon@2.3.0 (ESM-only, aliased and bundled into extension via CJS output)
  • Uses jsonc-parser (ESM entry aliased to avoid UMD internal require issues) with human-readable error types
  • Single bundled CJS output (dist/extension.cjs, ~103 KB — all dependencies fully inlined)
  • Only external dependency at runtime: vscode (provided by the host)
  • Proper dispose pattern for all registered commands and diagnostics
  • vscode.workspace.fs for file operations (remote workspace compatible)
  • Error handling: try/catch on file reads, edit failure detection, cursor jump to error line
  • Per-document debounce timers (no race conditions with multiple open .toon files)
  • Strict mode always enabled for validation consistency

Commands

Command Trigger
Convert JSON to TOON Cmd+Alt+T, context menu, command palette
Convert TOON to JSON Cmd+Alt+J, context menu, command palette
Convert to TOON (Save As…) Explorer context menu on .json files
Convert to JSON (Save As…) Explorer context menu on .toon files

Settings

Setting Default Description
toon.encode.indent 2 TOON output indentation
toon.encode.delimiter , Tabular array delimiter
toon.encode.keyFolding off Dotted key folding
toon.decode.expandPaths off Expand dotted keys on decode
toon.json.indent 2 JSON output indentation
toon.openAfterConvert true Open file after save-as conversion
toon.validation.enable true Real-time validation toggle

akumarpalo and others added 13 commits June 4, 2026 10:25
…and settings

- Add @toon-format/toon and jsonc-parser as dependencies
- Register 4 commands: jsonToToon, toonToJson, convertToToonFile, convertToJsonFile
- Add context menus for explorer (.json/.toon) and editor
- Add keyboard shortcuts: Cmd+Alt+T (to TOON), Cmd+Alt+J (to JSON)
- Register TOON language with .toon extension
- Add user settings for encode/decode options and validation toggle
- Declare workspace trust support
- Bump version to 0.1.0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- jsonToToon: JSON.parse (or jsonc-parser for JSONC) → encode() → TOON string
- toonToJson: decode() → JSON.stringify with configurable indent
- ConversionResult type with success/failure discrimination
- Error position extraction for both JSON (via offset) and TOON (via ToonDecodeError.line)
- Utility functions for reading user settings (encode/decode options)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- jsonToToon: in-editor conversion with selection support and language mode switch
- toonToJson: in-editor conversion with selection support and language mode switch
- convertToToonFile: explorer/file conversion with save dialog
- convertToJsonFile: explorer/file conversion with save dialog
- Safety net guards prevent converting to the same format
- Error handling with cursor jump to error line
- Status bar feedback on success (3s transient message)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DiagnosticCollection validates .toon files in the Problems panel
- Validates on open, change (debounced 300ms), and clears on close
- Respects toon.validation.enable setting
- Extension entry point registers all 4 commands with dispose pattern
- Sets up diagnostics on activation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Syntax highlighting for keys, values, arrays, tabular headers, escape sequences
- Scopes: support.type.property-name, string.quoted.double, constant.numeric,
  constant.language.boolean, constant.language.null, variable.other.field
- Array header regex matches key[N]{fields}: patterns
- Language config: bracket pairs, auto-close, off-side folding, indentation rules

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Disable dts generation in tsdown (not needed for extension)
- Enable clean build output
- Add .node-version (22) for development tooling
- Update .vscodeignore to exclude dev files, keep dist/, syntaxes/, language-configuration.json

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds "Run Extension" configuration that launches the Extension
Development Host with a pre-build step.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously, commands rejected files that weren't .json/.toon.
Now: if text is selected, attempt conversion regardless of file type.
Language checks only apply for full-document conversion (no selection).

This enables converting JSON/TOON snippets embedded in .md, .txt,
or any other file by selecting the relevant text first.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Editor context menu now shows "Convert JSON to TOON" and
"Convert TOON to JSON" when there's an active selection,
regardless of the file's language. This enables converting
embedded JSON/TOON in any file type via right-click.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cleaner context menu labels without the redundant prefix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix debounce race condition: use per-document timer map instead of
  single global timer. Timers cleaned up on document close.
- Improve JSONC error messages: use printParseErrorCode() for human-
  readable error types (e.g., "CommaExpected at line 5")
- Add V8-specific comment on extractJsonErrorLine regex
- Add try/catch around workspace.fs.readFile in file conversion
  commands to handle permission/missing file errors gracefully
- Check editor.edit() return value: show error if edit was rejected
- Remove toon.decode.strict setting: always decode in strict mode
  (fixes diagnostics vs command inconsistency)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rewrite README with full feature documentation, usage guide, settings table
- Add CHANGELOG.md for marketplace
- Add extension icon (SVG)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix import ordering (perfectionist/sort-imports)
- Fix export ordering (perfectionist/sort-exports)
- Add parens to arrow function params (style/arrow-parens)
- Use --no-dependencies flag in vsce package (pnpm compatibility)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@akumarpalo akumarpalo requested review from a team and johannschopplich as code owners June 4, 2026 05:41
akumarpalo and others added 3 commits June 4, 2026 14:10
tsdown was treating dependencies as external despite only 'vscode'
being listed in the external config. Added explicit noExternal to
force bundling. Without this, the extension fails to activate since
the .vsix has no node_modules.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ESM output with createRequire shim was causing activation failures.
CJS is the universally compatible format for VS Code extensions.
Output file changed from dist/extension.mjs to dist/extension.cjs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The UMD entry of jsonc-parser has internal require('./impl/format')
calls that don't resolve when bundled into a single file. Fixed by
aliasing jsonc-parser to its ESM entry point which gets fully inlined.

Also removed "type": "module" from package.json and switched main
to dist/extension.cjs for reliable CJS loading in VS Code.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant