Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: include keyword in configuration #796

Open
fwsmit opened this issue Dec 22, 2020 · 19 comments
Open

Feature: include keyword in configuration #796

fwsmit opened this issue Dec 22, 2020 · 19 comments
Labels

Comments

@fwsmit
Copy link
Member

fwsmit commented Dec 22, 2020

The include keyword would work as follows. On any line in the configuration file you could write include followed by a file name (this could also be changed to only before the first section. This file name can have a "/*" at the end to say that the entire content of a directory has to be included. When reading a config file, every time an include keyword is read, dunst will read the relevant file before continuing.

Example:

~/.config/dunst/dunstrc

# use manjaro theme
include /etc/xdg/dunst/themes/manjaro

# override certain colours of that theme
[urgency_normal]
    background = "#bbbbbb"

/etc/xdg/dunst/themes/manjaro

[urgency_normal]
    background = "#285577"
    foreground = "#ffffff"

This feature would be very useful for things like themes. Dunst could ship with a few default themes that can be enabled by just including them in your dunstrc. Other things like layouts and icon sets could be included this way as well.

@tsipinakis
Copy link
Member

Hm, the problem here is that the ini format is not really designed for such a functionality.

  • What would happen if a section is defined in both files? Merge them?
    • If a setting is included in both files which one takes precedent?
    • If, similarly, a setting is included in 2 included files which one takes precedent?

I think we would need to move the config to an entirely new language to achieve something like this cleanly.

@fwsmit
Copy link
Member Author

fwsmit commented Dec 24, 2020

Hm, the problem here is that the ini format is not really designed for such a functionality.

True, but I think it's possible to implement in a not too confusing way. They only thing that would be confusing here is that the include would be ignoring the section. This can be partially avoided by only allowing includes at the beginning and the end of the file.

This is very rough pseudocode of what it would look like.

struct settings;

void parsefile(file) {
        for(all lines) {
                if (isKey)
                        set(key, value, section);
                else if (isInclude)
                        parsefile(f);
        }
}

This would be equivalent to the, IMO harder to implement, c style includes where the contents of the file are just dumped in place of the include. If you do it this way you would have to allow duplicate sections (I don't know how they're currently handled).

To answer your questions:

What would happen if a section is defined in both files? Merge them?

Every section is just handled when the parser sees it. The variables get the value that is set last.

If a setting is included in both files which one takes precedent?

The last one. So if the example in my last comment, the background colour will be #bbbbbb.

If, similarly, a setting is included in 2 included files which one takes precedent?

The setting from the last included file.

I think we would need to move the config to an entirely new language to achieve something like this cleanly.

I hope I've shown you it's possible in ini format, although it's not standard of course.
Do you know a config language that would suit better for this? The big downside would of course be that all current configs will eventually have to be deprecated and replaced.

@tsipinakis
Copy link
Member

Sorry for the delay, this one fell through.

Do you know a config language that would suit better for this?

There was some talk of moving to yaml, but I can't find the issue with a quick github search, and either way I'm not sure how easy it is to handle from C.

I hope I've shown you it's possible in ini format, although it's not standard of course.

Indeed this looks like it could work, and since the feedback in #328 is that something like this is needed I'd accept a PR :).

@WhitePeter
Copy link
Contributor

WhitePeter commented Oct 2, 2021

While I was working on fixing the issues in #917 an idea popped into my head that could provide a viable alternative to an #include: drop-ins, i.e. $XDG_CONFIG_HOME/dunst/dunstrc.d/*.conf. They are very easy to implement with the approach taken in said PR. In the end those would just be appended to the respective "main" dunstrc in the parent directory.

Food for thought?

@WhitePeter
Copy link
Contributor

And even the include should not be too hard, I think.

@infokiller
Copy link

@WhitePeter drop-ins wouldn't support conditional includes, right?
My use case is to have one config that is shared across all your machines, and some tweaks per machine in separate files. I want to manage all these files in the same dotfiles repo, but using drop-ins would include all customizations in all machines.

@chrishoage
Copy link

The way I solve this (not related to dunst, but in general for all my configs) is to have different drop ins for different machines and then link the correct configs to the home directory.

Many configurations don't support conditional includes, so it was a solve I had to make for things like sxhkd and a bunch of other programs.

@infokiller
Copy link

I like to be able to git clone my dotfiles and have everything just work, and that all my machines use the same configuration files (possibly with different execution paths). I also like to be able to edit source files directly and avoid generated files.
This means my ideal solution for customizing stuff for each machine is to have conditional includes "natively" supported. Many don't support it, and further there are many that don't even support drop ins. In these cases, I can resort to other solutions (generate machine-specific configs from templates, linking the right file, etc.), but I find these solutions inferior.
So I think you can't beat conditional includes for the use case of per-machine customizations.

@chrishoage
Copy link

I agree, it would be nice if every project had rich support for configs that including conditions.

However I'm sympathetic to how complex conditional includes are. Configuration is typically quite simple parsing of values with little to no logic involved.

I feel putting the onus of my complex configuration needs on developers who maintain projects is unfair. I am happy to adopt solutions to fit my needs with out creating more complexity in upstream projects.

There are lots of dotfile management solutions which offer templates which have conditions which you can use to bootstrap machines, or any other number of methods.

As you mention - some projects don't support drop ins at all, so needing to handle this complex configuration some other way is basically a necessity.

@infokiller
Copy link

I appreciate the efforts of the developers and this is only my feedback. They are obviously free to spend their time however they want.
However, the config per machine issue is very common, especially since dunst has settings such as width, height, offset that are likely to change between monitors. So, this is not just one person's "complex configuration needs".
I think a solution that adds the ability to include my/file/$ENV_VAR is not complex and solves this use case well (i3/sway support this, for example).
This is not critical because there is a simple workaround (cat <conf1> <conf2> ... | dunst -conf -), but having the include mechanism that expands environment variables would be better.

@fwsmit
Copy link
Member Author

fwsmit commented Nov 14, 2021

I'd recommend using a dotfile manager like chezmoi. This will allow for a rich syntax for templates. I get that you don't want to use generated config files, but they don't have to be annoying when you integrate chezmoi with your editor. When I save a file from chezmoi in my editor, the changes automatically get applied.

@infokiller
Copy link

Thanks for the suggestion @fwsmit, I know chezmoi and many other dotfiles managers and template engines that can handle this as well, but for now the cat <conf1> <conf2> ... | dunst -conf - workaround is good enough and doesn't introduce another dependency for me.

@chrishoage
Copy link

Are includes still being considered now that drop-in configs have landed?

I have updated my dotfiles to use the drop-in config here chrishoage/dotfiles@0bfb118

As such I was able to restore my pywal generated theme! Thanks a ton for this work 🙂

However, in my opinion this is still a bit cumbersome, and could be greatly improved by allowing my to include the generated theme directly instead of needing to symlink it to the dropin directory.

e.g.

include ~/.cache/wal/dunst-colors.conf

[global]
# rest of config

This would be similar to how alacritty handles it, which slots in nicely with generated configs.

import:
  - ~/.cache/wal/alacritty-colors.yml

font:
  size: 11

Allowing includes would save a step of forcing a symlink.

Thanks again!

@fwsmit
Copy link
Member Author

fwsmit commented Mar 1, 2022

Good to hear that you like it. Includes would be a great addition. We have opted this time to not go for includes, because it takes a bit more time to get it right. It's definitely still an option for the future.

@bynect bynect removed this from the 1.7 milestone Mar 5, 2024
@bynect
Copy link
Member

bynect commented Mar 5, 2024

Hm, the problem here is that the ini format is not really designed for such a functionality.

* What would happen if a section is defined in both files? Merge them?
  
  * If a setting is included in both files which one takes precedent?
  * If, similarly, a setting is included in 2 included files which one takes precedent?

I think we would need to move the config to an entirely new language to achieve something like this cleanly.

I was wondering, doesn't this still apply to the drop ins files that are loaded right now?

@fwsmit
Copy link
Member Author

fwsmit commented Mar 8, 2024

Yeah, it's solved by just defining some kind of order. The last defined value will be used.

@bynect
Copy link
Member

bynect commented Mar 9, 2024

Yeah, it's solved by just defining some kind of order. The last defined value will be used.

Wait, so if there are multiple global sections only the last is used? Or are all sections used and the keys override each other?

@fwsmit
Copy link
Member Author

fwsmit commented Mar 9, 2024

They override each other iirc

@Heus-Sueh
Copy link

I would like this feature, it would make creating themes easier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants