Closed lovesegfault closed 6 years ago
Minimal nix file to reproduce
{}:
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "zsh-nix-shell-6";
shellHook=''alias taco=echo\ "tacos!"'';
}
This feature would be extremely hard to support.
The shim has to evaluate the commands that nix-shell
passes to it using bash
since they aren't valid zsh
commands. Inside that bash
shell the shim starts a zsh
shell. That means that the shellHook
will run inside bash
before the zsh
shell is spawned.
Aliases aren't propagated from bash
to zsh
> bash
$ alias taco=echo\ "tacos!"
$ zsh
> taco
zsh: command not found: taco
The only way to support shellHook
s completely would be a bash
script interpreter for zsh
. Alternatively compgen -a
provides a way to enumerate all aliases currently defined. So you could theoretically recreate them and pass them to zsh
.
For now I will update the readme that this isn't currently supported. Sorry :(
Could you provide a litte more information on your usecase? Maybe we can figure out some workaround.
edit: according to the folks on #nixos IRC it's pretty uncommon to define aliases inside a shellHook
though.
Yeah I figured this would be rather hard, but thought was worth reporting anyway.
Regarding use case, it's a bit contrived, but here's what I'm doing. My OS is on version X
of glibc
. I have a nix shell which I need to be on version Y>X
of glibc
. I can't simply add ${glibc}/lib
to LD_LIBRARY_PATH
since that will then break all of my OS-tools, and yet I need the internal glibc on LD_LIBRARY_PATH
when running a particular command foo
.
My solution was to create an alias foo=LD_LIBRARY_PATH=${glibc}/lib:${LD_LIBRARY_PATH}\ foo
and call it a day; and I wanted this to be always available in the shell, so I added it to shellHook.
Yeah, that could be solved pretty easily without an alias
in a shellHook
.
I'll close this issue now as wont fix. I hope this isn't a dealbreaker for you. If it is you are free to provide a fix yourself ;)
For now I will update the readme that this isn't currently supported. Sorry :(
Hey,
I believe I found a workaround for limitation above. For me it works when I will define shellScript first, like so:
with import <nixpkgs> {};
let
initEnv = pkgs.writeShellScriptBin "init-environment" ''
export ZDOTDIR=$PWD
'';
in
stdenv.mkDerivation {
name = "env";
buildInputs = [
initEnv
];
shellHook = ''
source init-environment
'';
}
In root directory I have created a symlink to user configuration ln -s ~/.zshrc .zshrc
(to get global setup) and added additional .zshenv
file for project specific aliases.
Without introducing init-environment
I was not able to define ENV
vars at all.
How did you try to set environment variables in the first place? As far as I can see your solution should be equivalent to setting the variable inside the shellHook
directly. In both scenarios the actual code that sets the variable is executed before you are dropped into zsh
.
The following works for me:
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "env";
shellHook = "export SOME_VAR=VALUE";
}
The idea of setting ZDOTDIR
inside of the shellHook
is pretty cool. Although I wouldn't use PWD
.
I would create a directory with all the relevant files and let nix take care of linking stuff together correctly:
.
├── zdotdir
│ └── .zshrc
├── default.nix
source ~/.zshrc
alias taco=echo\ "tacos!"
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "withCustomEnv";
shellHook = "export ZDOTDIR=${./zdotdir}";
}
actually you are right in case of exporting var, I was blind and forgot about export, sorry for confusions 👍
Your version is much cleaner and going to use it! Thanks!
I wrote a little nix expression that should take care of all edgecases I could come across.
Usage would be like this:
{ pkgs ? import <nixpkgs> {}
, zdotdir ? import (builtins.fetchurl {
url = "https://gist.githubusercontent.com/chisui/bba90fccc930f614743dc259fbadae6d/raw/4108222addc1d646c1b0a6d12130083e2219ad28/zdotdir.nix";
}) { inherit pkgs; }
}:
pkgs.stdenv.mkDerivation {
name = "withZshEnv";
shellHook = zdotdir {
zshenv = ''
alias taco=echo\ "tacos!";
'';
};
}
If that works for you @damianbaar and @bemeurer I'll include it in the readme.
Hey, looks cool, however getting this, if I'm going to nix-shell
from zsh
but if I will run nix-shell
within nix-shell
then all good.
Does it work now if you use this version? https://gist.githubusercontent.com/chisui/bba90fccc930f614743dc259fbadae6d/raw/b29f5ed299825f16162de5fcb43aae95ab3ddd46/zdotdir.nix
no difference, but after changing to
in ''
if [ -n ''${ZDOTDIR} ]; // from zsh way to posix way
then
export ZDOTDIR_PARENT=$ZDOTDIR;
fi
export ZDOTDIR=${zDotDir};
''
echo
for ZDOTDIR
gives me /nix/store/6yxiszpzndk52ar21rzyrw63j873p75g-ZDOTDIR
and got taco
in scope.
i've changed a bit your piece, with less assumptions about env vars, so you can pass string or path to file,
here you can find details: https://gist.github.com/damianbaar/57aff242d06c75444dbd36bf5400060e
Hm, in your version the users dotfiles aren't loaded. Is that by design? In my setup I have a custom theme that includes the current nix-shell environment in the prompt, which isn't loaded if you simple set the ZDOTDIR
var.
Issue description
Currently, if you define aliases in the
shellHook
portion of yourshell.nix
/default.nix
file, they do not get passed to zsh.Steps to reproduce
shell.nix
with ashellHook
section like such:shellHook=''alias taco=echo\ "tacos!"''
nix-shell --pure
, and then tuntaco
inside the shell to verify the alias works.nix-shell
and then runtaco
inside the shell; the alias no longer worksTechnical details