Add a Format affordance on the playground toolbar once Monaco lands (#24). Monaco wires when formatting runs; we supply what formatting does per language via monaco.languages.registerDocumentFormattingEditProvider (and/or invoking editor.getAction('editor.action.formatDocument').run() when built-ins apply).
Goals — shared platform behavior
Toolbar: visible Format button (semi-playground-aware where labels/shortcuts are shared).
Shortcuts: target Format document from keyboard (e.g. align with VS Code / platform norms). Note: In Chrome, Ctrl + Shift + I is DevTools — pick a non-conflicting chord (e.g. Shift + Alt + F like Windows VS Code, or preventDefault on editor focus) and document in shortcuts table.
Optional polish (separate milestones OK): format on save, format before run/submit (“format on run”) — gated so lesson flows stay predictable.
Architecture: thin FormatProvider (or facade) injected per LANGUAGE_RUNNER_CONFIG / Monaco model language id — no duplicated toolbar logic per formatter backend.
Disclaimer: Monaco does not ship production-grade formatters for every language — implementations tracked in: #36 (JS/TS Prettier), #37 (Python Black / backend), #38 (C# Roslyn).
Technical notes
provideDocumentFormattingEdits: replace full-model range text with formatted output.
Errors: surface formatter failures in snackbar or inline without corrupting undo stack when possible (pushEditOperations vs setValue).
Teaching: deterministic style acceptable for beginners; avoid surprising mass edits without clear affordance (“Format changed your code”).
Dependency
Blocks on Monaco migration for app-language-runner — #24. Child tickets plug real formatters beneath this facade.
Acceptance criteria
Format invoked from toolbar + keyboard on happy path.
No-op or clear message when no provider registered for current language.
Document how per-language hooks register (readme or ADR snippet).
## Summary
Add a **Format** affordance on the playground **toolbar** once **Monaco** lands (`#24`). Monaco wires **when** formatting runs; **we** supply **what** formatting does per language via `monaco.languages.registerDocumentFormattingEditProvider` (and/or invoking `editor.getAction('editor.action.formatDocument').run()` when built-ins apply).
## Goals — shared platform behavior
- **Toolbar**: visible **Format** button (semi-playground-aware where labels/shortcuts are shared).
- **Shortcuts**: target **Format document** from keyboard (e.g. align with VS Code / platform norms). **Note:** In **Chrome**, **`Ctrl + Shift + I`** is **DevTools** — pick a non-conflicting chord (e.g. **`Shift + Alt + F`** like Windows VS Code, or `preventDefault` on editor focus) and document in shortcuts table.
- **Optional polish** (separate milestones OK): format on save, format before run/submit (“format on run”) — gated so lesson flows stay predictable.
- **Architecture**: thin **FormatProvider** (or facade) injected per **`LANGUAGE_RUNNER_CONFIG` / Monaco model language id** — no duplicated toolbar logic per formatter backend.
- **Disclaimer**: Monaco does **not** ship production-grade formatters for every language — **implementations tracked in**: **#36** (JS/TS Prettier), **#37** (Python Black / backend), **#38** (C# Roslyn).
## Technical notes
- **`provideDocumentFormattingEdits`**: replace full-model range text with formatted output.
- **Errors**: surface formatter failures in snackbar or inline without corrupting undo stack when possible (`pushEditOperations` vs `setValue`).
- **Teaching**: deterministic style acceptable for beginners; avoid surprising mass edits without clear affordance (“Format changed your code”).
## Dependency
- Blocks on Monaco migration for **`app-language-runner`** — `#24`. Child tickets plug real formatters beneath this facade.
## Acceptance criteria
- [ ] Format invoked from toolbar + keyboard on happy path.
- [ ] No-op or clear message when no provider registered for current language.
- [ ] Document how per-language hooks register (readme or ADR snippet).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Add a Format affordance on the playground toolbar once Monaco lands (
#24). Monaco wires when formatting runs; we supply what formatting does per language viamonaco.languages.registerDocumentFormattingEditProvider(and/or invokingeditor.getAction('editor.action.formatDocument').run()when built-ins apply).Goals — shared platform behavior
Ctrl + Shift + Iis DevTools — pick a non-conflicting chord (e.g.Shift + Alt + Flike Windows VS Code, orpreventDefaulton editor focus) and document in shortcuts table.LANGUAGE_RUNNER_CONFIG/ Monaco model language id — no duplicated toolbar logic per formatter backend.Technical notes
provideDocumentFormattingEdits: replace full-model range text with formatted output.pushEditOperationsvssetValue).Dependency
app-language-runner—#24. Child tickets plug real formatters beneath this facade.Acceptance criteria