Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

  1. repeated --config-file <PATH> files, if provided
  2. the nearest .cmakefmt.yaml, .cmakefmt.yml, or .cmakefmt.toml found by walking upward from the target
  3. ~/.cmakefmt.yaml, ~/.cmakefmt.yml, or ~/.cmakefmt.toml
  4. 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

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

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:

  • prefix
  • open
  • close
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:

  • lower
  • upper
  • unchanged
style:
  command_case: lower

keyword_case

Controls the casing of recognized keywords and flags.

Allowed values:

  • lower
  • upper
  • unchanged
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_case
  • keyword_case
  • line_width
  • tab_size
  • dangle_parens
  • dangle_align
  • max_hanging_wrap_positional_args
  • max_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
  • QUIET is a standalone flag
  • SOURCES starts a keyword section with one or more values
  • LIBRARIES starts 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_tabchars
  • max_pargs_hwrap
  • max_subgroups_hwrap
  • separate_ctrl_name_with_space
  • separate_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.