libsyntaxfmt provides middleware for formatting Oak source files, isolating core formatting logic from CLI concerns. It formats Oak code to consistent style.
syntaxfmt := import('syntaxfmt')
{
formatContent: formatContent
formatFile: formatFile
formatFileInPlace: formatFileInPlace
formatFileWithDiff: formatFileWithDiff
getChangedOakFiles: getChangedOakFiles
} := import('syntaxfmt')
Formats Oak source code string.
Parameters:
content- Oak source code string
Returns: Formatted source code string
{ formatContent: formatContent } := import('syntaxfmt')
code := 'fn add(a,b){a+b}'
formatted := formatContent(code)
println(formatted)
// => fn add(a, b) {
// a + b
// }
Reads and formats a file without modifying it.
Parameters:
path- File path to format
Returns: Result object:
{ ok: true, content: <formatted> }on success{ ok: false, error: <message> }on error
{ formatFile: formatFile } := import('syntaxfmt')
result := formatFile('lib/utils.oak')
if result.ok {
true -> println(result.content)
_ -> println('Error: ' + result.error)
}
Formats a file and writes the result back to the same file.
Parameters:
path- File path to format in-place
Returns: Result object:
{ ok: true }on success{ ok: false, error: <message> }on error
{ formatFileInPlace: formatFileInPlace } := import('syntaxfmt')
result := formatFileInPlace('src/main.oak')
if result.ok {
true -> println('File formatted successfully')
_ -> println('Error: ' + result.error)
}
Formats a file and returns a diff showing changes.
Parameters:
path- File path to format
Returns: Result object:
{ ok: true, diff: <diff output> }on success{ ok: false, error: <message> }on error
Note: Requires diff command available on the system.
{ formatFileWithDiff: formatFileWithDiff } := import('syntaxfmt')
result := formatFileWithDiff('lib/utils.oak')
if result.ok {
true -> if result.diff != '' {
true -> println(result.diff)
_ -> println('No formatting changes needed')
}
_ -> println('Error: ' + result.error)
}
Gets a list of changed .oak files from git.
Returns: Result object:
{ ok: true, files: [path1, path2, ...] }on success{ ok: false, error: <message> }on error
Note: Requires git repository and git command.
{ getChangedOakFiles: getChangedOakFiles } := import('syntaxfmt')
result := getChangedOakFiles()
if result.ok {
true -> {
println('Changed Oak files:')
each(result.files, println)
}
_ -> println('Error: ' + result.error)
}
{ formatFileInPlace: formatFileInPlace } := import('syntaxfmt')
{ printf: printf } := import('fmt')
path := 'src/app.oak'
result := formatFileInPlace(path)
if result.ok {
true -> printf('✓ Formatted {{0}}\n', path)
_ -> printf('✗ Failed to format {{0}}: {{1}}\n', path, result.error)
}
{ formatFileInPlace: formatFileInPlace } := import('syntaxfmt')
files := ['lib/utils.oak', 'lib/helpers.oak', 'src/main.oak']
each(files, fn(file) {
result := formatFileInPlace(file)
if result.ok {
true -> println('Formatted: ' + file)
_ -> println('Failed: ' + file + ' - ' + result.error)
}
})
{ formatFile: formatFile } := import('syntaxfmt')
fn checkFormatting(path) {
original := readFile(path)
result := formatFile(path)
if result.ok {
true -> if result.content = original {
true -> { formatted: true, path: path }
_ -> { formatted: false, path: path }
}
_ -> { error: result.error, path: path }
}
}
files := ['src/main.oak', 'lib/utils.oak']
results := files |> map(checkFormatting)
each(results, fn(r) {
if r.formatted = false {
true -> println('Needs formatting: ' + r.path)
} |> r.error {
? -> ?
_ -> println('Error: ' + r.path)
}
})
{
getChangedOakFiles: getChangedOakFiles
formatFileInPlace: formatFileInPlace
} := import('syntaxfmt')
result := getChangedOakFiles()
if result.ok {
true -> {
println('Formatting ' + string(len(result.files)) + ' changed file(s)...')
each(result.files, fn(file) {
formatResult := formatFileInPlace(file)
if formatResult.ok {
true -> println('✓ ' + file)
_ -> println('✗ ' + file + ': ' + formatResult.error)
}
})
}
_ -> println('Error: ' + result.error)
}
{ formatFileWithDiff: formatFileWithDiff } := import('syntaxfmt')
fn previewFormatting(path) {
result := formatFileWithDiff(path)
if result.ok {
true -> if result.diff {
'' -> {
println(path + ': Already formatted')
{ needsFormat: false }
}
_ -> {
println(path + ' changes:')
println(result.diff)
{ needsFormat: true, diff: result.diff }
}
}
_ -> {
println(path + ': Error - ' + result.error)
{ error: result.error }
}
}
}
previewFormatting('lib/utils.oak')
{
getChangedOakFiles: getChangedOakFiles
formatFile: formatFile
} := import('syntaxfmt')
fn checkFormattingCI() {
result := getChangedOakFiles()
if !result.ok -> {
println('Error: ' + result.error)
exit(1)
}
unformatted := []
each(result.files, fn(file) {
original := readFile(file)
formatResult := formatFile(file)
if formatResult.ok & formatResult.content != original -> {
unformatted <- append(unformatted, file)
}
})
if len(unformatted) > 0 {
true -> {
println('The following files need formatting:')
each(unformatted, fn(f) { println(' - ' + f) })
exit(1)
}
_ -> {
println('All files are properly formatted ✓')
exit(0)
}
}
}
checkFormattingCI()
{ formatFileInPlace: formatFileInPlace } := import('syntaxfmt')
{ listFiles: listFiles } := import('fs')
{ endsWith?: endsWith? } := import('str')
fn formatDirectory(dir) {
with listFiles(dir) fn(entries) if entries {
? -> println('Error reading directory: ' + dir)
_ -> {
oakFiles := entries |> filter(fn(e) {
!e.dir? & e.name |> endsWith?('.oak')
})
each(oakFiles, fn(file) {
path := dir + '/' + file.name
result := formatFileInPlace(path)
if result.ok {
true -> println('✓ ' + path)
_ -> println('✗ ' + path)
}
})
}
}
}
formatDirectory('lib')
formatDirectory('src')
- Uses
syntax.print()for formatting - File operations use
fslibrary - Diff generation uses system
diffcommand - Git integration uses
exec()to rungit diff - Returns structured result objects (not exceptions)
The formatter applies consistent Oak style:
- Standard indentation
- Consistent spacing around operators
- Proper bracket/brace alignment
- Normalized whitespace
All functions return result objects:
// Success
{ ok: true, content: '...' } // or { ok: true }
// Error
{ ok: false, error: 'Could not read file' }
- Requires
diffcommand for diff generation - Requires
gitcommand for changed files - No configuration options (fixed style)
- Comments may be reformatted
- Original file replaced (no automatic backup)
- Code formatting: Enforce consistent style
- CI/CD: Check formatting in pipelines
- Pre-commit hooks: Format before commit
- Batch processing: Format entire projects
- Editor integration: Format on save