-
-
Notifications
You must be signed in to change notification settings - Fork 127
Description
Because YAML anchors do not allow specialising a child node of an anchored-in tree, we need to instead roll our own joint of merging user-specific changes via inheritance.
Use case
- I have three profiles (one is
default
which is what contour supplies, then I havemaster
andlight
which are two themed customised things). When Contour comes with changes to the default schema, it's a PITA to upgrade the other two profiles because a simple diff tool just can't help as my custom profiles are always additions versus the default. - Automatic update of config files will get messy if entire sub-trees need update which may or may not have some keys.
Proposal
1. Hardcode for each top-level listing map (e.g. profiles
and colour_schemes
) the __default__
key. This is the key where Contour's "official" configuration should be put (e.g., in the contour generate config ...
output).
This will make updates to the official configuration easier, as we need to only update one well-defined and reserved tree.
2. (Optionally) Introduce the __inherits__
or __base__
(I'm purposefully using some reserved underscore mangling yadda here) which takes as an argument a single (or multiple?) other named entity from the same tree: e.g., a profile might inherit another profile.
This could make custom configurations more composable (a'la CMakePresets), but might make the implementation unnecessarily messy!
3. (Irrespective of whether 2. is implemented...) when resolving a specific <top-level-tree-structure>.<user-defined-identifier>.whatever.blah
key, use the following logic (in this example, rolling with the profiles, but the colour_schemes
is the same yadda!):
- If
profiles.foo.whatever.blah
exist, resolve to that value. - If
profiles.foo.whatever.blah
does not exist, butprofiles.<T>.whatever.blah
exists, resolve to that.- If entities might inherit from a single but user-specified base "class":
<T>
is that - If entities might inherit from a list of multiple user-specified base classes:
<T>
is the last in that list - If entities might not user-customisable inherit,
<T>
is__default__
- If entities might inherit from a single but user-specified base "class":
- If no such value exists, fall back to Contour's baked-in default and emit a warning
4. When new keys are added to the schema (a.k.a. when the warning mentioned above is emitted), optionally offer merging such changes into the __default__
base "class". This way, it will also automatically be inherited into every user-customised profile.
Example
With this, I could achieve the following way of customisation which would make my profile YAML easier to read and edit:
profiles:
__default__:
# All the hardcoded b.s.
...
master:
# __base__: "__default__" (implicitly?)
font:
size: 14
regular:
family: "JetBrainsMono"
permissions:
capture_buffer: allow
colors: "dracula"
colour_schemes:
__default__:
# Similarly, the default stuff...
...
dracula:
# __base__: "__default__"
default:
background: "#282a36"
foreground: "#f8f8f2"
Why not YAML anchors instead?
default:
font:
regular: "JetBrains Mono"
size: 12
my_profile: &<< default # I have no fucking idea about the syntax
font:
size: 14
# Expectation: "regular" stays the same
YAML anchors do not support the use case described in this ticket, and the Expectation:
line above does NOT hold...