My personal collection of nix shell files for temporary packages, shell functions, and configuration files.
There are certain tools I use repeatedly, but rarely enough that I don't want to keep
them in my user environment. For some, I may want settings and aliases that a simple
nix-shell or nix shell command cannot provide.
The solution? Nix can use shell.nix files and devShells to symlink files
and specify shell hooks. This repo is a collection of these files.
Note
These shells are for my personal use cases. I welcome anyone to create their own repo based on these files!
The shells can be entered with or without flakes.
At the root directory, use nix develop followed by the shell to enter.
The names of the devShells can be found in flake.nix.
Example:
flake.nix
{
# ... other file contents ...
outputs = { self, nixpkgs }:
let
allSystems = nixpkgs.lib.genAttrs nixpkgs.lib.platforms.all;
toSystems = passPkgs: allSystems (system: passPkgs (import nixpkgs { inherit system; }));
in
{
devShells = toSystems (pkgs: {
hello = import ./hello/shell.nix { inherit pkgs; };
});
};
}$ nix develop .#helloTo use a shell other than bash, you can do something like:
$ nix develop .#hello --command zshEnter the directory with the shell.nix file you want to use, and do nix-shell.
Example:
$ cd hello
$ nix-shellYou can export aliases in Nix's shellHook, but since devShells are made in bash,
the aliases don't carry to other shells like zsh.
This is especially a problem if one uses direnv (e.g. with nix-direnv), which automatically drops you into your current shell.
However, there is a workaround: pkgs.writeShellScriptBin. This is a trivial builder
that writes a script file to /nix/store/<store path>/bin/<file>, and if included in
the shell's packages list, can be made available and executable in shell environment.
This repo stores these scripts in an alises set whose leaves can be included separately
in the shell's packages list.
Example:
shell.nix
{ pkgs ? import <nixpkgs> { } }:
let
aliases = {
uwu-hello = pkgs.writeShellScriptBin "uwu-hello" ''
hello -g "hewwo?"
'';
custom-hello = pkgs.writeShellScriptBin "uwu-hello" ''
hello -g "$@"
'';
};
in
pkgs.mkShell {
packages = [
pkgs.hello
aliases.custom-hello
];
}In the shell, custom-hello "hi" does hello -g "hi", but uwu-hello is not a command.
You can run ln -s in shellHook can symlink existing files to the specified location.
You can also write something like this:
shell.nix
{ pkgs ? import <nixpkgs> { } }:
pkgs.mkShell {
# ...
shellHook =
let
config-file = builtins.toFile "config.toml" ''
foo = "bar"
[baz]
hello = 1
'';
in
''
ln -s ${config-file} ~/.config/example/config.toml
'';
}Or use the variations of pkgs.writeTextFile, pkgs.writeText, etc.
If the program can be run with a specified config file path, you can also wrap it like so:
{ pkgs ? import <nixpkgs> { } }:
let
config-file = builtins.toFile "config.toml" ''
foo = "bar"
[baz]
hello = 1
'';
aliases = {
example-script = pkgs.writeShellScriptBin "example" ''
example --config ${config-file} "$@"
'';
};
in
pkgs.mkShell {
packages = [ aliases.example-script ];
}For more complex usages, see wrapProgram.