This document specifies the canonical formatting for .mx source files. The
moxiefmt tool enforces these rules mechanically.
If the content within a { } block fits under 80 characters wide with ;
separating statements, the single-line form is canonical.
This rule applies universally to all brace-delimited constructs:
if, for, select, switchstruct, interface[] (slice/array literals), map[] (map literals)func bodiesSingle-line:
if err != nil { return err } struct{ x int32; y int32 } for i := int32(0); i < n; i++ { sum += i } func name() { return 1 }
Multi-line (exceeds 80 chars, or author preference for clarity):
struct{ name string addr string port int32 }
Tabs, not spaces. One tab per nesting level. Tab width = 4 spaces. No mixed indentation.
When a block exceeds the 80-column threshold:
{ stays on the same line as the preamble} on its own line, aligned with the preambleExplicit semicolons separate statements on a single line. In multi-line form, newlines replace semicolons - no trailing semicolons at line ends.
{ when it attaches to a type keyword or type name: struct{, interface{, TypeName{, map[K]V{, []T{
{ in control flow where { follows an expression: if err != nil {, for i < n {
{ when it follows ): func name() {, if f() {
; in single-line blocks(() or []Note (language constraint, not purely formatting): all return values must be
named. Return signatures take the form (name type, name type) with no spaces
between the parens and the list. This applies universally: top-level functions,
methods, and method fields within struct/interface definitions.
{ or before closing }Always multi-line with () wrapping, one statement per line. The single-line
form is not valid.
import( "fmt" "os" )
requires( example.com/pkg v1.2.3 )
replace( example.com/pkg => ../local/pkg )
Contiguous items within struct{, interface{, and function bodies are
vertically aligned by column. A double blank line (two consecutive newlines with
no content) breaks an alignment group - items after the break start a new
independent alignment.
struct{ name string address string port int32
x int32 y int32 }
Trailing // comments after statements are also vertically aligned within a
contiguous block. A single blank line continues the block; a double blank line
resets alignment.
x := compute() // first pass y := transform(x) // second pass z := finalize(y) // done
a := other() // new alignment group b := more() // independent of above
80 columns is the hard threshold for the single-line rule. Lines in multi-line form should also target 80 columns but this is not enforced mechanically - the formatter only uses 80 as the single-line/multi-line decision boundary.
The formatter automatically wraps return values in () with named parameters.
Even a single return value is wrapped: func f() (err error) not
func f() error. This is a language constraint that moxiefmt enforces
mechanically.