Fish: Difference between revisions
imported>Haemeah m better link for option reference |
imported>Cyounkins Adding section Setting fish as your shell |
||
Line 3: | Line 3: | ||
== Installation == | == Installation == | ||
A basic user-specific installation with [[Home Manager]] may look like this: | A basic user-specific installation with [[Home Manager]] may look like this: | ||
Line 21: | Line 19: | ||
programs.fish.enable = true; | programs.fish.enable = true; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Setting fish as your shell == | |||
Warning! [https://fishshell.com/docs/current/index.html#default-shell As noted in the fish documentation], using fish as your *login* shell (referenced in <code>/etc/passwd</code>) may cause issues because fish is not POSIX compliant. In particular, this author found systemd's emergency mode to be completely broken when fish was set as the login shell. | |||
This issue is discussed extensively on the [https://wiki.gentoo.org/wiki/Fish#Caveats Gentoo] and [https://wiki.archlinux.org/title/Fish#System_integration Arch] wikis. There they present an alternative, keeping bash as the system shell but having it exec fish when run interactively. | |||
Here is one solution, which launches fish unless the parent process is already fish: | |||
<syntaxhighlight lang="nix"> | |||
programs.bash = { | |||
interactiveShellInit = '' | |||
if [[ $(${pkgs.procps}/bin/ps --no-header --pid=$PPID --format=comm) != "fish" && -z ''${BASH_EXECUTION_STRING} ]] | |||
then | |||
shopt -q login_shell && LOGIN_OPTION='--login' || LOGIN_OPTION="" | |||
exec ${pkgs.fish}/bin/fish $LOGIN_OPTION | |||
fi | |||
''; | |||
}; | |||
</syntaxhighlight> | |||
If you still want to set fish as the login shell, see [[Command Shell#Changing default shell]]. | |||
== Configuration == | == Configuration == |
Revision as of 05:26, 9 February 2024
fish, the Friendly Interactive Shell, is a command shell designed around user-friendliness.
Installation
A basic user-specific installation with Home Manager may look like this:
home-manager.users.myuser = {
programs.fish.enable = true;
};
Change myuser
to the username of the user you want to configure.
You can enable the fish shell and manage fish configuration and plugins with Home Manager, but to enable vendor fish completions provided by Nixpkgs you will also want to enable the fish shell in /etc/nixos/configuration.nix
:
programs.fish.enable = true;
Setting fish as your shell
Warning! As noted in the fish documentation, using fish as your *login* shell (referenced in /etc/passwd
) may cause issues because fish is not POSIX compliant. In particular, this author found systemd's emergency mode to be completely broken when fish was set as the login shell.
This issue is discussed extensively on the Gentoo and Arch wikis. There they present an alternative, keeping bash as the system shell but having it exec fish when run interactively.
Here is one solution, which launches fish unless the parent process is already fish:
programs.bash = {
interactiveShellInit = ''
if [[ $(${pkgs.procps}/bin/ps --no-header --pid=$PPID --format=comm) != "fish" && -z ''${BASH_EXECUTION_STRING} ]]
then
shopt -q login_shell && LOGIN_OPTION='--login' || LOGIN_OPTION=""
exec ${pkgs.fish}/bin/fish $LOGIN_OPTION
fi
'';
};
If you still want to set fish as the login shell, see Command Shell#Changing default shell.
Configuration
System wide
To enable fish plugins, add your preferred plugins to `environment.systemPackages`:
environment.systemPackages = with pkgs; [
fishPlugins.done
fishPlugins.fzf-fish
fishPlugins.forgit
fishPlugins.hydro
fzf
fishPlugins.grc
grc
];
programs.fish.enable = true;
Home Manager
An example configuration in Home Manager for adding plugins and changing options could look like this:
home-manager.users.myuser = {
programs.fish = {
enable = true;
interactiveShellInit = ''
set fish_greeting # Disable greeting
'';
plugins = [
# Enable a plugin (here grc for colorized command output) from nixpkgs
{ name = "grc"; src = pkgs.fishPlugins.grc.src; }
# Manually packaging and enable a plugin
{
name = "z";
src = pkgs.fetchFromGitHub {
owner = "jethrokuan";
repo = "z";
rev = "e0e1b9dfdba362f8ab1ae8c1afc7ccf62b89f7eb";
sha256 = "0dbnir6jbwjpjalz14snzd3cgdysgcs3raznsijd6savad3qhijc";
};
}
];
};
};
Full list of home-manager options for fish can be found See also here.
See fishPlugins package set for available plugins in nixpkgs.
Useful scripts
Show that you are in a nix-shell
Add this to the fish_prompt
function (usually placed in ~/.config/fish/functions/fish_prompt.fish
):
set -l nix_shell_info (
if test -n "$IN_NIX_SHELL"
echo -n "<nix-shell> "
end
)
and $nix_shell_info
to the echo in that function, e.g.:
echo -n -s "$nix_shell_info ~>"
Now your prompt looks like this:
- outside:
~>
- inside:
<nix-shell> ~>
You can directly start nix-shell in fish with nix-shell --run fish
.
Environments
Here are some examples of helper functions that put you in a nix-shell with the given packages installed.
You can either put these in programs.fish.functions
with home-manager or in ~/.config/fish/functions/fish_prompt.fish
without.
haskellEnv
function haskellEnv
nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [ $argv ])"
end
# Invocation: haskellEnv package1 packages2 .. packageN
pythonEnv
function pythonEnv --description 'start a nix-shell with the given python packages' --argument pythonVersion
if set -q argv[2]
set argv $argv[2..-1]
end
for el in $argv
set ppkgs $ppkgs "python"$pythonVersion"Packages.$el"
end
nix-shell -p $ppkgs
end
# Invocation: pythonEnv 3 package1 package2 .. packageN
# or: pythonEnv 2 ..