matklad / xshell

Apache License 2.0
696 stars 30 forks source link

Return the current environment of the shell #77

Open bzm3r opened 10 months ago

bzm3r commented 10 months ago

Currently, as far as I understand, it is not possible to return the environment of a shell: https://docs.rs/xshell/latest/src/xshell/lib.rs.html#383

Ideally, we should be able to return all the environment variables that a shell is aware of as a std::env::Vars or similar object?

(I can submit a PR for this.)

matklad commented 10 months ago

What would be the use-case here? There is Shell::var to look up a single variable.

Though, I guess there's no harm having this API in...

bzm3r commented 10 months ago

@matklad The use case for me is NixOS related: for various reasons, I created nix-shell inspired derivations which let me create "installable shells": i.e. scripts which run and load the user into a "nix development shell".

nix-shell works by controlling environment variables, and that is ultimately how programs like direnv for instance let you keep your "current shell", instead of the nix-shell default of a new bash shell. So the two things that go into defining a nix-shell are: 1) its packages, and 2) its environment variables.

As I move towards minimizing usage of bash, I have been finding it very helpful to use xshell. In order to get nix-shell/direnv like behaviour: I'd like to be able to load/unload "environment variables" that define the current shell. So, this API would let me get the current env-var "snapshot" for a xshell::Shell, save it, and then load on top of it (via some merging logic) a "nix-shell" env-var snapshot. Once I am done working in this "nix-style-xshell", I can then unload these environment variables, and reload the original environment variables that governed my Shell.

Initially, I thought I might just Clone the current Shell, so I was going to create a PR which allows cloning of Shell. However, for some use cases, e.g. debugging a "nix-style-xshell", it would be useful to have the ability to dump the current environment variables in a Rust data structure, so I think this API is relevant regardless?