How do I format an EK9 file that does not parse?

← Code Formatting · Ref: Q624

Use the -ff flag (force format) on a file that does not parse because of a slip with exactly one reading. Use -fF to force-format all project files.

FORCE FORMAT SINGLE FILE

  ek9 -ff myfile.ek9

Force format first repairs, as text, what stops a file parsing when only one reading of it is possible, then applies the normal formatter:
- layout: a byte-order mark is removed, CRLF line endings become LF, a missing or wrong first line becomes #!ek9, tabs used for layout become spaces (a tab inside a String is content and is kept), an odd base indent width becomes 2 spaces per level;
- slips from other languages: '-> a as Integer, b as String' becomes one parameter per line under a bare '->'; 'add(name as String)' on a declaration moves the parameter under '->'; a 'defines' block at column 0 moves to column 2; a bare 'default operator' moves to the end of its body; a stray trailing bracket is dropped; '&&' and '||' become 'and' and 'or'; a trailing ':' after an if/while condition is dropped; '#' and C block comments become EK9 comments; 'List<String>()' becomes 'List() of String'; 'Main() @Test' puts '@Test' on the line above; 'Type?: value' drops the '?'.
Every repair is reported, and the file is rewritten only if the result parses; otherwise it is left exactly as it was. Force format never renames anything: a misspelt keyword is left for you to correct, because guessing would rename valid identifiers (heads is a perfectly good name, not a typo for head).

FORCE FORMAT ALL FILES

  ek9 -fF myproject.ek9

This force-formats every .ek9 file in the project.

ALL FOUR FORMAT FLAGS

  ek9 -f  myfile.ek9    Format single file (must parse).
  ek9 -F  myproject.ek9  Format all project files (must parse).
  ek9 -ff myfile.ek9    Force format single file (repairs first).
  ek9 -fF myproject.ek9  Force format all project files (repairs first).

WHEN TO USE FORCE FORMAT

- When an editor has put tabs into the indentation, or saved Windows line endings or a byte-order mark.
- When code was written with another language's habits (comma parameters, '&&', a Python ':').
When a compile fails for one of these reasons, the compiler's own hint suggests ek9 -ff, lists the repairs it would make - and only then.

LIMITATIONS

Force format does not guess: a slip with two readings is named and left for you - '%' (mod or rem?), 'assert x, "message"' (EK9's assert takes no message), '$name' inside a backtick String ('${name}' or a literal '\$'), a misspelt keyword, or how many lines belong under an 'if'. The file is then left unchanged; fix it from the message and compile again.

See Q622 for standard single-file formatting. See Q623 for formatting all project files. See Q625 for why EK9 enforces a standard format.

Example

defines module qa.codeformatting.force

  defines function

    <?-
      A well-formatted function.
      After force-formatting a broken version, it would look like this.
    -?>
    sanitizeInput() as pure
      -> raw as String
      <- cleaned as String: raw.trim()

    isNonEmpty() as pure
      -> text as String
      <- result as Boolean: text?

  defines program

    ForceFormatDemo()
      stdout <- Stdout()

      userInput <- "  hello world  "
      cleaned <- sanitizeInput(userInput)
      hasContent <- isNonEmpty(cleaned)

      stdout.println(`Cleaned: '${cleaned}'`)
      stdout.println(`Has content: ${hasContent}`)

Common mistakes

E50001 — Removing the variable declaration means later references to the variable become unresolved, triggering E50001. See ek9 -h E50001 for details.

Incorrect:

sanitizeInput(userInput)
      hasContent <- isNonEmpty(cleaned)

Correct:

cleaned <- sanitizeInput(userInput)
      hasContent <- isNonEmpty(cleaned)
Other ways to ask this
  • What does ek9 -ff do?
  • How do I force-format a broken EK9 file?
  • Can the formatter fix syntax errors in my code?

Coming from another language?

Go: gofmt requires valid Go syntax, no force mode. Rust: rustfmt requires valid Rust syntax, no force mode. Python: black requires valid Python syntax. JavaScript: prettier can handle some malformed code. EK9: ek9 -ff repairs what stops a file parsing when it has exactly one reading (layout, comma parameters, '&&', a stray bracket ...), reports each repair, and never renames anything.

Keywords: ff, syntax, error, style, force, unparseable, broken, format, fF, recover, fix, indent