home-manager/modules/programs/broot.nix

277 lines
9.1 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.broot;
tomlFormat = pkgs.formats.toml { };
brootConf = {
verbs = cfg.verbs;
skin = cfg.skin;
modal = cfg.modal;
};
in {
meta.maintainers = [ maintainers.aheaume ];
options.programs.broot = {
enable = mkEnableOption "Broot, a better way to navigate directories";
enableBashIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Bash integration.
'';
};
enableZshIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Zsh integration.
'';
};
enableFishIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Fish integration.
'';
};
modal = mkEnableOption "modal (vim) mode";
verbs = mkOption {
type = with types; listOf (attrsOf (either bool str));
default = [
{
invocation = "p";
execution = ":parent";
}
{
invocation = "edit";
shortcut = "e";
execution = "$EDITOR {file}";
}
{
invocation = "create {subpath}";
execution = "$EDITOR {directory}/{subpath}";
}
{
invocation = "view";
execution = "less {file}";
}
];
example = literalExpression ''
[
{ invocation = "p"; execution = ":parent"; }
{ invocation = "edit"; shortcut = "e"; execution = "$EDITOR {file}" ; }
{ invocation = "create {subpath}"; execution = "$EDITOR {directory}/{subpath}"; }
{ invocation = "view"; execution = "less {file}"; }
{
invocation = "blop {name}\\.{type}";
execution = "/bin/mkdir {parent}/{type} && /usr/bin/nvim {parent}/{type}/{name}.{type}";
from_shell = true;
}
]
'';
description = ''
Define new verbs. For more information, see
<link xlink:href="https://dystroy.org/broot/documentation/configuration/#verb-definition-attributes"/>.
</para><para>
The possible attributes are:
</para>
<para>
<variablelist>
<varlistentry>
<term><literal>invocation</literal> (optional)</term>
<listitem><para>how the verb is called by the user, with placeholders for arguments</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>execution</literal> (mandatory)</term>
<listitem><para>how the verb is executed</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>key</literal> (optional)</term>
<listitem><para>a keyboard key triggering execution</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>shortcut</literal> (optional)</term>
<listitem><para>an alternate way to call the verb (without
the arguments part)</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>leave_broot</literal> (optional)</term>
<listitem><para>whether to quit broot on execution
(default: <literal>true</literal>)</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>from_shell</literal> (optional)</term>
<listitem><para>whether the verb must be executed from the
parent shell (default:
<literal>false</literal>)</para></listitem>
</varlistentry>
</variablelist>
'';
};
package = mkOption {
type = types.package;
default = pkgs.broot;
defaultText = literalExpression "pkgs.broot";
description = "Package providing broot";
};
skin = mkOption {
type = types.attrsOf types.str;
default = { };
example = literalExpression ''
{
status_normal_fg = "grayscale(18)";
status_normal_bg = "grayscale(3)";
status_error_fg = "red";
status_error_bg = "yellow";
tree_fg = "red";
selected_line_bg = "grayscale(7)";
permissions_fg = "grayscale(12)";
size_bar_full_bg = "red";
size_bar_void_bg = "black";
directory_fg = "lightyellow";
input_fg = "cyan";
flag_value_fg = "lightyellow";
table_border_fg = "red";
code_fg = "lightyellow";
}
'';
description = ''
Color configuration.
</para><para>
Complete list of keys (expected to change before the v1 of broot):
<itemizedlist>
<listitem><para><literal>char_match</literal></para></listitem>
<listitem><para><literal>code</literal></para></listitem>
<listitem><para><literal>directory</literal></para></listitem>
<listitem><para><literal>exe</literal></para></listitem>
<listitem><para><literal>file</literal></para></listitem>
<listitem><para><literal>file_error</literal></para></listitem>
<listitem><para><literal>flag_label</literal></para></listitem>
<listitem><para><literal>flag_value</literal></para></listitem>
<listitem><para><literal>input</literal></para></listitem>
<listitem><para><literal>link</literal></para></listitem>
<listitem><para><literal>permissions</literal></para></listitem>
<listitem><para><literal>selected_line</literal></para></listitem>
<listitem><para><literal>size_bar_full</literal></para></listitem>
<listitem><para><literal>size_bar_void</literal></para></listitem>
<listitem><para><literal>size_text</literal></para></listitem>
<listitem><para><literal>spinner</literal></para></listitem>
<listitem><para><literal>status_error</literal></para></listitem>
<listitem><para><literal>status_normal</literal></para></listitem>
<listitem><para><literal>table_border</literal></para></listitem>
<listitem><para><literal>tree</literal></para></listitem>
<listitem><para><literal>unlisted</literal></para></listitem>
</itemizedlist></para>
<para>
Add <literal>_fg</literal> for a foreground color and
<literal>_bg</literal> for a background colors.
'';
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
xdg.configFile."broot/conf.toml".source =
tomlFormat.generate "broot-config" brootConf;
# Dummy file to prevent broot from trying to reinstall itself
xdg.configFile."broot/launcher/installed-v1".text = "";
programs.bash.initExtra = mkIf cfg.enableBashIntegration (
# Using mkAfter to make it more likely to appear after other
# manipulations of the prompt.
mkAfter ''
# This script was automatically generated by the broot function
# More information can be found in https://github.com/Canop/broot
# This function starts broot and executes the command
# it produces, if any.
# It's needed because some shell commands, like `cd`,
# have no useful effect if executed in a subshell.
function br {
f=$(mktemp)
(
set +e
broot --outcmd "$f" "$@"
code=$?
if [ "$code" != 0 ]; then
rm -f "$f"
exit "$code"
fi
)
code=$?
if [ "$code" != 0 ]; then
return "$code"
fi
d=$(cat "$f")
rm -f "$f"
eval "$d"
}
'');
programs.zsh.initExtra = mkIf cfg.enableZshIntegration ''
# This script was automatically generated by the broot function
# More information can be found in https://github.com/Canop/broot
# This function starts broot and executes the command
# it produces, if any.
# It's needed because some shell commands, like `cd`,
# have no useful effect if executed in a subshell.
function br {
f=$(mktemp)
(
set +e
broot --outcmd "$f" "$@"
code=$?
if [ "$code" != 0 ]; then
rm -f "$f"
exit "$code"
fi
)
code=$?
if [ "$code" != 0 ]; then
return "$code"
fi
d=$(cat "$f")
rm -f "$f"
eval "$d"
}
'';
programs.fish.shellInit = mkIf cfg.enableFishIntegration ''
# This script was automatically generated by the broot function
# More information can be found in https://github.com/Canop/broot
# This function starts broot and executes the command
# it produces, if any.
# It's needed because some shell commands, like `cd`,
# have no useful effect if executed in a subshell.
function br
set f (mktemp)
broot --outcmd $f $argv
if test $status -ne 0
rm -f "$f"
return "$code"
end
set d (cat "$f")
rm -f "$f"
eval "$d"
end
'';
};
}