Getting direnv.vim to work properly #398
Replies: 2 comments 4 replies
-
|
This is not cleanly solveable with nixCats as it is. I am honestly not really sure how this could be solveable at all from within a wrapper script for any program, not just nvim. At least not cleanly. It might be, but I am not sure how. Basically, the plugin issues an event, and you would need to restore the environment from nvim after that event. But to do that, you have to know all the things that could be in that environment. NixCats allows you to provide arbitrary arguments to makeWrapper, so there isn't exactly a great way to get all the things that were added, its not just PATH additions, someone could theoretically change anything about the environment of the launched nvim. Maybe it would be possible to printenv both at the start and end of the wrapper and find the difference, but then you would be reimplementing half of direnv in order to work around direnv. Maybe a second wrapper script can be made which is designed to be sourced and provide everything but do nothing else? The problem with either of those would be, you can't then just source that from within nvim, you would need to get direnv to source that. Because nvim can't edit the environment of the shell that called it. I guess it might be worth asking if a new nix wrapper generator can be created that does this environment editing directly within nvim? But also, Im not sure that would even solve it, it still changes the environment without re-running any other config, which would probably still overwrite the changes even if done within your nvim config. It probably removes things added by mason even, I would assume. Is there a global config for direnv? I haven't used it much, is there a global config for it that lets you add extra things to any shell you enter? Because if not, if you wanted to add that stuff back you would need to add whatever packages to every single shell config. On top of that, it honestly feels like a bug in direnv. Direnv works by running the stuff in a subshell and then propagating that to the host. It doesn't directly run in the host shell. When you swap over shells to a different one, shouldn't it be able to undo its modifications, rather than just setting the shell to its exact state from prior to the direnv command? This could happen with a lot of things. There is a lot of stuff in nixpkgs wrapped simply for functionality. If you wanted to keep any of those running through multiple direnv calls, you would need to solve this problem. But text editors are likely to be the most obvious. But say, for example, you wrapped npm-watch. If you then changed direnv like this, the wrapped npm-watch that is running would also break. Is there a way to rewrite the direnv.vim plugin to make it so the new direnv goes on top of the current shell rather than replacing it? Replacing it is obviously ideal, but unless they fix that in direnv, I would think that stacking any extra ones on top of the first would be the next best option. Or, maybe you just make the wrapper script check at the start if it is in a direnv shell, and if so, cancel it before entering nvim and then restarting it maybe? But that also feels messy. |
Beta Was this translation helpful? Give feedback.
-
|
If I understand you correctly @mdietrich16, this is what is going on? I'd argue that direnv and nix-cats are both "working as intended" and your workflow unfortunately uncovers in this unintuitive behavior. I guess you are using neovim as a "long running session" and change directories to switch projects for example? For the same reason I guess disabling the option If nix cats collects all paths it injects in an env variable ( |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
-
I am using Nix flakes with devShells for development environments, which get activated with direnv automagically. I think the way NixCats provides Nix-provided executables like LSPs by adding their binaries to the Neovim PATH is a problem when trying to integrate with direnv via direnv.vim.
When starting nvim in a directory that has an .envrc and is loaded by direnv, everything works at first, but when changing the directory, the direnv.vim plugins unloads the environment and with it, the modifications the Neovim wrapper applies to Neovim's PATH variable. This does not happen, when starting Neovim in a non-direnv directory, changing dir to one (and thus loading the env) and changing dir out of it again. Then PATH is properly reset, and at any point all binaries are available.
The concrete way this works (I believe) is that direnv (somehow) saves the initial shell state, opening neovim triggers direnv to look up if something needs to be done, it doesn't since the env is already loaded. But changing dirs outside unloads the environment, meaning a reset to the initial shell state. This means that the nixCats modification of PATH are also removed, since they were not there at the initial shell state.
Starting Neovim in a non-direnv directory an :cd-ing into one works as desired, because then the env has to be loaded from scratch and the Neovim-internal shell state is now properly tracked.
Any ideas on how to fix this?
Beta Was this translation helpful? Give feedback.
All reactions