Treatment of Comments

Tombi uses a group-based comment model to keep formatting stable and auto-sorting predictable.

This page explains the behavior in plain TOML examples, without implementation details.

Quick Summary

  • Tombi treats blank-line-separated comment blocks as meaningful boundaries.
  • Sorting happens inside each group, not across group boundaries.
  • # tombi: directives only control formatter/linter rules when placed in a position that has a clear target.

Comment Roles in TOML

Leading comments

Comments directly attached to the item below.

# leading comment 1
# leading comment 2
key = "value"

Trailing comments

A comment at the end of the same line.

key = "value" # trailing comment

Dangling comment groups

Comment blocks separated by blank lines. These create visual/logical boundaries.

# dangling comment group A line 1
# dangling comment group A line 2

# dangling comment group B line 1
# dangling comment group B line 2

Blank Lines Define Boundaries

A blank line is treated as a boundary between groups.

That boundary is important because Tombi does not move values/keys across it when sorting.

[tool.demo]
b = 2
a = 1

z = 26
y = 25

Tombi may reorder b/a and z/y inside each group, but it does not merge or cross the boundary.

Where # tombi: Directives Are Effective

A simple rule:

  • Effective: before the first item of the current container.
  • Not effective for rule control: between groups after items already appeared.

Below are concrete examples.

Root-level example

Effective at root level (before first key):

# root directive: effective for the root table
# tombi: format.rules.table-keys-order = "ascending"

b = 2
a = 1

Not effective at root level (appears after root items started):

b = 2
a = 1

# root group-boundary directive:
# interpreted as an empty key-value group directive
# (not used for rule control)
# tombi: format.rules.table-keys-order = "ascending"

z = 26
y = 25

In this position, Tombi interprets the directive as belonging to an empty key-value group at the boundary.
So it is recognized by tooling, but it does not affect formatter/linter rule control.

Standard table example

Effective for [package] (before first key in that table):

[package]
# package directive: effective for this table
# tombi: format.rules.table-keys-order = "ascending"

name = "demo"
version = "1.0.0"

Not effective for [package] (between table groups after keys already appeared):

[package]
name = "demo"
version = "1.0.0"

# package group-boundary directive: not used for rule control
# tombi: format.rules.table-keys-order = "ascending"

description = "example"
license = "MIT"

Array example

Effective for the array (before first value):

items = [
  # array directive: effective for this array
  # tombi: format.rules.array-values-order = "ascending"

  "banana",
  "apple",
]

Not effective for the array (between value groups after values already appeared):

items = [
  "banana",
  "apple",

  # array group-boundary directive: not used for rule control
  # tombi: format.rules.array-values-order = "ascending"

  "date",
  "cherry",
]

Inline table example

Effective for the inline table (before first key-value in the inline table):

point = {
  # inline-table directive: effective for this inline table
  # tombi: format.rules.table-keys-order = "ascending"

  y = 20,
  x = 10,
}

Not effective for the inline table (between groups after key-values already appeared):

point = {
  y = 20,
  x = 10,

  # inline-table group-boundary directive: not used for rule control
  # tombi: format.rules.table-keys-order = "ascending"

  z = 30,
}

Array-of-tables example

Effective for each [[servers]] block only when placed before that block's first key:

[[servers]]
# array-of-table directive: effective for this table item
# tombi: format.rules.table-keys-order = "ascending"

port = 8080
host = "localhost"

Not effective when placed between groups after keys already appeared:

[[servers]]
port = 8080
host = "localhost"

# array-of-table group-boundary directive: not used for rule control
# tombi: format.rules.table-keys-order = "ascending"

protocol = "http"

What Happens to Non-Effective Directives?

When a directive is placed at a group boundary (not rule-effective):

  • Formatter rule control: no available rules in this position
  • Linter rule control: no available rules in this position
  • Editor support (completion/hover/validation): still available

So you still get language-server assistance, but the directive does not change formatting/linting behavior.

One Annotated Walkthrough

# [root directive: effective for root]
# tombi: format.rules.table-keys-order = "ascending"

# [root dangling comment group]

[package]
# [table directive: effective for package table]
# tombi: format.rules.table-keys-order = "ascending"

name = "demo"
version = "1.0.0"

# [table group-boundary directive: not effective for rule control]
# tombi: format.rules.table-keys-order = "descending"

description = "example"

items = [
  # [array directive: effective for this array]
  # tombi: format.rules.array-values-order = "ascending"

  "b",
  "a",

  # [array group-boundary directive: not effective for rule control]
  # tombi: format.rules.array-values-order = "descending"

  "d",
  "c",
]

Reading rule:

  • Comments labeled "directive: effective" are used for rule control.
  • Comments labeled "group-boundary directive" are treated as boundary comments and are not used for formatter/linter rule control.

For directive syntax and available options, see Comment Directive.