Skip to content
FutureBlitz

    Install

    Testing and tools, 2 of 5

    Formatting

    Lay code out in FutureBlitz's one style with fb fmt, check it in CI with --check, and set the line width.

    What you’ll build

    A short program written carelessly, with odd spacing, extra blank lines, and a line that’s too long, which fb fmt lays out in the standard style. Then you’ll check formatting without changing anything, as a CI job would, and change the line width.

    Untidy code

    This program works, but its spacing is all over the place:

    main.fb
    Import std.core
    
    
    Function Average( values:Float[] ):Float
      If values.Count==0 Then Return 0
      Local total=0.0
      For v In values
            total+=v   // add it up
      End For
    
    
      Return total/(values.Count As Float)
    End Function
    
    Function Describe(name:String,value:Float,count:Int,unit:String):String
        Return "{name}: {value} {unit}, from {count} readings"
    End Function
    
    Local temperatures:Float[]=[ 18.5,21.0 , 19.5,23.0 ]
    Print( Describe("average temperature", Average(temperatures), temperatures.Count, "degrees Celsius at noon") )

    fb fmt

    fb fmt main.fb

    fb fmt rewrites the file in place. With no file named, it formats every .fb file of the package you’re in.

    Import std.core
    
    Function Average(values: Float[]): Float
        If values.Count == 0 Then Return 0
        Local total = 0.0
        For v In values
            total += v // add it up
        End For
    
        Return total / (values.Count As Float)
    End Function
    
    Function Describe(name: String, value: Float, count: Int, unit: String): String
        Return "{name}: {value} {unit}, from {count} readings"
    End Function
    
    Local temperatures: Float[] = [18.5, 21.0, 19.5, 23.0]
    Print(Describe("average temperature", Average(temperatures), temperatures.Count,
                   "degrees Celsius at noon"))
    Output
    average temperature: 20.5 degrees Celsius at noon, from 4 readings

    What changed:

    • Each block is indented 4 spaces.
    • Binary operators, =, and += have a space on each side, and : and , a space after them. Parentheses and brackets have none inside.
    • Two blank lines in a row became one.
    • A comment after code is one space after it. Its text is kept.
    • The last line was wider than 100 columns, so it was broken after a comma, and the next line lines up one past the open parenthesis.

    There’s one style and no options for it, so every FutureBlitz project reads the same. The formatter only changes the spaces between tokens and where long lines break, and it checks that the result parses to the same code before writing it, so formatting never changes what a program does. A file that doesn’t parse is left as it is, with its errors reported.

    Checking without changing

    --check lists the files that aren’t formatted and exits with 1, without changing them:

    fb fmt --check main.fb
    main.fb
    error: 1 file isn't formatted; fb fmt formats them

    A CI job that runs fb fmt --check fails on code that wasn’t formatted, and passes once it is. In VS Code, the extension formats each file as you save it, in the same style.

    The line width

    Lines are 100 columns wide unless the package’s project.toml says otherwise, in [format]:

    [format]
    width = 80

    The width can be from 40 to 1000. Line breaks you write inside a statement stay, and lines are never joined, so a statement you’ve split by hand keeps its shape. A line that can’t fit at any break, like one holding a long string, is left as written.

    What you learned

    • fb fmt formats files in place, in the one standard style.
    • Formatting changes only spacing and line breaks, never what the code does.
    • fb fmt --check lists unformatted files and fails, for CI.
    • [format] width in project.toml sets the line width, 100 by default.

    Report an issue with this page or with FutureBlitz on GitHub.