Files
dev/configs/nixos/modules/shell/fish/default.nix

116 lines
3.7 KiB
Nix

{
config,
lib,
pkgs,
...
}:
# fish for the primary user, configured through home-manager.
let
cfg = config.modules.shell.fish;
user = config.user.name;
shortcuts = config.registry.shell-shortcut.${config.networking.hostName};
envVars = config.registry.env-var.${config.networking.hostName};
commandsOf = shortcuts: lib.mapAttrs (_name: shortcut: shortcut.command) shortcuts;
exportEnvVar = name: value: ''
set -gx ${name} ${lib.escapeShellArg value}
'';
in
{
options.modules.shell.fish = {
enable = lib.mkEnableOption "fish as the user's shell, configured via home-manager";
defaultShell = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Set fish as the user's default login shell.";
};
};
config = lib.mkIf cfg.enable {
# System-level fish registers it in /etc/shells and installs vendor completions.
programs.fish.enable = true;
users.users.${user}.shell = lib.mkIf cfg.defaultShell pkgs.fish;
home-manager.users.${user} = {
home.packages = with pkgs; [
bat # backs the manpager
fastfetch # the shell greeting
];
xdg.configFile."fish/completions/bazel.fish".source = ./completions/bazel.fish;
programs.fish = {
enable = true;
preferAbbrs = true;
plugins = [
# Notify when a long command finishes.
{
name = "done";
src = pkgs.fishPlugins.done.src;
}
# Restore the !! and !$ history bindings.
{
name = "bang-bang";
src = pkgs.fishPlugins.bang-bang.src;
}
];
shellAliases = commandsOf (lib.filterAttrs (_name: shortcut: !shortcut.abbreviation) shortcuts);
shellAbbrs = commandsOf (lib.filterAttrs (_name: shortcut: shortcut.abbreviation) shortcuts);
functions = {
# Pick the logo that fits the terminal so the greeting never wraps.
# The full logo needs about 118 columns beside the info block, the
# compact one about 89, the info block alone about 71.
fish_greeting = ''
if test "$COLUMNS" -ge 118
fastfetch
else if test "$COLUMNS" -ge 89
fastfetch --logo NixOS_small
else
fastfetch --logo none
end
'';
# vi insert mode omits the emacs ctrl-f and ctrl-r bindings, so restore both.
# ctrl-f accepts an autosuggestion and ctrl-r opens the history pager.
# vi normal mode keeps its ctrl-r redo, since only insert mode is bound.
fish_user_key_bindings = ''
bind -M insert ctrl-f forward-char
bind -M insert ctrl-r history-pager
'';
history = {
description = "Show command history with timestamps";
body = "builtin history --show-time='%F %T '";
};
backup = {
description = "Copy <file> to <file>.bak";
argumentNames = "filename";
body = "cp $filename $filename.bak";
};
copy = {
description = "Copy a file, or recursively copy a source directory into a destination";
body = builtins.readFile ./functions/copy.fish;
};
deploy-to = {
description = "Deploy the current dotfiles branch to a host through target-local nixos-rebuild";
body = builtins.readFile ./functions/deploy-to.fish;
};
};
# Rendered by home-manager into ~/.config/fish/config.fish.
interactiveShellInit = lib.concatStringsSep "\n" (
(lib.mapAttrsToList exportEnvVar envVars)
++ [ (builtins.readFile ./config.fish) ]
);
};
};
};
}