symconf.matching module¶
Generic combinatorial name-matching subsystem
Config files are expected to have names matching the following spec:
<style>-<scheme>.<config_pathname>
config_pathname
: refers to a concrete filename, typically that which is expected by the target app (e.g.,kitty.conf
). In the context ofconfig_map
in the registry, however, it merely serves as an identifier, as it can be mapped onto any path.scheme
: indicates the lightness mode (“light” or “dark”)style
: general identifier capturing the stylizations applied to the config file. This is typically of the form<variant>-<palette>
, i.e., including a reference to a particular color palette.
For example
soft-gruvbox-dark.kitty.conf
gets mapped to
style -> "soft-gruvbox"
scheme -> "dark"
pathname -> "kitty.conf"
- class symconf.matching.Matcher[source]¶
Bases:
object
- get_file_parts(paths)[source]¶
Split pathnames into parts for matching.
Pathnames should be of the format
<style>-<scheme>.<config_pathname>
where
style
is typically itself of the form<variant>-<palette>
.- Return type:
list
[FilePart
]
- match_paths(paths, prefix_order)[source]¶
Find and return FilePart matches according to the provided prefix order.
The prefix order specifies all valid style-scheme combos that can be considered as “consistent” with some user input (and is computed external to this method). For example, it could be
[ ('none', 'none') ('none', 'dark') ]
indicating that either
none-none.<config>
ornone-dark.<config>
would be considered matching pathnames, with the latter being preferred.This method exists because we need a way to allow any of the combos in the prefix order to match the candidate files. We don’t know a priori how good of a match will be available, so we consider each file for each of the prefixes, and take the latest/best match for each unique config pathname (allowing for a “soft” match).
Checking for matches
When thinking about how best to structure this method, it initially felt like indexing factors of the FileParts would make the most sense, preventing the inner loop that needs to inspect each FilePart for each element of the prefix order. But indexing the file parts and checking against prefixes isn’t so straightforward, as we’d still need to check matches by factor. For instance, if we index by style-scheme, either are allowed to be “any,” so we’d need to check for the 4 valid combos and join the matching lists. If we index by both factors individually, we may have several files associated with a given key, and then need to coordinate the checks across both to ensure they belong to the same file.
In any case, you should be able to do this in a way that’s a bit more efficient, but the loop and the simple conditionals is just much simpler to follow. We’re also talking about at most 10s of files, so it really doesn’t matter.
- Parameters:
pathnames
scheme
style
prefix_order (
list
[tuple
[str
,str
]])strict
- Return type:
list
[FilePart
]
- prefix_order(scheme, style, strict=False)[source]¶
Determine the order of concrete config pathname parts to match, given the
scheme
andstyle
inputs.There is a unique preferred match order when
style
,scheme
, both, or none areany
. In general, whenany
is provided for a given factor, it is best matched by a config file that expresses indifference under that factor.- Return type:
list
[tuple
[str
,str
]]
- relaxed_match(match_list)[source]¶
Isolate the best match in a match list and find its relaxed variants.
This method allows us to use the
match_paths()
method for matching templates rather than direct user config files. In the latter case, we want to symlink the single best config file match for each stem, across all stems with matching prefixes (e.g.,none-dark.config.a
andsolarized-dark.config.b
have two separate stems with prefixes that could matchscheme=dark, style=any
query). We can find these files by just indexing thematch_path
outputs (i.e., all matches) by config pathname and taking the one that appears latest (under the prefix order) for each unique value.In the template matching case, we want only a single best file match, period (there’s really no notion of “config stems,” it’s just the prefixes). Once that match has been found, we can then “relax” either the scheme or style (or both) to
none
, and if the corresponding files exist, we use those as parts of the template keys. For example, if we matchsolarized-dark.toml
, we would also consider the values innone-dark.toml
if available. The TOML values that are defined in the most specific (i.e., better under the prefix order) match are loaded “on top of” those less specific matches, overwriting keys when there’s a conflict.none-dark.toml
, for instance, might define a general dark scheme background color, but a more specific definition insolarized-dark.toml
would take precedent. These TOML files would be stacked before using the resulting dictionary to populate config templates.- Return type:
list
[FilePart
]