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

Clobbers vim-only environment variables modifications #19

Open
Shados opened this issue Oct 29, 2019 · 5 comments

Comments

@Shados
Copy link

@Shados Shados commented Oct 29, 2019

I'm not sure how this happens, but direnv.vim appears to clobber environment variable values that are set only for the vim process (e.g. via env FOO=bar vim ... or vim being launched through a wrapper script).

From what I understand, direnv.vim just calls direnv to get the differing environment variables, which should be diffing against the environment it is launched in (and processes launched through :!{cmd} do inherit the vim environment, at least), and thus should return a set of environment variables that take into account values set only for the vim process... but it doesn't.

Instead, it is somehow returning a set of environment variables equivalent to what I get from running direnv in the parent shell of the vim process, rather than in the vim process itself. Any variables that are modified both by direnv and by some wrapper around vim will effectively have the vim-specific changes dropped (in my case, $PATH).

@zimbatm

This comment has been minimized.

Copy link
Member

@zimbatm zimbatm commented Oct 29, 2019

That can happen when direnv unloads (or reloads). When that happens is that direnv restores the original value of the environment variables. If any changes happened to that variable in the mean time, they will be lost.

For example you go into your project with the shell, which triggers a direnv load. Then start vim and somehow set the PATH to something else. Now if inside of vim you reload, the PATH will be restored to the original value (and then changed again in the case of a reload).

@Shados

This comment has been minimized.

Copy link
Author

@Shados Shados commented Oct 29, 2019

Ahhh, OK, I think I see: the direnv process launched by vim picks up on the DIRENV_ variables having been set, so it knows that direnv is already loaded. Then, a later reload functions by internally restoring to a saved initial state (which is from the shell, as it didn't save the initial vim environment state, because it was already in a direnv session), applying the modified envrc changes on top of that, and exporting any changed variables back out again?

That's really quite unfortunate. There are some cases in which I do need PATH modified for vim specifically, and would also like to pick up on direnv modifications to PATH =/. I guess this is generally a problem in any case where an environment variable is modified after direnv has loaded?

I think a solution that reasonably preserves user intent can be implemented for array-like variables like PATH, but I'm not sure there's a good solution in general. It might at least be nice to make it configurable (per envrc) whether modified variables are clobbered on a reload or not.

@zimbatm

This comment has been minimized.

Copy link
Member

@zimbatm zimbatm commented Oct 29, 2019

Yes I think you understand the problem now and also see that there is no obvious solution.

I think the best is to treat those variables as reserved and push the PATH changes to the .envrc as it's going to be more generally applicable. What type of PATH changes does vim need to do?

@Shados

This comment has been minimized.

Copy link
Author

@Shados Shados commented Oct 30, 2019

I have some ridiculous Nix stuff for configuring vim, and one aspect of that is providing external tools to vim plugins that rely on them. In many cases, it is possible to exactly point the plugins to the tool paths via a plugin configuration option, but in others they just rely on the tools being present in PATH.

I could patch the latter type of plugins to take binary paths via config options, of course, but there are also cases where I want specific tools available within the vim environment for non-plugin purposes (e.g. for use with :!{cmd} or :terminal), and I don't necessarily want those tools polluting my global environment.

@zimbatm

This comment has been minimized.

Copy link
Member

@zimbatm zimbatm commented Nov 10, 2019

The only solution I can think of would be to wrap vim to make sure direnv is unloaded before it enters vim similarly to the tmux solution. That way, vim can change the PATH, and then load the direnv plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.