# Modula-2 formatting `Format Document` (Shift+Alt+F) normalises a whole file through the language server (`textDocument/formatting`), and `Format Selection` does the same for the selected lines (`textDocument/rangeFormatting`). Every rule below is settable under `modula2.format.*` in Settings; changes apply live, no reload. ## What the formatter does - **Indentation** from block structure (`BEGIN`/`IF`/`CASE`/`LOOP`/ `RECORD`/…`END`), using `indentSize` spaces or tabs. - **Keyword case** (`upper`, the default, or `preserve`). - **Spacing**: operators, commas, colons, `..` ranges. - **Blank lines** collapsed to `emptyLineLimit`; trailing whitespace trimmed; file ends with exactly one newline (all settable). Line structure is deliberately preserved: statements are never joined or split, so formatting a file you didn't write can't scramble its layout. Comments are preserved verbatim (only repositioned). Formatting is idempotent and token-exact: running it twice changes nothing, and it never adds, removes or renames code — verified across real-world sources, whose formatted output still compiles with `gm2`. ## Settings | Setting | Default | Effect | |---|---|---| | `modula2.format.indentSize` | `2` | Spaces per level (0–8; unused with tabs). | | `modula2.format.useTabs` | `false` | Indent with tabs. | | `modula2.format.keywordCase` | `"upper"` | `"upper"` uppercases reserved words, `"preserve"` leaves case alone. There is intentionally no `"lower"`: lowercase keywords do not compile with `gm2`. | | `modula2.format.spaceAroundOperators` | `true` | `a := b`, `x + y`. Off gives compact `a:=b`, `x+y`. | | `modula2.format.spaceAfterComma` | `true` | `a, b` vs `a,b`. | | `modula2.format.spaceBeforeColon` | `false` | `x: INTEGER` vs `x : INTEGER`. | | `modula2.format.spaceAroundRange` | `true` | `[0 .. 9]` vs `[0..9]`. | | `modula2.format.emptyLineLimit` | `1` | Max consecutive blank lines (0–10). | | `modula2.format.trimTrailingWhitespace` | `true` | Strip trailing spaces. | | `modula2.format.insertFinalNewline` | `true` | Exactly one newline at end of file. | ## Notes - `keywordCase` covers reserved words only. Predefined identifiers (`INTEGER`, `TRUE`, `NIL`, …) can legally be redeclared, so they are never retouched — same as the typing-time auto-uppercasing. - Identifiers that merely look like keywords (`mod`, `In`, `Type` are all real identifiers in the wild and accepted by `gm2`) are resolved first and left alone. Unresolvable ones follow the keyword rule, matching the editor's auto-uppercasing. - `CLIENT` tab/indent settings (`editor.tabSize`) do not drive Modula-2 formatting; `modula2.format.*` always wins. - `Format Selection` formats whole lines intersecting the selection, using full-document context (indentation levels depend on preceding lines) while leaving everything outside the selection byte-identical — including collapsing surplus blank lines and the final newline when the selection reaches end of file. With an empty selection, the cursor line is formatted.