Config Reference
Everything you need to know to tune cmakefmt for your project.
The short version:
- user config may be YAML or TOML
- YAML is the recommended default for hand-edited configs
- custom command syntax goes under
commands: - command-specific layout and style tweaks go under
per_command_overrides:
Config Discovery Order
For a given target file, cmakefmt resolves config in this order:
- repeated
--config-file <PATH>files, if provided - the nearest
.cmakefmt.yaml,.cmakefmt.yml, or.cmakefmt.tomlfound by walking upward from the target ~/.cmakefmt.yaml,~/.cmakefmt.yml, or~/.cmakefmt.toml- built-in defaults
If multiple supported config filenames exist in the same directory, YAML is preferred over TOML.
When you want to see exactly what happened:
cmakefmt --show-config-path src/CMakeLists.txt
cmakefmt --show-config src/CMakeLists.txt
cmakefmt --explain-config
Recommended Starter File
YAML is the recommended user-facing format:
format:
line_width: 80
tab_size: 2
style:
command_case: lower
keyword_case: upper
Generate the full starter template with:
cmakefmt --dump-config > .cmakefmt.yaml
If you prefer TOML:
cmakefmt --dump-config toml > .cmakefmt.toml
Table Of Contents
- Format Options
- Style Options
- Markup Options
- Per-command Overrides
- Custom Command Specs
- Old Draft Key Names
Defaults
format:
line_width: 80
tab_size: 2
use_tabs: false
max_empty_lines: 1
max_hanging_wrap_lines: 2
max_hanging_wrap_positional_args: 6
max_hanging_wrap_groups: 2
dangle_parens: false
dangle_align: prefix
min_prefix_length: 4
max_prefix_length: 10
space_before_control_paren: false
space_before_definition_paren: false
style:
command_case: lower
keyword_case: upper
markup:
enable_markup: true
reflow_comments: false
first_comment_is_literal: true
literal_comment_pattern: ""
bullet_char: "*"
enum_char: "."
fence_pattern: "^\\s*[`~]{3}[^`\\n]*$"
ruler_pattern: "^[^\\w\\s]{3}.*[^\\w\\s]{3}$"
hashruler_min_length: 10
canonicalize_hashrulers: true
Format Options
line_width
Target maximum output width before wrapping is attempted.
format:
line_width: 100
Raise this if your project prefers wider CMake calls.
tab_size
Indent width in spaces when use_tabs is false.
format:
tab_size: 4
use_tabs
Use tab characters for indentation instead of spaces.
format:
use_tabs: true
This affects leading indentation only. Internal alignment rules use the configured indentation unit but are not otherwise changed.
max_empty_lines
Maximum number of consecutive blank lines to preserve.
format:
max_empty_lines: 1
Blank-line runs larger than this limit are clamped down. Vertical breathing room is preserved; runaway gaps are not.
max_hanging_wrap_lines
Maximum number of lines a hanging-wrap layout may consume before the formatter falls back to a more vertical layout.
format:
max_hanging_wrap_lines: 2
Lower values force more aggressively vertical output.
max_hanging_wrap_positional_args
Maximum positional arguments to keep in a hanging-wrap layout before falling back to a more vertical layout.
format:
max_hanging_wrap_positional_args: 6
Most noticeable on commands with long source or header lists.
max_hanging_wrap_groups
Maximum number of keyword/flag subgroups to keep in a hanging-wrap layout.
format:
max_hanging_wrap_groups: 2
Lower this to push keyword-heavy commands toward vertical layout sooner.
dangle_parens
Place the closing ) on its own line when a call wraps.
format:
dangle_parens: true
Effect:
target_link_libraries(
foo
PUBLIC
bar
baz
)
dangle_align
Alignment strategy for a dangling closing ).
Allowed values:
prefixopenclose
format:
dangle_align: prefix
min_prefix_length
Lower heuristic bound used when deciding between compact and wrapped layouts.
format:
min_prefix_length: 4
Leave this alone unless you are deliberately tuning layout behavior.
max_prefix_length
Upper heuristic bound used when deciding between compact and wrapped layouts.
format:
max_prefix_length: 10
Like min_prefix_length, this is a layout-tuning knob rather than a
day-one config option.
space_before_control_paren
Insert a space before ( for control-flow commands such as if, foreach,
and while.
format:
space_before_control_paren: true
Effect:
if (WIN32)
message(STATUS "Windows")
endif ()
space_before_definition_paren
Insert a space before ( for function and macro definitions.
format:
space_before_definition_paren: true
Effect:
function (my_helper arg)
...
endfunction ()
Style Options
command_case
Controls the casing of command names.
Allowed values:
lowerupperunchanged
style:
command_case: lower
keyword_case
Controls the casing of recognized keywords and flags.
Allowed values:
lowerupperunchanged
style:
keyword_case: upper
Example — with command_case: lower and keyword_case: upper:
target_link_libraries(foo PUBLIC bar)
stays:
target_link_libraries(foo PUBLIC bar)
With command_case: upper and keyword_case: lower:
TARGET_LINK_LIBRARIES(foo public bar)
Markup Options
enable_markup
Enable comment-markup awareness.
markup:
enable_markup: true
When enabled, the formatter can recognize lists, fences, and rulers inside comments rather than treating them as opaque text.
reflow_comments
Reflow plain line comments to fit within the configured line width.
markup:
reflow_comments: true
Leave this false if you want comments preserved more literally.
first_comment_is_literal
Preserve the first comment block in a file without any reflowing or markup processing.
markup:
first_comment_is_literal: true
Useful for license headers or hand-crafted introductory comments that must stay exactly as written.
literal_comment_pattern
Regex for comments that should never be reflowed.
markup:
literal_comment_pattern: "^\\s*NOTE:"
Use this for project-specific comment conventions that must stay untouched.
bullet_char
Preferred bullet character when normalizing markup lists.
markup:
bullet_char: "*"
enum_char
Preferred punctuation for numbered lists when normalizing markup.
markup:
enum_char: "."
fence_pattern
Regex describing fenced literal comment blocks.
markup:
fence_pattern: "^\\s*[`~]{3}[^`\\n]*$"
Keep the default unless your project has a strong house style.
ruler_pattern
Regex describing ruler-style comments that should be treated specially.
markup:
ruler_pattern: "^[^\\w\\s]{3}.*[^\\w\\s]{3}$"
hashruler_min_length
Minimum length before a hash-only line is treated as a ruler.
markup:
hashruler_min_length: 10
canonicalize_hashrulers
Normalize hash-ruler comments when markup handling is enabled.
markup:
canonicalize_hashrulers: true
If your project uses decorative comment rulers and wants them normalized consistently, keep this enabled.
Per-command Overrides
Use per_command_overrides: to change formatting knobs for one command name
without touching that command’s argument syntax.
Example:
per_command_overrides:
my_custom_command:
line_width: 120
command_case: unchanged
keyword_case: upper
tab_size: 4
dangle_parens: false
dangle_align: prefix
max_hanging_wrap_positional_args: 8
max_hanging_wrap_groups: 3
Supported override fields:
command_casekeyword_caseline_widthtab_sizedangle_parensdangle_alignmax_hanging_wrap_positional_argsmax_hanging_wrap_groups
Use this when you want a command to format differently from the global defaults.
Do not use it to define a command’s argument structure — that belongs in
commands:.
Custom Command Specs
Use commands: to teach cmakefmt about custom functions and macros, or to
override the built-in shape of an existing command.
Example:
commands:
my_custom_command:
pargs: 1
flags:
- QUIET
kwargs:
SOURCES:
nargs: "+"
LIBRARIES:
nargs: "+"
This tells cmakefmt that:
- the command starts with one positional argument
QUIETis a standalone flagSOURCESstarts a keyword section with one or more valuesLIBRARIESstarts a keyword section with one or more values
Once the formatter knows the structure, it can group and wrap the command intelligently — instead of treating every token as an undifferentiated argument. For larger custom specs, YAML is much easier to maintain than TOML, which is why the default starter config is YAML.
Old Draft Key Names
The current cmakefmt config schema only accepts the clearer names on this
page. If you have an older local config using names such as:
use_tabcharsmax_pargs_hwrapmax_subgroups_hwrapseparate_ctrl_name_with_spaceseparate_fn_name_with_space
update them before use. cmakefmt fails fast on unknown config keys rather
than silently ignoring them — so you will know immediately.