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

Load configuration from XDG_CONFIG_DIRS #4506

Open
mitchellh opened this issue Jan 3, 2025 · 8 comments · May be fixed by #4845
Open

Load configuration from XDG_CONFIG_DIRS #4506

mitchellh opened this issue Jan 3, 2025 · 8 comments · May be fixed by #4845
Milestone

Comments

@mitchellh
Copy link
Contributor

Discussed in #4477

Originally posted by vikanezrimaya January 3, 2025
I want to be able to drop a system-wide config for Ghostty into /etc/xdg. XDG_CONFIG_DIRS is a variable listing additional locations for config files that could be checked if the appropriate config in $XDG_CONFIG_HOME/~/.config is not found, and by default it includes /etc/xdg (at least on my distribution of choice).

If ghostty would respect this directory (by either loading this config if no config exists in the home directory, or loading it before the user config, allowing user to override system-wide defaults), that would be nice. It looks like ghostty creates an empty default config if it doesn't exist in the home directory, so perhaps the second option is the most appropriate.

Solution

We should load from both XDG_CONFIG_DIRS and XDG_CONFIG_HOME and override along the way.

@jcollie
Copy link
Collaborator

jcollie commented Jan 3, 2025

For anyone that works on this, consider creating an iterator interface similar to the LocationIterator in src/config/theme.zig that iterates through all of the possible locations in order of preference (including the macOS Application Support directory). Eventually we'll want to include Windows' equivalent locations.

@danudey
Copy link
Contributor

danudey commented Jan 3, 2025

It's worth noting that, per the spec, $XDG_CONFIG_DIRS can be a colon-delimited array of paths (similar to PATH). Technically this means that we should check each of the directories specified there (if there are more than one) for config files.

Currently the code in internal_os.xdg.dir() seems to assume:

  1. That the directories are a subdirectory of $HOME
  2. That there's only one going to be one directory in the environment variable passed in
  3. That you only want one directory returned.

I think it's worth deciding if ghostty should just use the first directory in $XDG_CONFIG_DIRS or if the xdg directory lookups should return an array of zero or more directory paths based on what's in the environment variable provided.

Forgot to add: possibly using an external cross-platform library like known-folders is the right call here, but they seem to assume just one configuration directory and not multiple.

@mitchellh
Copy link
Contributor Author

My expectation was we'd read all the directories. I agree that with @jcollie that the proper approach is to implement an iterator for this to avoid unnecessary allocations.

@jcollie
Copy link
Collaborator

jcollie commented Jan 3, 2025

So to be a little more specific, we need an iterator that returns these directories in this order:

  1. $XDG_CONFIG_HOME/ghostty iff $XDG_CONFIG_HOME is set
  2. $HOME/.config/ghostty iff $XDG_CONFIG_HOME is not set
  3. $HOME/Library/Application Support/com.mitchellh.ghostty iff macOS
  4. %APPDATA%/ghostty (TBD) iff Windows
  5. $dir/ghostty foreach : separated dir in $XDG_CONFIG_DIRS

Or should we look at $XDG_CONFIG_DIRS before the macOS/Windows specific directories?

@mitchellh
Copy link
Contributor Author

I would simplify the problem to start by creating an iterator on its own that just iterates XDG_CONFIG_DIRS and then build a more complex iterator around that (nest them). That's a pattern we've done before and it simplifies the problem.

For XDG_CONFIG_DIRS, we would want to load those before XDG_CONFIG_HOME.

Also note in your list that step 2 is redundant, because that's the default XDG_CONFIG_HOME path as specified by the spec so 1 and 2 are the same.

@vikanezrimaya
Copy link

So to be a little more specific, we need an iterator that returns these directories in this order...

@jcollie If the final config will be a composite of all existing configs, then I believe to allow user to override system-wide values, the directories you mentioned need to be returned in the reverse order:

  • Load system-wide configs from $XDG_CONFIG_DIRS in reverse order (i.e. the last directory in the list is loaded first as the lowest-priority config, and every directory before it can override the values it sets)
  • Load home configs from $XDG_CONFIG_HOME/$HOME/.config/whatever other operating systems use, overwriting values from system-wide configs loaded and composited above

@jcollie
Copy link
Collaborator

jcollie commented Jan 4, 2025

So to be a little more specific, we need an iterator that returns these directories in this order...

@jcollie If the final config will be a composite of all existing configs, then I believe to allow user to override system-wide values, the directories you mentioned need to be returned in the reverse order:

When looking for a single config file, the first one found "wins" right now. So if both ~/.config/ghostty/config and /etc/xdg/ghostty/config exist only one would be loaded. To load/merge multiple files they would need to be specified using a config-file entry.

@jcollie
Copy link
Collaborator

jcollie commented Jan 4, 2025

From the XDG spec

$XDG_CONFIG_DIRS defines the preference-ordered set of base directories to search for configuration files in addition to the $XDG_CONFIG_HOME base directory. The directories in $XDG_CONFIG_DIRS should be separated with a colon ':'.

If $XDG_CONFIG_DIRS is either not set or empty, a value equal to /etc/xdg should be used.

The order of base directories denotes their importance; the first directory listed is the most important. When the same information is defined in multiple places the information defined relative to the more important base directory takes precedent. The base directory defined by $XDG_DATA_HOME is considered more important than any of the base directories defined by $XDG_DATA_DIRS. The base directory defined by $XDG_CONFIG_HOME is considered more important than any of the base directories defined by $XDG_CONFIG_DIRS. 

@mitchellh mitchellh added this to the 1.0.2 milestone Jan 4, 2025
@mjrochford mjrochford linked a pull request Jan 9, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants