Sweets
Configuration

Splitting Your Config

Organize sweets.lua with relative, root-confined includes

sweets.include(path) runs another Lua file at that point in the current layer. Use it to keep bindings, rules, and outputs in separate files.

Suggested structure

~/.config/sweets/
├── sweets.lua
├── bindings.lua
├── rules.lua
└── parts/
    ├── general.lua
    ├── layout.lua
    └── startup.lua

Keep the root file small and include the parts in execution order:

~/.config/sweets/sweets.lua
sweets.include("parts/general.lua")
sweets.include("parts/layout.lua")
sweets.include("bindings.lua")
sweets.include("rules.lua")
sweets.include("parts/startup.lua")

Each file uses the normal API:

~/.config/sweets/bindings.lua
sweets.bind("MOD+Return", "spawn", { "foot" })
sweets.bind("MOD+D", "spawn", { "fuzzel" })

for number = 1, 9 do
    sweets.bind("MOD+" .. number, "workspace", number)
end

Paths

Paths are relative to the file containing the sweets.include call, not to the working directory. Nested includes need no parent directories:

~/.config/sweets/parts/general.lua
sweets.include("pointer.lua")  -- ~/.config/sweets/parts/pointer.lua

Absolute paths and .. are rejected, and includes cannot leave the directory holding their root sweets.lua. A leading ~ is not expanded — it looks for a literal ~ directory.

A symlink is accepted only when its target is a regular file that is still inside the same root.

Do not include the installed /usr/share/sweets/sweets.lua from your own file. Sweets already loads it as the first layer.

Order and scope

Declarations take effect in include order, and bindings, rules, input selectors, and startup commands keep their declaration order across files.

A singleton such as sweets.general may appear once across a root and all of its includes. sweets.layout_style may appear once per layout.

Included files share globals but not locals. Assign a global before an include reads it:

~/.config/sweets/sweets.lua
palette = { accent = "#C27AFF" }
sweets.include("parts/border.lua")
~/.config/sweets/parts/border.lua
sweets.border({ focused = palette.accent })

Repeats and cycles

A file may appear only once per candidate. Including it twice is an error, even through two different symlinks, and so is a cycle:

a.lua
sweets.include("b.lua")
b.lua
sweets.include("a.lua")  -- error

Sweets reports the include chain so you can find the repeat or cycle.

Validation and reload

sweets --check-config                        # installed and personal layers
sweets --check-config ./test/sweets.lua      # one root and its includes

Errors name the included file and Lua line. Sweets watches every included file, so saving one reloads the whole tree. A missing include rejects the configuration, and Sweets watches for that path to appear.

Includes count against the configuration limits: 32 sources, 16 levels of nesting, 256 KiB per file, and 512 KiB in total.

Common errors

ErrorCause
include path must be relativeThe path begins at /
include path must not contain ..The path tries to leave its root
cannot resolve configuration sourceThe file is missing or unreadable
include target escapes permitted rootA symlink resolves outside the root
source included more than onceTwo includes resolve to the same file
include cycleAn included file includes one of its parents
sweets.SECTION may be declared only onceA singleton appears twice in a layer

Next steps

On this page