Man pages / silk-format(1) — Format Silk Source Files

silk-format(1) — Format Silk Source Files

NOTE: This is the Markdown source for the eventual man 1 page for silk format. The roff-formatted manpage should be generated from this content.

Name#

silk-format — format Silk source files.

Synopsis#

  • silk format [options] <path> [<path> ...]
  • silk fmt [options] <path> [<path> ...]

Description#

silk format rewrites Silk source files (.slk and .silk) to the canonical formatting style.

The formatter discovers project configuration by searching for .silk/format.toml, starting from each formatted file’s directory and walking upward to the filesystem root. The first config file found applies to that file.

When you pass a directory, the recursive walk also honors .gitignore files in that tree (including parent repository ignore files when you format a subdirectory). Explicitly named file arguments still format even when they are ignored, so you can target a specific generated or local file intentionally.

The formatter is readability-oriented:

  • it normalizes indentation,
  • it splits same-line statement runs so each statement or block body starts on its own line,
  • it keeps semicolons nested inside paren/bracket groups inline instead of treating them as standalone statement breaks (for example join(T; h) and for (...; ...; ...) stay single-line unless the source already uses a multiline layout),
  • it preserves newline-based if / else if headers by keeping the opening { on its own line and indenting chained condition lines one level deeper than the control keyword,
  • it inserts a visual separator after standalone block-closing } boundaries when the next token starts a new statement or declaration,
  • it keeps } else { on one line,
  • it preserves the file’s detected newline style (\n or \r\n) when it emits new layout,
  • it preserves ordinary line/block comments instead of deleting or reflowing them away,
  • and it reflows large named-import lists into one imported symbol per line.

When the leading package/module/import header contains only declarations and whitespace, silk format also canonicalizes imports into three sections:

  • std::... and std-root imports first,
  • then non-relative package/module imports,
  • then relative file imports,

with alphabetical sorting inside each section.

This header reordering pass is intentionally conservative. If the leading header region contains ordinary comments or other non-whitespace trivia between declarations, the formatter keeps that region in source order instead of rewriting it. It still normalizes the blank-line boundary between that preserved header region and the first non-header declaration.

Options#

  • --json — emit newline-terminated, schema-versioned changed-file results on stdout.
  • --check — do not write any files; exit non-zero if any file would change.
  • --help, -h — show command usage and exit.
  • -- — end of options (treat following args as paths, even if they begin with -).

JSON Output#

--json emits schemaVersion, command, ok, check, status, changedCount, and changedFiles.

In --check --json mode, files that would change produce ok: false, "needs-formatting", and the same non-zero exit code as human output.

Configuration (.silk/format.toml)#

The formatter reads configuration from a TOML file at .silk/format.toml.

Supported keys (under the [format] table):

  • indent_style = "space" | "tab" (default: "space")
  • indent_width = <int> (default: 2; used only when indent_style = "space")

Example:

[format]
indent_style = "space"
indent_width = 2

Notes#

  • Multi-line string literals (including raw backtick strings) are preserved verbatim.
  • Ordinary line/block comments are preserved; multiline block-comment bodies keep their source text.
  • Formatter-emitted layout preserves the file’s detected newline convention instead of mixing LF into CRLF files.
  • The formatter preserves comment-bearing header regions instead of reordering them.
  • Recursive directory walks honor .gitignore; explicitly named file paths still format.
  • The formatter does not type-check inputs; use silk check to validate code.

Examples#

silk fmt src
silk format --check .
silk format --check --json .
import util from pkg::util;
import { Delta, Alpha, Beta, Gamma } from "./local.slk";
import "./a.slk";
import std::io;
import { Zebra, Beta, Alpha, Gamma } from pkg::names;
import std::fs;

fn main () -> int { let x: int = 1; if x == 1 { return 0; } return 1; }

becomes:

import std::fs;
import std::io;

import {
  Alpha,
  Beta,
  Gamma,
  Zebra,
} from pkg::names;
import util from pkg::util;

import "./a.slk";
import {
  Alpha,
  Beta,
  Delta,
  Gamma,
} from "./local.slk";

fn main () -> int {
  let x: int = 1;
  if x == 1 {
    return 0;
  }

  return 1;
}

See Also#

Source repository · Edit this page · View Markdown