Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/fish: add functions setting #377595

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 172 additions & 0 deletions nixos/modules/programs/fish.nix
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,127 @@ let
nativeBuildInputs = [ pkgs.babelfish ];
} "babelfish < ${path} > $out;";

fishIndent =
name: text:
pkgs.runCommand name {
nativeBuildInputs = [ cfg.package ];
inherit text;
passAsFile = [ "text" ];
} "env HOME=$(mktemp -d) fish_indent < $textPath > $out";

functionModule = lib.types.submodule {
options = {
body = lib.mkOption {
type = lib.types.lines;
description = ''
The function body.
'';
};

argumentNames = lib.mkOption {
type = with lib.types; nullOr (either str (listOf str));
default = null;
description = ''
Assigns the value of successive command line arguments to the names
given.
'';
};

description = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
A description of what the function does, suitable as a completion
description.
'';
};

wraps = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Causes the function to inherit completions from the given wrapped
command.
'';
};

onEvent = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Tells fish to run this function when the specified named event is
emitted. Fish internally generates named events e.g. when showing the
prompt.
'';
};

onVariable = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Tells fish to run this function when the specified variable changes
value.
'';
};

onJobExit = lib.mkOption {
type = with lib.types; nullOr (either str int);
default = null;
description = ''
Tells fish to run this function when the job with the specified group
ID exits. Instead of a PID, the stringer `caller` can
be specified. This is only legal when in a command substitution, and
will result in the handler being triggered by the exit of the job
which created this command substitution.
'';
};

onProcessExit = lib.mkOption {
type = with lib.types; nullOr (either str int);
default = null;
example = "$fish_pid";
description = ''
Tells fish to run this function when the fish child process with the
specified process ID exits. Instead of a PID, for backwards
compatibility, `%self` can be specified as an alias
for `$fish_pid`, and the function will be run when
the current fish instance exits.
'';
};

onSignal = lib.mkOption {
type = with lib.types; nullOr (either str int);
default = null;
example = [
"SIGHUP"
"HUP"
1
];
description = ''
Tells fish to run this function when the specified signal is
delievered. The signal can be a signal number or signal name.
'';
};

noScopeShadowing = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Allows the function to access the variables of calling functions.
'';
};

inheritVariable = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Snapshots the value of the specified variable and defines a local
variable with that same name and value when the function is defined.
'';
};
};
};

in

{
Expand Down Expand Up @@ -142,6 +263,24 @@ in
type = lib.types.lines;
};

functions = lib.mkOption {
type = with lib.types; attrsOf (either lines functionModule);
default = { };
example = ''
{
__fish_command_not_found_handler = {
body = "__fish_default_command_not_found_handler $argv[1]";
onEvent = "fish_command_not_found";
};

gitignore = "curl -sL https://www.gitignore.io/api/$argv";
}
'';
description = ''
Basic functions to add to fish. For more information see
<https://fishshell.com/docs/current/cmds/function.html>.
'';
};
};

};
Expand Down Expand Up @@ -239,6 +378,39 @@ in
'';
}

{
etc = lib.mapAttrs' (name: def: {
name = "fish/functions/${name}.fish";
value.source =
let
modifierStr = n: v: lib.optional (v != null) ''--${n}="${toString v}"'';
modifierStrs = n: v: lib.optional (v != null) "--${n}=${toString v}";
modifierBool = n: v: lib.optional (v != null && v) "--${n}";

mods =
with def;
modifierStr "description" description
++ modifierStr "wraps" wraps
++ modifierStr "on-event" onEvent
++ modifierStr "on-variable" onVariable
++ modifierStr "on-job-exit" onJobExit
++ modifierStr "on-process-exit" onProcessExit
++ modifierStr "on-signal" onSignal
++ modifierBool "no-scope-shadowing" noScopeShadowing
++ modifierStr "inherit-variable" inheritVariable
++ modifierStrs "argument-names" argumentNames;

modifiers = if lib.isAttrs def then " ${toString mods}" else "";
body = if lib.isAttrs def then def.body else def;
in
fishIndent "${name}.fish" ''
function ${name}${modifiers}
${lib.strings.removeSuffix "\n" body}
end
'';
}) cfg.functions;
}

{
etc."fish/generated_completions".source =
let
Expand Down