cppl-format is the standalone command-line formatter for C++L - C++ with
Laws.
It is a thin CLI over cppl::formatter (compiler/formatter), the same
canonical-formatting engine cppl-lsp calls for
textDocument/formatting/rangeFormatting/onTypeFormatting. The CLI and
the language server share one engine and always agree: there is no
CLI-specific or editor-specific notion of canonical C++L formatting.
Ordinary C++ layout (indentation, line width, brace style, spacing) is
delegated entirely to clang-format, using the repository's .clang-format
by default. cppl-format does not reimplement any of that.
On top of clang-format's output, cppl-format relocates C++L-specific
declaration clauses so each begins its own continuation line, indented one
level from the enclosing declaration or loop header, with the opening { on
its own separate line back at the declaration's column:
// before
verified int fifty(int x) ensures (result == 50) {
return 50;
}
// after
verified int fifty(int x)
ensures (result == 50)
{
return 50;
}This applies to expects, ensures, invariant, and proves. There is no
whitespace between a clause keyword and its ( — expects and friends are
not C++ control statements, so the repository's SpaceBeforeParens: ControlStatements rule intentionally does not apply to them.
Refinement where clauses stay inline and are never relocated:
type Percentage = int where (self >= 0 && self <= 100);cppl-format builds as part of the ordinary CMake project; there is no
separate build step.
make buildor, directly:
cmake --preset dev
cmake --build build/devThe executable is produced at build/dev/bin/cppl-format.
cppl-format [options] <file>...By default, formatted output is written to stdout and the input files are left untouched.
-i, --in-place Rewrite each file in place instead of printing to stdout.
--check Report formatting drift without writing anything;
exit nonzero if any input file is not canonical.
--clang-format=<path> Use a specific clang-format executable instead of
the one selected at configure time.
-i and --check are mutually exclusive.
Examples:
# Print the canonical form of a file to stdout.
cppl-format path/to/file.cpp
# Reformat a file in place.
cppl-format -i path/to/file.cpp
# Verify a whole directory is canonically formatted (e.g. in CI);
# exits nonzero if anything would change.
cppl-format --check tests/fixtures/*.cpp
# Use a non-default clang-format binary.
cppl-format --clang-format=/opt/llvm/bin/clang-format -i path/to/file.cppFormatting is idempotent: running cppl-format -i twice on the same file
produces no further changes after the first pass.
cppl-format --check is folded into the repository's existing format/
format-check targets (cmake/CpplFormatting.cmake), alongside the
ordinary-C++ clang-format pass (cmake/Formatting.cmake):
make format # rewrites both ordinary C++ and C++L-specific layout
make format-check # fails if either layer has driftedThere is one command a developer or CI runs, not two separate formatters to remember to invoke.
make testor, to run only the formatter-related suites:
ctest --test-dir build/dev -R 'formatter_test|lsp_formatting_test|format_check'formatter_testexercisescompiler/formatterdirectly: laws, verified functions, loops, refinements, proofs, range/on-type formatting,check_style, and an idempotency property test over the real fixture corpus undertests/fixtures/.lsp_formatting_testprovescppl-lsp's formatting handlers and the shared engine produce byte-identical output over the same input.format_check(tests/format/format_check.sh) drives the installedcppl-formatbinary exactly as a developer or CI would, covering--check,-i, and idempotency.
cppl-format and cppl-lsp are two surfaces over one engine:
cppl::formatter (compiler/formatter)
/ \
/ \
▼ ▼
cppl-format CLI cppl-lsp
(--check / -i / stdout) (textDocument/formatting, rangeFormatting,
onTypeFormatting, publishDiagnostics
style warnings)
Neither surface owns a second definition of what "canonical" means. New
formatting rules belong in compiler/formatter, not in the CLI or the LSP
individually.
See tools/cppl-lsp/README.md for the language server's formatting
capabilities, and compiler/formatter/include/cppl/formatter/format.hpp for
the engine's API.