Split the Config

Keep the TUIOS config in more than one file with include lists and config.d, and see which file sets each key.

You can keep the TUIOS config in more than one file. Use this to share one config between machines and keep the settings of one machine in a separate file. A Nix or home-manager setup can also put its settings in a file that it manages.

There are two ways to add files. Use one or both:

  • An include list in config.toml.
  • A config.d directory next to config.toml.

The include list

Put an include list at the top of config.toml, before the first table:

include = ["hosts.toml", "~/.config/tuios/local.toml", "?work.toml"]

[appearance]
border_style = "thick"
  • A relative path is relative to the file that has the include line.
  • ~ is your home directory.
  • A name that starts with ? is optional. When the file is not there, TUIOS says nothing.
  • An included file can have its own include list.

Put include before the first table

TOML puts a key below a table header into that table. An include key below [appearance] is appearance.include, and it includes nothing. TUIOS shows a warning when this happens.

Windows paths

On Windows, write an include path with forward slashes, or put it in a single-quoted literal string. In a double-quoted TOML string, a backslash starts an escape.

include = ["C:/Users/me/tuios/local.toml", 'C:\Users\me\tuios\work.toml']

The config.d directory

Put *.toml files in a config.d directory next to config.toml. TUIOS reads them in name order, so 10-theme.toml comes before 50-hosts.toml. You do not need to name them in config.toml.

Which file wins

TUIOS reads the files in this order. A later file wins over an earlier file.

  1. The files in the include list, in list order. An included file's own includes come before it.
  2. The files in config.d, in name order.
  3. config.toml.

config.toml comes last and wins. It holds only the keys that you changed. On the first start, TUIOS writes a config.toml with comments and no settings. The one exception is [startup]: TUIOS writes tiled = true and daemon = true there, unless another file sets them. Each change from TUIOS adds or changes only the key that you changed. So an included file applies everywhere except where you set a value of your own.

How the files merge

  • Tables merge key by key, at every depth. [hosts.NAME] tables merge by name, so each file can add its own hosts.
  • For a single value, the later file wins.
  • An array of values replaces the earlier array. It does not add to it. For example, a later new_window = ["ctrl+t"] replaces the earlier keys of new_window.
  • An array of tables, such as [[keybindings.command]], merges entry by entry. TUIOS never replaces it whole. A later entry matches an earlier entry by name when both have a name, and by key when they do not. A matched entry merges key by key. An entry that matches nothing goes at the end.

A relative file path in an included file, such as a [plugins] dirs entry or a token_file, is relative to that file.

Remove an entry from an earlier file

To remove an array entry that an earlier file sets, add an entry with the same name or key and disabled = true. TUIOS removes both entries.

# config.d/50-work.toml: drop the deploy command from shared.toml on this machine
[[keybindings.command]]
name = "deploy"
disabled = true

What is not an error

TUIOS shows a warning and continues in these cases:

  • An include names a file that does not exist. TUIOS skips it, so one machine can include a file that only it has. With ?, there is no warning.
  • An include makes a cycle, or a file includes itself. TUIOS reads each file one time.
  • TUIOS cannot read an optional include or a config.d file, such as a link that points to itself. TUIOS skips it.
  • An include key is below a table header.

These stop the load, the same as an error in config.toml:

  • A file that exists and has a TOML error.
  • A required include that TUIOS cannot read.
  • An include that names a directory. Put a directory of files in config.d instead.

Find where a key comes from

tuios config files                     # every file, in merge order
tuios config origin                    # every key and the file that sets it
tuios config origin appearance.theme   # one key, and the keys under it

tuios config files marks a file that TUIOS cannot write as read-only. tuios config origin also names the earlier files that set the same key. Their values lose.

$ tuios config origin appearance
appearance.border_style  config.toml  (also set in shared.toml)
appearance.theme         shared.toml

Both commands take --json.

Hot reload

TUIOS watches every file it reads: config.toml, each included file, each file in config.d, and the config.d directory itself. When a file is a link, TUIOS also watches the file that the link points to. A save to any of these files applies at once. An included file that was missing applies when you make it, if its directory exists.

How TUIOS saves a change

The settings page, tuios set-config, the keybind manager, tuios keybinds unbind, tuios hosts add and tuios plugins write the config. They write only the keys that you changed. They never copy the other files into config.toml. A save keeps the new values of a file that changed on disk while you worked.

Each change goes to one file:

  • A key that a file sets goes to the last file that sets it.
  • A new entry in a table of entries, such as a new [hosts.NAME], goes to the last writable file that has entries in that table.
  • Any other new key goes to config.toml.
  • A removed key is removed from each file that sets it.

TUIOS changes only the lines of the key. The comments, the blank lines and the line endings of the file stay. A comment above a table stays with that table. TUIOS never writes a file again from its values. When TUIOS cannot write a change into the lines of an included file, it writes the change to config.toml and tells you. When it cannot remove a key that way, the save fails and the message names the file.

Read-only files

TUIOS never writes a read-only file. This includes a file that Nix or home-manager links in from the store.

  • When a read-only file sets the key, TUIOS writes the change to config.toml and tells you.
  • When config.toml is read-only too, TUIOS writes the change to the last writable file that config.toml includes. That file must come after every file that sets the key. If there is no such file, the save fails and the message names the file to change.
  • TUIOS cannot remove a key from a read-only file. To remove an array entry, TUIOS writes a disabled = true entry to a writable file.

TUIOS does not make a missing include. When config.toml is read-only, make the writable file yourself, and put it last in the include list:

touch ~/.config/tuios/local.toml

If TUIOS can write no file, a save fails with this message:

tuios cannot write config.toml or any file it includes. Make config.toml writable, or include a writable file

Clean up an old config.toml

An older TUIOS wrote every key into config.toml. That file wins over every other file, so it hides them. Run tuios config prune to remove the keys that have their default value.

tuios config prune --dry-run   # show the keys, change nothing
tuios config prune             # list the keys, ask, then change the file
tuios config prune --yes       # do not ask

The command lists the keys that another file sets, because their value changes after the prune. A run with no terminal needs --yes. The [startup] keys stay. The comments and the include list stay.

tuios config reset writes the first-start config.toml again. It keeps your include list and lists the other files that still apply.

Example: a dotfiles layout

One shared file in a dotfiles repository, one file per machine, and a config.toml that TUIOS owns:

~/.config/tuios/
├── config.toml          # written by TUIOS: only your local changes
├── shared.toml          # link to ~/dotfiles/tuios/shared.toml
└── config.d/
    └── 50-hosts.toml    # the hosts of this machine, not in the repository
# config.toml
include = ["shared.toml", "?work.toml"]
# shared.toml
[appearance]
theme = "nord"
border_style = "rounded"

[keybindings]
leader_key = "ctrl+a"
# config.d/50-hosts.toml
[hosts.build]
addr = "build.lan"

work.toml is optional, so a machine without it gets no warning. A new host from tuios hosts add goes to 50-hosts.toml, because that is the last writable file with [hosts] entries.

Nix and home-manager

There are two setups:

  • TUIOS owns config.toml. Let Nix write an included file, such as nix.toml, and put include = ["nix.toml"] in config.toml. A change in the app goes to config.toml and wins over the Nix value.
  • Nix owns config.toml. Let Nix write config.toml with include = ["local.toml"] as the last entry. Make local.toml yourself, as a normal file. A change in the app goes to local.toml.

In the second setup, config.toml comes after local.toml and wins. A key that the Nix config.toml sets cannot change from the app, and the save fails. Put the settings that you change in the app in an included file, not in config.toml.

On this page