Fish: Difference between revisions

Pigs (talk | contribs)
Reorganized and polished content, added information about installing fish for those not using home manager
Tags: Mobile edit Mobile web edit Advanced mobile edit
Line 4: Line 4:
== Installation ==
== Installation ==


A basic user-specific installation with [[Home Manager]] may look like this:
=== NixOS System Installation ===


<syntaxhighlight lang="nix">
To install fish for a user on a regular nixos system:
home-manager.users.myuser = {
  programs.fish.enable = true;
};
</syntaxhighlight>
 
Change <code>myuser</code> 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 <code>/etc/nixos/configuration.nix</code>:
{{file|/etc/nixos/configuration.nix|nix|
 
<nowiki>
<syntaxhighlight lang="nix">
   programs.fish.enable = true;
   programs.fish.enable = true;
</syntaxhighlight>
  users.extraUsers.myuser = {
    ...
    shell = pkgs.fish;
  };
</nowiki>
}}
Replace <code>myuser</code> with the appropriate username.


== 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 (via <code>/etc/passwd</code>) may cause issues, particularly for the <code>root</code> user, because fish is not POSIX compliant. While using fish as the default shell for regular users is generaly safe, caution is still advised. See the [[#section Setting fish as default shell|Setting fish as default shell]] section for recommendations and mitigations.}}


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.
=== Home Manager ===


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.
For a user-specific installation managed by [[Home Manager]], use the following configuration:


Here is one solution, which launches fish unless the parent process is already fish:
{{file|home.nix|nix|
 
<nowiki>
<syntaxhighlight lang="nix">
home-manager.users.myuser = {
programs.bash = {
   programs.fish.enable = true;
   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>
</nowiki>
}}


If you still want to set fish as the login shell, see [[Command Shell#Changing default shell]].
Replace <code>myuser</code> with the appropriate username.


=== Running fish interactively with zsh as system shell on darwin ===
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:


Zsh users on darwin will need to use a modified version of the above snippet. As written, it presents two incompatibilities. First, being BSD-derived, MacOS's <code>ps</code> command accepts different options. Second, this is a script intended for bash, not zsh. MacOS uses zsh as its default shell.
{{file|/etc/nixos/configuration.nix|nix|
<nowiki>
  programs.fish.enable = true;
</nowiki>
}}


<syntaxhighlight lang="nix">
== Configuration ==
programs.zsh = {
  initExtra = ''
    if [[ $(ps -o command= -p "$PPID" | awk '{print $1}') != 'fish' ]]
    then
        exec fish -l
    fi
  ''
};
</syntaxhighlight>


== Configuration ==
Available fish plugins packaged in Nixpkgs can be found via the [https://search.nixos.org/packages?query=fishPlugins fishPlugins package set].


=== System wide ===
=== NixOS System Configuration ===


To enable fish plugins, add your preferred plugins to `environment.systemPackages`:
To enable fish plugins system-wide, add your preferred plugins to `environment.systemPackages`:


<syntaxhighlight lang="nix">
{{file|/etc/nixos/configuration.nix|nix|
<nowiki>
environment.systemPackages = with pkgs; [
environment.systemPackages = with pkgs; [
  ...
   fishPlugins.done
   fishPlugins.done
   fishPlugins.fzf-fish
   fishPlugins.fzf-fish
Line 73: Line 64:
   grc
   grc
];
];
</nowiki>
}}


programs.fish.enable = true;
For a full list of fish module options, refer to [https://search.nixos.org/options?query=programs.fish programs.fish].
</syntaxhighlight>


=== Home Manager ===
=== Home Manager ===
Line 81: Line 73:
An example configuration in Home Manager for adding plugins and changing options could look like this:
An example configuration in Home Manager for adding plugins and changing options could look like this:


<syntaxhighlight lang="nix">
{{file|home.nix|nix|
<nowiki>
home-manager.users.myuser = {
home-manager.users.myuser = {
   programs.fish = {
   programs.fish = {
Line 104: Line 97:
   };
   };
};
};
</syntaxhighlight>
</nowiki>
Full list of home-manager options for fish can be found  See also [https://github.com/nix-community/home-manager/blob/master/modules/programs/fish.nix here].
}}
 
For the full list of available home-manager options for fish, refer to the [https://github.com/nix-community/home-manager/blob/master/modules/programs/fish.nix module source].
 
== Tips and tricks ==
 
=== Setting fish as default shell ===
 
Using fish as the the login shell can cause compatibility issues. For example, certain recovery environments such as systemd's emergency mode to be completely broken when fish was set as the login shell. This  limitation is noted on the [https://wiki.gentoo.org/wiki/Fish#Caveats Gentoo] wiki. 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:
 
{{file|/etc/nixos/configuration.nix|nix|
<nowiki>
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
  '';
};
</nowiki>
}}
 
If you still want to set fish as the login shell, see [[Command Shell#Changing the default shell]].
 
==== Running fish interactively with zsh as system shell on darwin ====


See [https://search.nixos.org/packages?channel=unstable&from=0&size=50&buckets=%7B%22package_attr_set%22%3A%5B%22fishPlugins%22%5D%2C%22package_license_set%22%3A%5B%5D%2C%22package_maintainers_set%22%3A%5B%5D%2C%22package_platforms%22%3A%5B%5D%7D&sort=relevance&query=fishPlugins fishPlugins package set] for available plugins in nixpkgs.
Zsh users on darwin will need to use a modified version of the above snippet. As written, it presents two incompatibilities. First, being BSD-derived, MacOS's <code>ps</code> command accepts different options. Second, this is a script intended for bash, not zsh. MacOS uses zsh as its default shell.


== Useful scripts ==
<syntaxhighlight lang="nix">
programs.zsh = {
  initExtra = ''
    if [[ $(ps -o command= -p "$PPID" | awk '{print $1}') != 'fish' ]]
    then
        exec fish -l
    fi
  ''
};
</syntaxhighlight>


=== Show that you are in a nix-shell ===
=== Show that you are in a nix-shell ===
Line 136: Line 166:


=== Environments ===
=== Environments ===
Here are some examples of helper functions that put you in a nix-shell with the given packages installed.  
Here are some examples of helper functions that put you in a nix-shell with the given packages installed.