WayfireWM / wf-config

A library for managing configuration files, written for wayfire

Home Page:https://wayfire.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Increase flexibility of compound options.

AhoyISki opened this issue · comments

Currently, the way compound options are done, you have to type something like this:

[section]
option_1_key1 = value
option_2_key1 = value
...

option_1_key1 = value
option_2_key2 = value
...

For the options available in the default wayfire plugins, this isn't too much of a problem, but for compound options with more than 2 options, it could be quite cumbersome and inelegant to have to write the key1, key2, etc, for every single option. Instead, why not let the user also type something like this:

[section]

[.key1]
option_1 = value
option_2 = value
...

[.key2]
option_1 = value
option_2 = value
...

I'm not advocating for the replacement of the original way of doing this, but having that second option would be pretty nice, and it also works well with established INI formating.

Moving this to wf-config as currently it is the place where the config file parsing is implemented.

Generally, I (and many others seem to) agree with you that this is cumbersome. However, I have two objections:

  1. The syntax you mentioned seems very close to the 'object' syntax. objects are for example outputs, where you define a config section of the type [output:<something>] and then you have the same options for each object. While objects have their perfectly valid uses, I think that (ab)using objects to represent lists like compound options is a bad design, as it mixes options and sections.

  2. I am also unsure whether piling more things on top of our INI syntax is a good idea. Maybe someone should develop an alternative Wayfire config backend with YAML/JSON/whatever format, port WCM to it (I think many of the Wayfire users find WCM a very useful piece of software) and then merge it upstream as a better alternative.

The ini file format seemed a good fit in the early days of Wayfire, as indeed all configuration options were simple values to be fed to the plugins. Nowadays, with objects and compound options it looks more and more like a little bit more complex config format would be preferable.

commented

It probably needn't (and shouldn't) be much more complex. I think adding a simple namespace syntax will alleviate many of its limitations.

[section]
key = value
namespace {
    key = value
}
guid = {01234567-89AB-CDEF-FEDC-BA9876543210}

Notice the equal sign in guid = { treats braces as part of the value string, whereas a brace after the name denotes the start of a namespace.
You could have such values accessible with path style syntax: namespace/key

For example, the command plugin:

[command]
repeatable_binding_volume_up = KEY_VOLUMEUP
command_volume_up = amixer set Master 5%+
repeatable_binding_volume_down = KEY_VOLUMEDOWN
command_volume_down = amixer set Master 5%-

to this (if "prefix" means what it should):

[command]
commands {
    volume_up = amixer set Master 5%+
    volume_down = amixer set Master 5%-
}
repeatable_bindings {
    volume_up = KEY_VOLUMEUP
    volume_down = KEY_VOLUMEDOWN
}

Or grouping by command (which keeps the tuple nature):

[command]
volume_up {
    command = amixer set Master 5%+
    repeatable_binding = KEY_VOLUMEUP
}
volume_down {
    command = amixer set Master 5%-
    repeatable_binding = KEY_VOLUMEDOWN
}

Parsing is simple if strict with this style of line breaks, and can be described ABNF style:

namespace-start = name "{" EOL
leave-namespace = "}" EOL

I haven't yet had a good look at the current parser code used, but the extra logic in parsing this should be very simple. The only additional state that would be needed is a string that keeps track of the namespace. For the example:

[section]                      |
key = value                    |
namespace {                    | /namespace
    key = value                | /namespace
}                              |
guid = {01234567-89AB-CDEF}    |

And if you need to do so in the future, nesting can be added with ease:

[section]                      |
key = value                    |
namespace {                    | /namespace
    key = value                | /namespace
    key2 = val2                | /namespace
    nested {                   | /namespace/nested
        key = valueA           | /namespace/nested
        key2 = val2A           | /namespace/nested
        val_id = {01234567}    | /namespace/nested
    }                          | /namespace
    key3 = val3                | /namespace
}                              |
key2 = val2                    |

The key name could be section + state + '/' + name

I think the hjson backend developed by @marcusbritanicus is the way forward: https://gitlab.com/wayfireplugins/wf-config-hjson

EDIT: or a similar plugin, there is nothing too special about hjson, but I personally find it rather nice.

There's no need to reinvent the wheel (our own config syntax, parsing, etc.)

commented

Hjson is also a reinvented wheel, but in this case it doesn't seem too bad. I just did a test running ini2hjson on my wayfire.ini and I can follow the contents of the file very well, but I may be biased because of all the years I spent in C/C++.

Maybe there is also enough flexibility there to replace the XML files with Hsjon to avoid multiple configuration formats unnecessarily.