nnn: init (#2368)
nnn is a terminal file manager. It is configured mostly using environment variables, so the way I found it to avoid needing to write either shell specific code or using `home.sessionVariables` (that would need to make the user relogin at every configuration change) is to wrap the program using `wrapProgram`.main
parent
80d23ee06c
commit
592da767bd
@ -0,0 +1,129 @@ |
||||
{ config, lib, pkgs, ... }: |
||||
|
||||
with lib; |
||||
|
||||
let |
||||
cfg = config.programs.nnn; |
||||
|
||||
renderSetting = key: value: "${key}:${value}"; |
||||
|
||||
renderSettings = settings: |
||||
concatStringsSep ";" (mapAttrsToList renderSetting settings); |
||||
|
||||
pluginModule = types.submodule ({ ... }: { |
||||
options = { |
||||
src = mkOption { |
||||
type = with types; nullOr path; |
||||
example = literalExample '' |
||||
(pkgs.fetchFromGitHub { |
||||
owner = "jarun"; |
||||
repo = "nnn"; |
||||
rev = "v4.0"; |
||||
sha256 = "sha256-Hpc8YaJeAzJoEi7aJ6DntH2VLkoR6ToP6tPYn3llR7k="; |
||||
}) + "/plugins"; |
||||
''; |
||||
default = null; |
||||
description = '' |
||||
Path to the plugin folder. |
||||
''; |
||||
}; |
||||
|
||||
mappings = mkOption { |
||||
type = with types; attrsOf str; |
||||
description = '' |
||||
Key mappings to the plugins. |
||||
''; |
||||
default = { }; |
||||
example = literalExample '' |
||||
{ |
||||
c = "fzcd"; |
||||
f = "finder"; |
||||
v = "imgview"; |
||||
}; |
||||
''; |
||||
}; |
||||
}; |
||||
}); |
||||
in { |
||||
meta.maintainers = with maintainers; [ thiagokokada ]; |
||||
|
||||
options = { |
||||
programs.nnn = { |
||||
enable = mkEnableOption "nnn"; |
||||
|
||||
package = mkOption { |
||||
type = types.package; |
||||
default = pkgs.nnn; |
||||
defaultText = literalExample "pkgs.nnn"; |
||||
example = |
||||
literalExample "pkgs.nnn.override ({ withNerdIcons = true; });"; |
||||
description = '' |
||||
Package containing the <command>nnn</command> program. |
||||
''; |
||||
}; |
||||
|
||||
finalPackage = mkOption { |
||||
type = types.package; |
||||
readOnly = true; |
||||
visible = false; |
||||
description = '' |
||||
Resulting nnn package. |
||||
''; |
||||
}; |
||||
|
||||
bookmarks = mkOption { |
||||
type = with types; attrsOf str; |
||||
description = '' |
||||
Directory bookmarks. |
||||
''; |
||||
example = literalExample '' |
||||
{ |
||||
d = "~/Documents"; |
||||
D = "~/Downloads"; |
||||
p = "~/Pictures"; |
||||
v = "~/Videos"; |
||||
}; |
||||
''; |
||||
default = { }; |
||||
}; |
||||
|
||||
extraPackages = mkOption { |
||||
type = with types; listOf package; |
||||
example = |
||||
literalExample "with pkgs; [ ffmpegthumbnailer mediainfo sxiv ]"; |
||||
description = '' |
||||
Extra packages available to nnn. |
||||
''; |
||||
default = [ ]; |
||||
}; |
||||
|
||||
plugins = mkOption { |
||||
type = pluginModule; |
||||
description = '' |
||||
Manage nnn plugins. |
||||
''; |
||||
default = { }; |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
config = let |
||||
nnnPackage = cfg.package.overrideAttrs (oldAttrs: { |
||||
nativeBuildInputs = (oldAttrs.nativeBuildInputs or [ ]) |
||||
++ [ pkgs.makeWrapper ]; |
||||
postInstall = '' |
||||
${oldAttrs.postInstall or ""} |
||||
|
||||
wrapProgram $out/bin/nnn \ |
||||
--prefix PATH : "${makeBinPath cfg.extraPackages}" \ |
||||
--prefix NNN_BMS : "${renderSettings cfg.bookmarks}" \ |
||||
--prefix NNN_PLUG : "${renderSettings cfg.plugins.mappings}" |
||||
''; |
||||
}); |
||||
in mkIf cfg.enable { |
||||
programs.nnn.finalPackage = nnnPackage; |
||||
home.packages = [ nnnPackage ]; |
||||
xdg.configFile."nnn/plugins" = |
||||
mkIf (cfg.plugins.src != null) { source = cfg.plugins.src; }; |
||||
}; |
||||
} |
@ -0,0 +1 @@ |
||||
{ nnn = ./nnn.nix; } |
@ -0,0 +1,57 @@ |
||||
{ config, lib, pkgs, ... }: |
||||
|
||||
{ |
||||
config = { |
||||
programs.nnn = { |
||||
enable = true; |
||||
bookmarks = { |
||||
d = "~/Documents"; |
||||
D = "~/Downloads"; |
||||
p = "~/Pictures"; |
||||
v = "~/Videos"; |
||||
}; |
||||
package = pkgs.nnnDummy; |
||||
extraPackages = with pkgs; [ foo bar ]; |
||||
plugins = { |
||||
src = ./plugins; |
||||
mappings = { |
||||
c = "fzcd"; |
||||
f = "finder"; |
||||
v = "imgview"; |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
test.stubs = { |
||||
nnnDummy.buildScript = '' |
||||
mkdir -p "$out/bin" |
||||
touch "$out/bin/nnn" |
||||
chmod +x "$out/bin/nnn" |
||||
|
||||
runHook postInstall |
||||
''; |
||||
foo = { name = "foo"; }; |
||||
bar = { name = "bar"; }; |
||||
}; |
||||
|
||||
nmt = { |
||||
description = |
||||
"Check if the binary is correctly wrapped and if the symlinks are made"; |
||||
script = '' |
||||
assertDirectoryExists home-files/.config/nnn/plugins |
||||
|
||||
assertFileRegex \ |
||||
home-path/bin/nnn \ |
||||
"^export NNN_BMS='D:~/Downloads;d:~/Documents;p:~/Pictures;v:~/Videos'\''${NNN_BMS:+':'}\$NNN_BMS$" |
||||
|
||||
assertFileRegex \ |
||||
home-path/bin/nnn \ |
||||
"^export NNN_PLUG='c:fzcd;f:finder;v:imgview'\''${NNN_PLUG:+':'}\$NNN_PLUG$" |
||||
|
||||
assertFileRegex \ |
||||
home-path/bin/nnn \ |
||||
"/nix/store/.*-"{foo,bar}"/bin" |
||||
''; |
||||
}; |
||||
}; |
||||
} |
Loading…
Reference in new issue