diff --git a/README.md b/README.md index 7e4f57f..f744dd1 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,36 @@ There's also an overlay which will give you the packages under `pkgs.yaziPlugins The plugin packages provided by this flake can be used with the home-manager module for Yazi, see [`programs.yazi.plugins`](https://nix-community.github.io/home-manager/options.xhtml#opt-programs.yazi.plugins). +### Home Manager Integration +Easily enable plugins, a sensible default is already preconfigured. +The init.lua, your keymaps, dependencies, plugins directory, ... are automatically managed for you +example usage inside home-manager: +```nix + imports = [ + (inputs.nix-yazi-plugins.legacyPackages.x86_64-linux.homeManagerModules.default) + ]; + + programs.yazi = { + enable = true; + }; + + programs.yazi.yaziPlugins = { + enable = true; + plugins = { + starship.enable = true; + jump-to-char = { + enable = true; + keys.toggle.on = [ "F" ]; + }; + relative-motions = { + enable = true; + show_numbers = "relative_absolute"; + show_motion = true; + }; + }; + }; +``` + ## Branches & Compatibility I try to support the latest release and the latest git of Yazi. If you run the unstable version, use the `main` branch. diff --git a/flake.nix b/flake.nix index 6c64941..b312318 100644 --- a/flake.nix +++ b/flake.nix @@ -29,31 +29,119 @@ }: let inherit (self) outputs; + instantiate_lib = lib: pkgs: rec { + inherit (pkgs) callPackage; + inherit (lib) + mapAttrs + mapAttrsToList + listToAttrs + filterAttrs + mkMerge + attrValues + filter + flatten + attrByPath + mkOption + mkEnableOption + ; + # bypass.package = ... + # -> bypass = ... + CondRaiseAttrs = n: set: mapAttrs (_n: v: v."${n}") (filterAttrs (_n: v: v ? "${n}") set); + + packages = (CondRaiseAttrs "package" YaziPlugins); + + homeManagerModulesRaised = (CondRaiseAttrs "hm-module" YaziPlugins); + homeManagerModulesImports = ( + map ( + v: + { config, lib, ... }: + let + cfg = config.programs.yazi.yaziPlugins.plugins.${v.name}; + in + { + imports = ( + filter (v: v != { }) [ + ( + inputs: + lib.mkIf (cfg.enable && inputs.config.programs.yazi.yaziPlugins.enable) ( + v.config ({ inherit cfg; } // (import ./lib.nix inputs)) inputs + ) + ) + (_: { + config = lib.mkIf (cfg.enable && cfg.package != null) { + programs.yazi.plugins.${v.name} = cfg.package; + }; + }) + (_: { + config = lib.mkIf (cfg.enable && cfg ? "runtimeDeps") { + programs.yazi.yaziPlugins.runtimeDeps = cfg.runtimeDeps; + }; + }) + (inputs: (v.options ({ inherit cfg; } // (import ./lib.nix inputs))) inputs) + ( + { pkgs, ... }: + { + options.programs.yazi.yaziPlugins.plugins.${v.name} = { + package = mkOption { + type = lib.types.nullOr lib.types.package; + description = "The ${v.name} package to use"; + default = self.packages.${pkgs.system}.${v.name}; + }; + enable = mkEnableOption v.name; + }; + } + ) + ] + ); + } + ) (attrValues homeManagerModulesRaised) + ); + + YaziPlugins = + let + AttrName = path: builtins.baseNameOf (builtins.dirOf path); + in + haumea.lib.load { + src = ./plugins; + inputs = + (removeAttrs pkgs [ + "self" + "super" + "root" + ]) + // { + flake = self; + }; + # Call files like with callPackage + loader = [ + { + matches = str: str == "package.nix"; + loader = inputs: path: (haumea.lib.loaders.callPackage inputs path); + } + { + matches = str: str == "hm-module.nix"; + loader = + _: path: + let + value = haumea.lib.loaders.verbatim { } path; + name = AttrName path; + in + { + inherit name; + options = + if value ? "options" then + (outer_inputs: inputs: { + options.programs.yazi.yaziPlugins.plugins.${name} = value.options outer_inputs inputs; + }) + else + _: _: { }; + config = if value ? "config" then value.config else _: _: { }; + }; + } + ]; + }; + }; - callYaziPlugins = - pkgs: - haumea.lib.load { - src = ./plugins; - inputs = - (removeAttrs pkgs [ - "self" - "super" - "root" - ]) - // { - flake = self; - }; - # Call files like with callPackage - loader = - with pkgs.lib; - inputs: path: - if hasSuffix "default.nix" "${path}" then - haumea.lib.loaders.default inputs path - else - haumea.lib.loaders.callPackage inputs path; - # Make the default.nix's attrs directly children of lib - transformer = haumea.lib.transformers.liftDefault; - }; in flake-utils-plus.lib.mkFlake { inherit self inputs; @@ -62,12 +150,29 @@ channels: let pkgs = channels.nixpkgs; + lib = inputs.nixpkgs.lib; + instance = (instantiate_lib lib pkgs); + inherit (pkgs) system; in { - packages = callYaziPlugins pkgs; formatter = pkgs.nixfmt-rfc-style; + inherit (instance) packages; + legacyPackages = { + homeManagerModules = rec { + yaziPlugins = + { lib, ... }: + { + imports = + ((instantiate_lib lib (inputs.nixpkgs.legacyPackages.${system})).homeManagerModulesImports) + ++ [ ./module.nix ]; + }; + default = yaziPlugins; + }; + }; + }; - overlays.default = final: prev: { yaziPlugins = callYaziPlugins prev; }; + overlays.default = final: prev: { yaziPlugins = (instantiate_lib (final.lib) prev).packages; }; + }; } diff --git a/lib.nix b/lib.nix new file mode 100644 index 0000000..76501b6 --- /dev/null +++ b/lib.nix @@ -0,0 +1,66 @@ +{ lib, ... }: +let + inherit (lib) mkOption isList; + inherit (lib.types) + submodule + str + either + listOf + ; +in +{ + setKeys = keys: { + programs.yazi.keymap.manager.prepend_keymap = lib.mapAttrsToList (_: key: { + inherit (key) on run desc; + }) keys; + }; + mkRuntimeDeps = + { pkgs }: + mkOption { + type = lib.types.listOf (lib.types.either lib.types.package lib.types.str); + description = '' + Additional runtime packages to add + to deactivate overlaying `lib.mkForce []` the parent option + ''; + default = pkgs; + }; + mkKeyOption = + { + on, + run, + desc, + }: + mkOption { + description = desc; + type = either (submodule { + options = { + on = mkOption { + type = listOf str; + default = on; + }; + run = mkOption { + type = str; + default = run; + }; + + desc = mkOption { + type = str; + default = desc; + }; + }; + }) (listOf str); + default = { + inherit on run desc; + }; + apply = + old: + if isList old then + { + on = old; + run = run; + } + else + old; + }; + +} diff --git a/module.nix b/module.nix new file mode 100644 index 0000000..239015a --- /dev/null +++ b/module.nix @@ -0,0 +1,31 @@ +{ + pkgs, + lib, + config, + ... +}: +let + inherit (lib) mkEnableOption mkOption; + inherit (lib.types) lines; + cfg = config.programs.yazi.yaziPlugins; +in +{ + options.programs.yazi.yaziPlugins = { + enable = mkEnableOption "yaziPlugins"; + runtimeDeps = mkOption { + type = lib.types.listOf (lib.types.either lib.types.package lib.types.str); + description = '' + Additional runtime packages to make available for yazi and plugins. + To deactivate overlaying set this to `lib.mkForce []`. + + This gets set by some plugin modules. + ''; + default = [ ]; + }; + }; + config = lib.mkIf (cfg.runtimeDeps != [ ]) { + programs.yazi.package = pkgs.yazi.override { + extraPackages = config.programs.yazi.yaziPlugins.runtimeDeps; + }; + }; +} diff --git a/plugins/bypass/hm-module.nix b/plugins/bypass/hm-module.nix new file mode 100644 index 0000000..073175c --- /dev/null +++ b/plugins/bypass/hm-module.nix @@ -0,0 +1,20 @@ +{ + options = + { cfg, mkKeyOption, ... }: + { lib, ... }: + { + keys = { + left = mkKeyOption { + on = [ "l" ]; + run = "plugin bypass --args=smart_enter"; + desc = "Open a file, or recursively enter child directory, skipping children with only a single subdirectory"; + }; + right = mkKeyOption { + on = [ "h" ]; + run = "plugin bypass --args=reverse"; + desc = "Recursively enter parent directory, skipping parents with only a single subdirectory"; + }; + }; + }; + config = { cfg, setKeys, ... }: { config, lib, ... }: { } // (setKeys cfg.keys); +} diff --git a/plugins/bypass/default.nix b/plugins/bypass/package.nix similarity index 85% rename from plugins/bypass/default.nix rename to plugins/bypass/package.nix index b9ccecc..ebcd506 100644 --- a/plugins/bypass/default.nix +++ b/plugins/bypass/package.nix @@ -21,8 +21,7 @@ stdenv.mkDerivation { ''; meta = with lib; { - description = - "Yazi plugin for skipping directories with only a single sub-directory"; + description = "Yazi plugin for skipping directories with only a single sub-directory"; homepage = "https://github.com/Rolv-Apneseth/bypass.yazi"; license = licenses.mit; maintainers = [ ]; diff --git a/plugins/chmod/hm-module.nix b/plugins/chmod/hm-module.nix new file mode 100644 index 0000000..076449a --- /dev/null +++ b/plugins/chmod/hm-module.nix @@ -0,0 +1,18 @@ +{ + options = + { cfg, mkKeyOption, ... }: + { lib, ... }: + { + keys = { + mod = mkKeyOption { + on = [ + "c" + "m" + ]; + run = "plugin chmod"; + desc = "Chmod on selected files"; + }; + }; + }; + config = { cfg, setKeys, ... }: { config, lib, ... }: { } // (setKeys cfg.keys); +} diff --git a/plugins/chmod/default.nix b/plugins/chmod/package.nix similarity index 100% rename from plugins/chmod/default.nix rename to plugins/chmod/package.nix diff --git a/plugins/copy-file-contents/default.nix b/plugins/copy-file-contents/package.nix similarity index 100% rename from plugins/copy-file-contents/default.nix rename to plugins/copy-file-contents/package.nix diff --git a/plugins/exifaudio/default.nix b/plugins/exifaudio/package.nix similarity index 100% rename from plugins/exifaudio/default.nix rename to plugins/exifaudio/package.nix diff --git a/plugins/full-border/hm-module.nix b/plugins/full-border/hm-module.nix new file mode 100644 index 0000000..6a6b799 --- /dev/null +++ b/plugins/full-border/hm-module.nix @@ -0,0 +1,7 @@ +{ + config = _: _: { + programs.yazi.initLua = '' + require("full-border"):setup() + ''; + }; +} diff --git a/plugins/full-border/default.nix b/plugins/full-border/package.nix similarity index 100% rename from plugins/full-border/default.nix rename to plugins/full-border/package.nix diff --git a/plugins/glow/default.nix b/plugins/glow/package.nix similarity index 100% rename from plugins/glow/default.nix rename to plugins/glow/package.nix diff --git a/plugins/hide-preview/hm-module.nix b/plugins/hide-preview/hm-module.nix new file mode 100644 index 0000000..419a2a2 --- /dev/null +++ b/plugins/hide-preview/hm-module.nix @@ -0,0 +1,14 @@ +{ + options = + { mkKeyOption, ... }: + _: { + keys = { + toggle = mkKeyOption { + on = [ "T" ]; + run = "plugin hide-preview"; + desc = "Hide or show preview"; + }; + }; + }; + config = { cfg, setKeys, ... }: _: (setKeys cfg.keys); +} diff --git a/plugins/hide-preview/default.nix b/plugins/hide-preview/package.nix similarity index 100% rename from plugins/hide-preview/default.nix rename to plugins/hide-preview/package.nix diff --git a/plugins/jump-to-char/hm-module.nix b/plugins/jump-to-char/hm-module.nix new file mode 100644 index 0000000..4541e80 --- /dev/null +++ b/plugins/jump-to-char/hm-module.nix @@ -0,0 +1,14 @@ +{ + options = + { mkKeyOption, ... }: + _: { + keys = { + toggle = mkKeyOption { + on = [ "f" ]; + run = "plugin jump-to-char"; + desc = "Jump to char"; + }; + }; + }; + config = { cfg, setKeys, ... }: _: (setKeys cfg.keys); +} diff --git a/plugins/jump-to-char/default.nix b/plugins/jump-to-char/package.nix similarity index 100% rename from plugins/jump-to-char/default.nix rename to plugins/jump-to-char/package.nix diff --git a/plugins/max-preview/hm-module.nix b/plugins/max-preview/hm-module.nix new file mode 100644 index 0000000..9c7a661 --- /dev/null +++ b/plugins/max-preview/hm-module.nix @@ -0,0 +1,14 @@ +{ + options = + { mkKeyOption, ... }: + _: { + keys = { + toggle = mkKeyOption { + on = [ "R" ]; + run = "plugin max-preview"; + desc = "Maximize or restore preview"; + }; + }; + }; + config = { cfg, setKeys, ... }: _: (setKeys cfg.keys); +} diff --git a/plugins/max-preview/default.nix b/plugins/max-preview/package.nix similarity index 100% rename from plugins/max-preview/default.nix rename to plugins/max-preview/package.nix diff --git a/plugins/ouch/default.nix b/plugins/ouch/package.nix similarity index 100% rename from plugins/ouch/default.nix rename to plugins/ouch/package.nix diff --git a/plugins/relative-motions/hm-module.nix b/plugins/relative-motions/hm-module.nix new file mode 100644 index 0000000..528e9e3 --- /dev/null +++ b/plugins/relative-motions/hm-module.nix @@ -0,0 +1,56 @@ +{ + options = + { cfg, mkKeyOption, ... }: + { lib, ... }: + { + keys = lib.listToAttrs ( + lib.genList ( + idx_n: + let + idx = builtins.toString (idx_n + 1); + in + { + name = idx; + value = mkKeyOption { + on = [ idx ]; + run = "plugin relative-motions --args=${idx}"; + desc = "Move in relative steps"; + }; + } + ) 9 + ); + show_numbers = lib.mkOption { + type = + with lib.types; + nullOr (enum [ + "relative" + "absolute" + "relative_absolute" + ]); + default = null; + description = "Shows relative or absolute numbers before the file icon"; + }; + show_motion = lib.mkEnableOption "Shows current motion in Status bar"; + only_motions = lib.mkEnableOption '' + If true, only the motion movements will be enabled, + i.e., the commands for delete, cut, yank and visual selection will be disabled''; + }; + config = + { cfg, setKeys, ... }: + { lib, ... }: + lib.mkMerge [ + (setKeys cfg.keys) + { + programs.yazi.initLua = + let + settings = { + inherit (cfg) show_numbers show_motion only_motions; + }; + settingsStr = lib.generators.toLua { } settings; + in + '' + require("relative-motions"):setup(${settingsStr}) + ''; + } + ]; +} diff --git a/plugins/relative-motions/default.nix b/plugins/relative-motions/package.nix similarity index 86% rename from plugins/relative-motions/default.nix rename to plugins/relative-motions/package.nix index 2726416..65a4f90 100644 --- a/plugins/relative-motions/default.nix +++ b/plugins/relative-motions/package.nix @@ -21,8 +21,7 @@ stdenv.mkDerivation { ''; meta = with lib; { - description = - "This plugin adds the some basic vim motions like 3k, 12j, 10gg, etc."; + description = "This plugin adds the some basic vim motions like 3k, 12j, 10gg, etc."; homepage = "https://github.com/dedukun/relative-motions.yazi.git"; license = licenses.mit; maintainers = [ ]; diff --git a/plugins/rich-preview/default.nix b/plugins/rich-preview/package.nix similarity index 100% rename from plugins/rich-preview/default.nix rename to plugins/rich-preview/package.nix diff --git a/plugins/smart-filter/hm-module.nix b/plugins/smart-filter/hm-module.nix new file mode 100644 index 0000000..cfeab76 --- /dev/null +++ b/plugins/smart-filter/hm-module.nix @@ -0,0 +1,14 @@ +{ + options = + { mkKeyOption, ... }: + _: { + keys = { + toggle = mkKeyOption { + on = [ "F" ]; + run = "plugin smart-filter"; + desc = "Smart filter"; + }; + }; + }; + config = { cfg, setKeys, ... }: _: (setKeys cfg.keys); +} diff --git a/plugins/smart-filter/default.nix b/plugins/smart-filter/package.nix similarity index 100% rename from plugins/smart-filter/default.nix rename to plugins/smart-filter/package.nix diff --git a/plugins/starship/hm-module.nix b/plugins/starship/hm-module.nix new file mode 100644 index 0000000..7b674f9 --- /dev/null +++ b/plugins/starship/hm-module.nix @@ -0,0 +1,7 @@ +{ + config = _: _: { + programs.yazi.initLua = '' + require("starship"):setup() + ''; + }; +} diff --git a/plugins/starship/default.nix b/plugins/starship/package.nix similarity index 100% rename from plugins/starship/default.nix rename to plugins/starship/package.nix diff --git a/plugins/system-clipboard/default.nix b/plugins/system-clipboard/package.nix similarity index 100% rename from plugins/system-clipboard/default.nix rename to plugins/system-clipboard/package.nix