helix icon indicating copy to clipboard operation
helix copied to clipboard

XDG support on windows

Open dsisnero opened this issue 2 years ago • 2 comments

I am a windows user and I set the XDG environment variables. On windows, helix doesn't honor these environment variables so it always goes to %APPDATA%, My %APPDATA% drive, is full so I changed XDG directories to a different drive. I think that if the variables are set, even on windows, should allow to follow XDG directories and if not should revert back to %APPDATA%

dsisnero avatar Apr 13 '23 19:04 dsisnero

I'd suggest opening an issue to the upstream library: https://github.com/lunacookies/etcetera

kirawi avatar Apr 28 '23 03:04 kirawi

The etcetera library is working as intended. The problem is that helix uses choose_base_strategy function from etcetera which uses Windows' Known Folder API on Windows and XDG on Unix. If you want to instead use XDG variables on Windows too, you can call base_strategy::Xdg::new() instead of choose_base_strategy() here: https://github.com/helix-editor/helix/blob/23.03/helix-loader/src/lib.rs#L110

utkarshgupta137 avatar May 15 '23 18:05 utkarshgupta137

Hi. Any updates on this? IMO, the config locations should be consistent across OS, when the XDG_ environment variables are set.

henriqpsantos avatar May 26 '23 09:05 henriqpsantos

The XDG and Windows strategies can't co-exist using the types in the crate. XDG would probably have to be implemented manually for Windows so it can fall back to the Windows strategy when the environment variables aren't set.

kirawi avatar Jun 02 '23 21:06 kirawi

The existence of the XDG variables isn't supposed to determine whether or not the XDG spec is followed i.e. ~/.config should be checked if $XDG_CONFIG_HOME isn't defined. You need to decide if the XDG or the Windows spec will be the primary location for Helix.

So the flow can be like this:

  • Check Xdg::config_dir() & use it if it exists
  • Check Windows::config_dir() & use it if it exists
  • If you want Xdg spec to be the primary location, then Helix should create Xdg::config_dir(), otherwise Windows::config_dir()

utkarshgupta137 avatar Jun 03 '23 05:06 utkarshgupta137

The Windows spec should be the default since it's what most users will expect (i.e https://github.com/helix-editor/helix/issues/7084). According to the spec, I don't think I'm wrong either. It says that if the environment variables aren't defined, it should fall back to the system default, which would be defined by the Windows spec.

i.e.

If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME/.config should be used.

kirawi avatar Jun 03 '23 15:06 kirawi

I think if XDG variables are set, that should be the default. Otherwise, there is no way to change it. If XDG variables aren't set, revert to windows spec and it doesn't affect normal windows users

On Sat, Jun 3, 2023 at 9:53 AM Kirawi @.***> wrote:

The Windows spec should be the default since it's what most users will expect (i.e #7084 https://github.com/helix-editor/helix/issues/7084). According to the spec, I don't think I'm wrong either. It says that if the environment variables aren't defined, it should fall back to the system default, which would be defined by the Windows spec.

— Reply to this email directly, view it on GitHub https://github.com/helix-editor/helix/issues/6747#issuecomment-1575034544, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAABQRMXIFOLKIQPDUCLXITXJNMXBANCNFSM6AAAAAAW5PTFSU . You are receiving this because you authored the thread.Message ID: @.***>

dsisnero avatar Jun 03 '23 16:06 dsisnero

Yes, that is what I mean.

kirawi avatar Jun 03 '23 20:06 kirawi

The Windows spec should be the default since it's what most users will expect (i.e #7084).

If you want Windows to be the primary/recommended location, then flow should be:

  • Check Windows::config_dir() & use it if it exists
  • Check Xdg::config_dir() & use it if it exists
  • Use Windows::config_dir()

It shouldn't just be use the location provided by $XDG_CONFIG_HOME if it is defined. You should also check ~/.config if $XDG_CONFIG_HOME isn't defined. Otherwise, if a user who isn't aware of XDG variables (which is likely the vast majority of Windows users), suddenly defines or stops defining $XDG_CONFIG_HOME, their configs would stop working.

According to the spec, I don't think I'm wrong either. It says that if the environment variables aren't defined, it should fall back to the system default, which would be defined by the Windows spec.

The defaults are defined by the XDG spec itself, as you quoted yourself:

If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME/.config should be used.

It doesn't say that the OS should specify the default.

utkarshgupta137 avatar Jun 04 '23 06:06 utkarshgupta137

It is a little ambiguous as it could also mean "equivalent," and most implementations interpret it as such (i.e. Racket or GTK glib). A hard-coded default would be pretty useless and not user-friendly (what benefit is there to forcing users to use these unix paths instead of the Windows paths that they already know?). The flow should be this:

  • If there is a set non-empty XDG environment variable and it points to a valid absolute path, it should be used.
  • Otherwise, use the Windows known files specification to find the OS-defined folder.

kirawi avatar Jun 04 '23 15:06 kirawi

It is a little ambiguous as it could also mean "equivalent," and most implementations interpret it as such (i.e. Racket or GTK glib). A hard-coded default would be pretty useless and not user-friendly (what benefit is there to forcing users to use these unix paths instead of the Windows paths that they already know?). The flow should be this:

* If there is a set non-empty XDG environment variable and it points to a valid absolute path, it should be used.

* Otherwise, use the Windows known files specification to find the OS-defined folder.

Hmmm. I don't use CLI on Windows, so I don't have strong opinions. I assumed it worked similarly to macOS because CLIs/TUIs on macOS follow "proper" XDG spec i.e. they default to ~/.config & such and fallback to ~/Library/Application Support only if they supported that location in the past.

utkarshgupta137 avatar Jun 05 '23 13:06 utkarshgupta137

I like how WezTerm handles this problem, and it also sounds more intuitive to me -- working from more specific to more general in terms of priority: 1- CLI argument 2- Program-specific environment variable (i.e. $HELIX_CONFIG_DIR) 3- File on the same directory as executable 4- XDG_ environment variables 5- $HOME\.config\helix.toml 6- $HOME\.helix.toml Add a step 4.5 or replace 5/6 for windows, using %APPDATA% folders instead of $HOME. The way that I find more logical is to merge the first existing (valid path) file with the global config.

It is a little ambiguous as it could also mean "equivalent," and most implementations interpret it as such (i.e. Racket or GTK glib). A hard-coded default would be pretty useless and not user-friendly (what benefit is there to forcing users to use these unix paths instead of the Windows paths that they already know?). The flow should be this:

* If there is a set non-empty XDG environment variable and it points to a valid absolute path, it should be used.

* Otherwise, use the Windows known files specification to find the OS-defined folder.

IMO hard-coded paths such as $HOME or %APPDATA% should only be used as a last priority.

henriqpsantos avatar Jun 05 '23 14:06 henriqpsantos

https://github.com/helix-editor/helix/pull/2135 for that. This issue is specifically about supporting XDG on Windows.

kirawi avatar Jun 05 '23 20:06 kirawi

I'm on windows. The standard, in my opinion, should be to support them for consistency across platforms. The issue for me is that the config directory on windows is hard-coded or must be specified by way of a CLI argument (or a symlink, but that is supported anyway).

henriqpsantos avatar Jun 06 '23 09:06 henriqpsantos

Yes, the linked PR covers that. Even so, that PR does not support XDG on Windows. So this issue can be seen as an extension of that. To rephrase, this issue is specifically about using the XDG environment variables to find the config folders within the scope of the current system. What you're talking about falls outside of this.

kirawi avatar Jun 06 '23 15:06 kirawi

https://github.com/helix-editor/helix/issues/6747#issuecomment-1576847335

Hmmm. I don't use CLI on Windows, so I don't have strong opinions. I assumed it worked similarly to macOS because CLIs/TUIs on macOS follow "proper" XDG spec i.e. they default to ~/.config & such and fallback to ~/Library/Application Support only if they supported that location in the past.

https://github.com/helix-editor/helix/issues/6747#issuecomment-1574671838

So the flow can be like this: * Check Xdg::config_dir() & use it if it exists * Check Windows::config_dir() & use it if it exists * If you want Xdg spec to be the primary location, then Helix should create Xdg::config_dir(), otherwise Windows::config_dir()

This seems to most obvious solution.

It's what I expect. I pull my dotfiles into my MSYS2 environment and everything should work. (Even vim can follow XDG 😄 )

go2null avatar Dec 19 '23 17:12 go2null

What is the status on this? How can I change my config in runtime directories on windows without using a command line switch?

dsisnero avatar Jan 17 '24 00:01 dsisnero

The behavior for Mac is also a bit weird. Usually if configuration uses system-native config paths then it is ~/Library/Application Support/myapp on Mac, %APPDATA%/myapp on Windows, and ~/.config/myapp on Linux (this is what the dirs crate does). Or, ~/.config/myapp is used on all three platforms, which isn't uncommon for CLI apps.

It is kind of unusual that Helix uses AppData on WIndows but ~/.config on Mac. IMO either the system native path should be used on all platforms (i.e., change the Mac default location to ~/Library/Application Support), or use ~/.config on all platforms (i.e., change Windows to accept this).

Or, since deprecating config locations is unlikely, allow either native locations or ~/.config and error (or at least warn) if config exists in both.

tgross35 avatar Jan 19 '24 22:01 tgross35

According to the upstream library etcetera, the convention is to use XDG for cli apps on all non-Windows platforms: https://docs.rs/etcetera/latest/etcetera/base_strategy/fn.choose_base_strategy.html

We could probably check if other editors like Vim/Kakoune do the same.

kirawi avatar Jan 19 '24 23:01 kirawi

I think the current config is consistent with neovim (On Mac it uses ~/.config, and it looks like WIndows is AppData https://jdhao.github.io/2018/11/15/neovim_configuration_windows/). Vim is stubborn and always ~/.vimrc (list of XDG support https://wiki.archlinux.org/title/XDG_Base_Directory).

I think many CLI apps that predate Rust usually use ~/.config or ~/.appname on all platforms, such as git. A lot of Rust apps seem to punt to dirs, which does AppData on Windows and ~/Libraries/Application Support on Mac, such as evcxr and zoxide. Alacritty and fd do the same as Helix link1 link2, but Wezterm is always ~/.config link.

What a mess... In any case, I feel that it isn't a bad idea to check ~/.config on Windows too and at least warn the user that config isn't read from that location.

tgross35 avatar Jan 19 '24 23:01 tgross35

According to the upstream library etcetera, the convention is to use XDG for cli apps on all non-Windows platforms: https://docs.rs/etcetera/latest/etcetera/base_strategy/fn.choose_base_strategy.html

We could probably check if other editors like Vim/Kakoune do the same.

Again, etcetera only contains a helper function for this pattern, since it seems to be a common pattern. If you want, you can use Xdg directly.

utkarshgupta137 avatar Jan 22 '24 11:01 utkarshgupta137

As long as the option is there to change it without a command line switch and so it is not hardcoded. Just pick APPDATA or HOME/.config as fallback but give the ability to use XDG if that is set. I think it should fall back to os convention but not as long a we can change it with ENV variable it doesn't matter too much

dsisnero avatar Jan 22 '24 14:01 dsisnero