diff --git a/README.md b/README.md index 3881ece..44037a9 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ This library provides two main components: vo=gpu hwdec=auto ''; - "mpv.input".content = '' + "input.conf".content = '' WHEEL_UP seek 10 WHEEL_DOWN seek -10 ''; @@ -140,12 +140,14 @@ Arguments: - Example: `[ "--silent" "--connect-timeout" "30" ]` - If provided, overrides automatic generation from `flags` - `preHook`: Shell script executed before the command (default: `""`) +- `postHook`: Shell script executed after the command. This will leave a bash process running, use with caution (default: `""`) - `passthru`: Additional attributes for the derivation's passthru (default: `{}`) - `aliases`: List of additional symlink names for the executable (default: `[]`) - `filesToPatch`: List of file paths (glob patterns) relative to package root to patch for self-references (default: `["share/applications/*.desktop"]`) - Example: `["bin/*", "lib/*.sh"]` to replace original package paths with wrapped package paths - Desktop files are patched by default to update Exec= and Icon= paths - `filesToExclude`: List of file paths (glob patterns) to exclude from the wrapped package (default: `[]`) +- `patchHook`: Shell script that runs after patchPhase to modify the wrapper package files (default: `""`) - `wrapper`: Custom wrapper function (optional, overrides default exec wrapper) The function: @@ -170,9 +172,12 @@ Built-in options (always available): - `flagSeparator`: Separator between flag name and value (default: `" "`) - `args`: Command-line arguments list (auto-generated from `flags` if not provided) - `env`: Environment variables +- `preHook`: Shell script executed before the command (default: `""`) +- `postHook`: Shell script executed after the command. This will leave a bash process running, use with caution (default: `""`) - `passthru`: Additional passthru attributes - `filesToPatch`: List of file paths (glob patterns) to patch for self-references (default: `["share/applications/*.desktop"]`) - `filesToExclude`: List of file paths (glob patterns) to exclude from the wrapped package (default: `[]`) +- `patchHook`: Shell script that runs after patchPhase to modify the wrapper package files (default `""`) - `wrapper`: The resulting wrapped package (read-only, auto-generated from other options) - `apply`: Function to extend the configuration with additional modules (read-only) @@ -231,7 +236,7 @@ Wraps mpv with configuration file support and script management: vo=gpu profile=gpu-hq ''; - "mpv.input".content = '' + "input.conf".content = '' RIGHT seek 5 LEFT seek -5 ''; diff --git a/checks/formatting.nix b/checks/formatting.nix index 7ddebfa..b399c67 100644 --- a/checks/formatting.nix +++ b/checks/formatting.nix @@ -4,6 +4,8 @@ }: pkgs.runCommand "formatting-check" { } '' - ${pkgs.lib.getExe self.formatter.${pkgs.system}} --no-cache --fail-on-change ${../.} + ${ + pkgs.lib.getExe self.formatter.${pkgs.stdenv.hostPlatform.system} + } --no-cache --fail-on-change ${../.} touch $out '' diff --git a/checks/patchHook.nix b/checks/patchHook.nix new file mode 100644 index 0000000..26ef891 --- /dev/null +++ b/checks/patchHook.nix @@ -0,0 +1,42 @@ +{ + pkgs, + self, +}: + +let + # Create a dummy package with a desktop file that references itself + dummyPackage = + (pkgs.runCommand "dummy-app" { } '' + # empty dir as a package + mkdir -p $out + '') + // { + meta.mainProgram = "dummy-app"; + }; + + # Wrap the package + wrappedPackage = self.lib.wrapPackage { + inherit pkgs; + package = dummyPackage; + patchHook = '' + touch $out/test + ''; + }; + +in +pkgs.runCommand "patchHook-test" + { + wrappedPath = "${wrappedPackage}"; + } + '' + echo "Testing patchHook functionality..." + echo "Wrapped package path: $wrappedPath" + + if [ ! -f "$wrappedPath/test" ]; then + echo "FAIL: file not created in patched package" + exit 1 + fi + + echo "SUCCESS: patchHook executed correctly" + touch $out + '' diff --git a/lib/default.nix b/lib/default.nix index 14d60b6..ec93b18 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -380,12 +380,14 @@ let - `flagSeparator`: Separator between flag names and values when generating args from flags (optional, defaults to " ") - `args`: List of command-line arguments like argv in execve (optional, auto-generated from flags if not provided) - `preHook`: Shell script to run before executing the command (optional) + - `postHook`: Shell script to run after executing the command, removes the `exec` call. use with care (optional) - `passthru`: Attribute set to pass through to the wrapped derivation (optional) - `aliases`: List of additional names to symlink to the wrapped executable (optional) - `filesToPatch`: List of file paths (glob patterns) to patch for self-references (optional, defaults to ["share/applications/*.desktop"]) - `filesToExclude`: List of file paths (glob patterns) to exclude from the wrapped package (optional, defaults to []) + - `patchHook`: Shell script that runs after patchPhase to modify the wrapper package files (optional) - `wrapper`: Custom wrapper function (optional, defaults to exec'ing the original binary with args) - - Called with { env, flags, args, envString, flagsString, exePath, preHook } + - Called with { env, flags, args, envString, flagsString, exePath, preHook, postHook } # Example @@ -445,30 +447,33 @@ let # " " for "--flag value" or "=" for "--flag=value" args ? generateArgsFromFlags flags flagSeparator, preHook ? "", + postHook ? "", passthru ? { }, aliases ? [ ], # List of file paths (glob patterns) relative to package root to patch for self-references (e.g., ["bin/*", "lib/*.sh"]) filesToPatch ? [ "share/applications/*.desktop" ], # List of file paths (glob patterns) to exclude from the wrapped package (e.g., ["bin/unwanted-*", "share/doc/*"]) filesToExclude ? [ ], + patchHook ? "", wrapper ? ( { exePath, flagsString, envString, preHook, + postHook, ... }: '' ${envString} ${preHook} - exec ${exePath}${flagsString} "$@" + ${lib.optionalString (postHook == "") "exec"} ${exePath}${flagsString} "$@" + ${postHook} '' ), }@funcArgs: let - # lndir was moved from xorg.lndir to lndir in https://github.com/NixOS/nixpkgs/pull/402102 - lndir = if pkgs ? xorg.lndir then pkgs.xorg.lndir else pkgs.lndir; + inherit (pkgs) lndir; # Generate environment variable exports envString = @@ -496,6 +501,7 @@ let flagsString exePath preHook + postHook ; }; @@ -512,6 +518,7 @@ let binName ? null, filesToPatch ? [ ], filesToExclude ? [ ], + patchHook ? "", ... }@args: pkgs.stdenv.mkDerivation ( @@ -567,6 +574,7 @@ let done '') filesToPatch} ''} + ${patchHook} # Create symlinks for aliases ${lib.optionalString (aliases != [ ] && binName != null) '' @@ -605,6 +613,7 @@ let "binName" "filesToPatch" "filesToExclude" + "patchHook" ]) ); @@ -639,6 +648,7 @@ let binName filesToPatch filesToExclude + patchHook ; passthru = (package.passthru or { }) @@ -649,6 +659,7 @@ let flags args preHook + postHook aliases ; override = diff --git a/lib/modules/wrapper.nix b/lib/modules/wrapper.nix index 9371c8e..a950d46 100644 --- a/lib/modules/wrapper.nix +++ b/lib/modules/wrapper.nix @@ -85,6 +85,29 @@ Example: [ "bin/unwanted-tool" "share/applications/*.desktop" ] ''; }; + options.patchHook = lib.mkOption { + type = lib.types.str; + default = ""; + description = '' + Shell script that runs after patchPhase to modify the wrapper package files. + ''; + }; + options.preHook = lib.mkOption { + type = lib.types.str; + default = ""; + description = '' + Shell script to run before executing the command. + ''; + }; + options.postHook = lib.mkOption { + type = lib.types.str; + default = ""; + description = '' + Shell script to run after executing the command. + Removes the `exec` call in the wrapper script which will leave a bash process + in the background, therefore use with care. + ''; + }; options.exePath = lib.mkOption { type = lib.types.path; description = '' @@ -123,6 +146,9 @@ env = config.env; filesToPatch = config.filesToPatch; filesToExclude = config.filesToExclude; + preHook = config.preHook; + postHook = config.postHook; + patchHook = config.patchHook; passthru = { configuration = config; } diff --git a/modules/fastfetch/module.nix b/modules/fastfetch/module.nix new file mode 100644 index 0000000..92efe6e --- /dev/null +++ b/modules/fastfetch/module.nix @@ -0,0 +1,38 @@ +{ + config, + lib, + wlib, + ... +}: +let + jsonFmt = config.pkgs.formats.json { }; +in +{ + _class = "wrapper"; + options = { + settings = lib.mkOption { + type = jsonFmt.type; + default = { }; + description = '' + fastfetch settings + see + ''; + }; + "config.jsonc" = lib.mkOption { + type = wlib.types.file config.pkgs; + default.path = jsonFmt.generate "fastfetch-config" config.settings; + description = "fastfetch config file"; + }; + }; + config = { + package = config.pkgs.fastfetch; + flags."--config" = "${config."config.jsonc".path}"; + meta.maintainers = [ + { + name = "holly"; + github = "hollymlem"; + githubId = 35699052; + } + ]; + }; +} diff --git a/modules/foot/module.nix b/modules/foot/module.nix index 8e6e27d..e6ceb05 100644 --- a/modules/foot/module.nix +++ b/modules/foot/module.nix @@ -5,7 +5,7 @@ ... }: let - iniFmt = config.pkgs.formats.ini { + iniFmt = config.pkgs.formats.iniWithGlobalSection { # from https://github.com/NixOS/nixpkgs/blob/89f10dc1a8b59ba63f150a08f8cf67b0f6a2583e/nixos/modules/programs/foot/default.nix#L11-L29 listsAsDuplicateKeys = true; mkKeyValue = @@ -30,7 +30,12 @@ in _class = "wrapper"; options = { settings = lib.mkOption { - inherit (iniFmt) type; + type = lib.types.attrsOf ( + lib.types.oneOf [ + iniFmt.lib.types.atom + (lib.types.attrsOf iniFmt.lib.types.atom) + ] + ); default = { }; description = '' Configuration of foot terminal. @@ -40,13 +45,21 @@ in "foot.ini" = lib.mkOption { type = wlib.types.file config.pkgs; description = "foot.init configuration file."; - default.path = iniFmt.generate "foot.ini" config.settings; + default.path = iniFmt.generate "foot.ini" { + globalSection = lib.filterAttrs (name: value: builtins.typeOf value != "set") config.settings; + sections = lib.filterAttrs (name: value: builtins.typeOf value == "set") config.settings; + }; }; }; - config.flags = { - "--config" = toString config."foot.ini".path; + config = { + filesToPatch = [ "share/systemd/user/foot-server.service" ]; + flags = { + "--config" = toString config."foot.ini".path; + }; + package = config.pkgs.foot; + meta = { + maintainers = [ lib.maintainers.randomdude ]; + platforms = lib.platforms.linux; + }; }; - config.package = config.pkgs.foot; - config.meta.maintainers = [ lib.maintainers.randomdude ]; - config.meta.platforms = lib.platforms.linux; } diff --git a/modules/ghostty/module.nix b/modules/ghostty/module.nix index e394a06..4bcbcbc 100644 --- a/modules/ghostty/module.nix +++ b/modules/ghostty/module.nix @@ -54,17 +54,25 @@ in ''; }; }; - config.flagSeparator = "="; - config.flags = { - "--config-file" = toString config.configFile.path; + config = { + filesToPatch = [ + "share/dbus-1/services/com.mitchellh.ghostty.service" + "share/systemd/user/app-com.mitchellh.ghostty.service" + ]; + flagSeparator = "="; + flags = { + "--config-file" = toString config.configFile.path; + }; + package = config.pkgs.ghostty; + meta = { + platforms = lib.platforms.linux; + maintainers = [ + { + name = "turbio"; + github = "turbio"; + githubId = 1428207; + } + ]; + }; }; - config.package = config.pkgs.ghostty; - config.meta.platforms = lib.platforms.linux; - config.meta.maintainers = [ - { - name = "turbio"; - github = "turbio"; - githubId = 1428207; - } - ]; } diff --git a/modules/halloy/module.nix b/modules/halloy/module.nix new file mode 100644 index 0000000..50e4db7 --- /dev/null +++ b/modules/halloy/module.nix @@ -0,0 +1,73 @@ +{ + config, + wlib, + lib, + ... +}: +let + tomlFmt = config.pkgs.formats.toml { }; +in +{ + _class = "wrapper"; + options = { + settings = lib.mkOption { + type = tomlFmt.type; + default = { }; + }; + "config.toml" = lib.mkOption { + type = wlib.types.file config.pkgs; + default.path = tomlFmt.generate "halloy-config" config.settings; + }; + extraFiles = lib.mkOption { + type = lib.types.listOf ( + lib.types.submodule { + options = { + name = lib.mkOption { + type = lib.types.nonEmptyStr; + description = "File name in the halloy config directory"; + }; + file = lib.mkOption { + type = wlib.types.file config.pkgs; + description = "File or path to add in the halloy config directory"; + }; + }; + } + ); + default = [ ]; + description = "Additional files to be placed in the config directory"; + }; + }; + config = { + env = { + XDG_CONFIG_HOME = toString ( + config.pkgs.linkFarm "halloy-merged-config" ( + map + (a: { + inherit (a) path; + name = "halloy/" + a.name; + }) + ( + let + entry = name: path: { inherit name path; }; + in + [ (entry "config.toml" config."config.toml".path) ] + ++ (map (f: { + inherit (f) name; + path = f.file.path; + }) config.extraFiles) + ) + ) + ); + }; + package = config.pkgs.halloy; + meta = { + maintainers = [ + { + name = "holly"; + github = "hollymlem"; + githubId = 35699052; + } + ]; + }; + }; +} diff --git a/modules/helix/module.nix b/modules/helix/module.nix index d9f6277..1446ff5 100644 --- a/modules/helix/module.nix +++ b/modules/helix/module.nix @@ -87,11 +87,29 @@ in ignoreFile = lib.mkOption { type = wlib.types.file config.pkgs; }; + extraFiles = lib.mkOption { + type = lib.types.listOf ( + lib.types.submodule { + options = { + name = lib.mkOption { + type = lib.types.nonEmptyStr; + description = "File name in the helix config directory"; + }; + file = lib.mkOption { + type = wlib.types.file config.pkgs; + description = "File or path to add in the helix config directory"; + }; + }; + } + ); + default = [ ]; + description = "Additional files to be placed in the config directory"; + }; }; config.ignoreFile.content = lib.strings.concatLines config.ignores; config.package = config.pkgs.helix; config.env = { - XDG_CONFIG_HOME = builtins.toString ( + XDG_CONFIG_HOME = toString ( config.pkgs.linkFarm "helix-merged-config" ( map (a: { @@ -108,6 +126,10 @@ in (entry "ignore" config.ignoreFile.path) ] ++ themes + ++ (map (f: { + inherit (f) name; + path = f.file.path; + }) config.extraFiles) ) ) ); diff --git a/modules/hyprland/check.nix b/modules/hyprland/check.nix new file mode 100644 index 0000000..9602e45 --- /dev/null +++ b/modules/hyprland/check.nix @@ -0,0 +1,33 @@ +{ + pkgs, + self, +}: + +let + hyprlandWrapped = + (self.wrapperModules.hypr.apply { + inherit pkgs; + + "hypr.conf".content = '' + + dwindle { + pseudotile = yes + preserve_split = yes + special_scale_factor = 0.95 + } + + general { + layout = dwindle + } + + ''; + }).wrapper; + +in +pkgs.runCommand "hypr-test" { } '' + + export XDG_RUNTIME_DIR=/run/user/$(id -u) + "${hyprlandWrapped}/bin/hyprland" --version | grep -q "${hyprlandWrapped.version}" + + touch $out +'' diff --git a/modules/hyprland/module.nix b/modules/hyprland/module.nix new file mode 100644 index 0000000..0733139 --- /dev/null +++ b/modules/hyprland/module.nix @@ -0,0 +1,33 @@ +{ + config, + lib, + wlib, + ... +}: +{ + _class = "wrapper"; + options = { + "hypr.conf" = lib.mkOption { + type = wlib.types.file config.pkgs; + default.content = ""; + description = '' + for basic setup of one hypr.conf file + ''; + }; + }; + + config.flags = { + "--config" = toString config."hypr.conf".path; + }; + + config.package = config.pkgs.hyprland; + + config.meta.maintainers = [ + { + name = "PeDro0210"; + github = "PeDro0210"; + githubId = 123851480; + } + ]; + config.meta.platforms = lib.platforms.linux; +} diff --git a/modules/inori/module.nix b/modules/inori/module.nix new file mode 100644 index 0000000..262e00d --- /dev/null +++ b/modules/inori/module.nix @@ -0,0 +1,46 @@ +{ + config, + lib, + wlib, + ... +}: +let + tomlFmt = config.pkgs.formats.toml { }; +in +{ + _class = "wrapper"; + options = { + settings = lib.mkOption { + type = tomlFmt.type; + default = { }; + description = '' + Configuration of inori. + See + ''; + }; + "config.toml" = lib.mkOption { + type = wlib.types.file config.pkgs; + # TODO add a pure toTOML function + default.path = tomlFmt.generate "config.toml" config.settings; + description = "inori configuration file."; + }; + }; + config = { + env.XDG_CONFIG_HOME = "${config.pkgs.linkFarm ([ + { + name = "inori/config.toml"; + inherit (config."config.toml") path; + } + ])}"; + package = config.pkgs.inori; + meta = { + maintainers = [ + { + name = "holly"; + github = "hollymlem"; + githubId = 35699052; + } + ]; + }; + }; +} diff --git a/modules/kanshi/check.nix b/modules/kanshi/check.nix new file mode 100644 index 0000000..5d93671 --- /dev/null +++ b/modules/kanshi/check.nix @@ -0,0 +1,25 @@ +{ + pkgs, + self, +}: + +let + kanshiWrapped = + (self.wrapperModules.kanshi.apply { + inherit pkgs; + + configFile.content = '' + profile { + output eDP-1 enable scale 2 + } + ''; + + }).wrapper; + +in +pkgs.runCommand "kanshi-test" { } '' + + "${kanshiWrapped}/bin/kanshi" --help 2>&1 | grep -q "config" + + touch $out +'' diff --git a/modules/kanshi/module.nix b/modules/kanshi/module.nix new file mode 100644 index 0000000..24005b1 --- /dev/null +++ b/modules/kanshi/module.nix @@ -0,0 +1,35 @@ +{ + config, + lib, + wlib, + ... +}: +{ + _class = "wrapper"; + options = { + configFile = lib.mkOption { + type = wlib.types.file config.pkgs; + default.content = ""; + description = '' + Kanshi configuration file. + See {manpage}`kanshi(5)` for the configuration format. + ''; + example = '' + profile { + output LVDS-1 disable + output "Some Company ASDF 4242" mode 1600x900 position 0,0 + } + + profile nomad { + output LVDS-1 enable scale 2 + } + ''; + }; + }; + config.flags = { + "--config" = "${config.configFile.path}"; + }; + config.package = config.pkgs.kanshi; + config.meta.maintainers = [ lib.maintainers.adeci ]; + config.meta.platforms = lib.platforms.linux; +} diff --git a/modules/mako/module.nix b/modules/mako/module.nix index 8fb45bb..a79fb92 100644 --- a/modules/mako/module.nix +++ b/modules/mako/module.nix @@ -5,7 +5,7 @@ ... }: let - iniFormat = config.pkgs.formats.iniWithGlobalSection { }; + iniFormat = config.pkgs.formats.iniWithGlobalSection { listsAsDuplicateKeys = true; }; iniAtomType = iniFormat.lib.types.atom; in { @@ -13,7 +13,10 @@ in options = { configFile = lib.mkOption { type = wlib.types.file config.pkgs; - default.path = iniFormat.generate "mako-settings" { globalSection = config.settings; }; + default.path = iniFormat.generate "mako-settings" { + globalSection = lib.filterAttrs (name: value: builtins.typeOf value != "set") config.settings; + sections = lib.filterAttrs (name: value: builtins.typeOf value == "set") config.settings; + }; }; settings = lib.mkOption { @@ -31,20 +34,25 @@ in ''; }; }; - - config.flagSeparator = "="; - config.flags = { - "--config" = toString config.configFile.path; + config = { + flagSeparator = "="; + flags = { + "--config" = toString config.configFile.path; + }; + package = config.pkgs.mako; + filesToPatch = [ + "share/dbus-1/services/fr.emersion.mako.service" + "share/systemd/user/mako.service" + ]; + meta = { + maintainers = [ + { + name = "altacountbabi"; + github = "altacountbabi"; + githubId = 82091823; + } + ]; + platforms = lib.platforms.linux; + }; }; - - config.package = config.pkgs.mako; - - config.meta.maintainers = [ - { - name = "altacountbabi"; - github = "altacountbabi"; - githubId = 82091823; - } - ]; - config.meta.platforms = lib.platforms.linux; } diff --git a/modules/mpv/module.nix b/modules/mpv/module.nix index 695f086..7f11c56 100644 --- a/modules/mpv/module.nix +++ b/modules/mpv/module.nix @@ -12,7 +12,7 @@ default = [ ]; description = "Scripts to add to mpv via override."; }; - "mpv.input" = lib.mkOption { + "input.conf" = lib.mkOption { type = wlib.types.file config.pkgs; default.content = ""; }; @@ -23,7 +23,7 @@ }; config.flagSeparator = "="; config.flags = { - "--input-conf" = toString config."mpv.input".path; + "--input-conf" = toString config."input.conf".path; "--include" = toString config."mpv.conf".path; }; config.package = ( diff --git a/modules/niri/check.nix b/modules/niri/check.nix index 6f88afb..781f3ac 100644 --- a/modules/niri/check.nix +++ b/modules/niri/check.nix @@ -9,7 +9,12 @@ let inherit pkgs; settings = { binds = { - "Mod+T".spawn-sh = "alacritty"; + "Mod+T" = { + spawn-sh = "alacritty"; + _attrs = { + repeat = false; + }; + }; "Mod+J".focus-column-or-monitor-left = null; "Mod+N".spawn = [ "alacritty" @@ -70,6 +75,14 @@ let }; outputs = { + "DP-4" = { + position = { + _attrs = { + x = 1440; + y = 1080; + }; + }; + }; "DP-3" = { position = { x = 1440; diff --git a/modules/niri/module.nix b/modules/niri/module.nix index 8badca5..c7f7ce9 100644 --- a/modules/niri/module.nix +++ b/modules/niri/module.nix @@ -12,20 +12,26 @@ let leftpad = v: lib.strings.concatMapStrings (v: " ${v}\n") (lib.strings.splitString "\n" v); mkBlock = n: v: - if v != "" then - '' - ${n.name or n} ${ - # attrs must be qouted - let - attr = n._attrs or ""; - in - if attr != "" then ''"${attr}"'' else "" - } { + let + attrs = if builtins.isAttrs n then (n._attrs or "") else ""; + formattedAttrs = + if builtins.isAttrs attrs then + lib.concatMapAttrsStringSep " " (k: v: "${k}=${toVal v}") attrs + else if attrs != "" then + # string attrs must be quoted + ''"${attrs}"'' + else + ""; + body = lib.optionalString (v != "") '' + { ${leftpad v} - }'' - else - ""; - # surround strings with qoutes + } + ''; + in + '' + ${n.name or n} ${formattedAttrs} ${body} + ''; + # surround strings with quotes toVal = v: if lib.isString v then @@ -59,14 +65,12 @@ let else mkKeyVal n v ) a; - mkTagged = - t: k: v: - "${t} ${k}=${toVal v}"; + mkTagged = tag: attrs: "${tag} ${lib.concatMapAttrsStringSep " " (k: v: "${k}=${toVal v}") attrs}"; mkRule = block: r: let - matches = map (lib.concatMapAttrsStringSep "\n" (mkTagged "match")) r.matches or [ ]; - excludes = map (lib.concatMapAttrsStringSep "\n" (mkTagged "exclude")) r.excludes or [ ]; + matches = map (mkTagged "match") r.matches or [ ]; + excludes = map (mkTagged "exclude") r.excludes or [ ]; misc = attrsToKdl ( lib.attrsets.removeAttrs r [ "matches" @@ -128,7 +132,12 @@ in type = lib.types.attrs; description = "Bindings of niri"; example = { - "Mod+T".spawn-sh = "alacritty"; + "Mod+T" = { + spawn-sh = "alacritty"; + _attrs = { + repeat = false; + }; + }; "Mod+J".focus-column-or-monitor-left = null; "Mod+N".spawn = [ "alacritty" @@ -211,6 +220,12 @@ in example = { "DP-3" = { background-color = "#003300"; + position = { + _attrs = { + x = 0; + y = 0; + }; + }; hot-corners = { off = null; }; diff --git a/modules/swayosd/check.nix b/modules/swayosd/check.nix new file mode 100644 index 0000000..1b8b30a --- /dev/null +++ b/modules/swayosd/check.nix @@ -0,0 +1,24 @@ +{ + pkgs, + self, +}: + +let + swayosdWrapped = + (self.wrapperModules.swayosd.apply { + inherit pkgs; + + settings = { + server = { + max_volume = 150; + min_brightness = 5; + }; + }; + }).wrapper; + +in +pkgs.runCommand "swayosd-test" { } '' + test -x "${swayosdWrapped}/bin/swayosd-server" + + touch $out +'' diff --git a/modules/swayosd/module.nix b/modules/swayosd/module.nix new file mode 100644 index 0000000..1f3d1e2 --- /dev/null +++ b/modules/swayosd/module.nix @@ -0,0 +1,57 @@ +{ + config, + lib, + wlib, + ... +}: +let + tomlFmt = config.pkgs.formats.toml { }; +in +{ + _class = "wrapper"; + options = { + settings = lib.mkOption { + type = tomlFmt.type; + default = { }; + description = '' + SwayOSD server configuration. + See https://github.com/ErikReider/SwayOSD for available options. + ''; + example = lib.literalExpression '' + { + server = { + max_volume = 150; + min_brightness = 5; + top_margin = 0.85; + show_percentage = true; + }; + } + ''; + }; + "config.toml" = lib.mkOption { + type = wlib.types.file config.pkgs; + default.path = tomlFmt.generate "config.toml" config.settings; + description = "Generated SwayOSD configuration file."; + }; + style = lib.mkOption { + type = wlib.types.file config.pkgs; + default.content = ""; + description = '' + CSS stylesheet for SwayOSD appearance. + See the SwayOSD repository for styling examples. + ''; + }; + }; + + config.flags = { + "--config" = "${config."config.toml".path}"; + "--style" = if (config.style.content != "") then "${config.style.path}" else false; + }; + + config.exePath = lib.getExe' config.pkgs.swayosd "swayosd-server"; + + config.package = config.pkgs.swayosd; + + config.meta.maintainers = [ lib.maintainers.adeci ]; + config.meta.platforms = lib.platforms.linux; +} diff --git a/modules/way-edges/module.nix b/modules/way-edges/module.nix new file mode 100644 index 0000000..31acee7 --- /dev/null +++ b/modules/way-edges/module.nix @@ -0,0 +1,64 @@ +{ + config, + lib, + wlib, + ... +}: +let + jsonFmt = config.pkgs.formats.json { }; +in +{ + _class = "wrapper"; + options = { + settings = lib.mkOption { + type = jsonFmt.type; + default = { }; + description = '' + way-edges settings + see + ''; + example = { + widgets = [ + { + namespace = "workspaces"; + monitor = "*"; + edge = "left"; + position = "top"; + layer = "top"; + active-increase = 0; + default-color = "#1e1e2e"; + focus-color = "#f5c2e7"; + hover-color = "#f5c2e7"; + length = 200; + preset = { + type = "niri"; + }; + thickness = 8; + type = "workspace"; + } + ]; + }; + }; + configFile = lib.mkOption { + type = wlib.types.file config.pkgs; + default.path = jsonFmt.generate "way-edges-config" config.settings; + description = '' + way-edges config file + see + ''; + }; + }; + config = { + package = config.pkgs.way-edges; + flags = { + "--config-path" = toString config.configFile.path; + }; + meta.maintainers = [ + { + name = "holly"; + github = "hollymlem"; + githubId = 35699052; + } + ]; + }; +} diff --git a/modules/zsh/module.nix b/modules/zsh/module.nix index 9503f01..39b0bf8 100644 --- a/modules/zsh/module.nix +++ b/modules/zsh/module.nix @@ -33,6 +33,78 @@ in description = "cd into a directory just by typing it in"; }; + integrations = { + fzf = { + enable = lib.mkEnableOption "fzf"; + package = lib.mkOption { + type = lib.types.package; + default = config.pkgs.fzf; + }; + }; + atuin = { + enable = lib.mkEnableOption "atuin"; + package = lib.mkOption { + type = lib.types.package; + default = config.pkgs.atuin; + }; + }; + oh-my-posh = { + enable = lib.mkEnableOption "oh-my-posh"; + package = lib.mkOption { + type = lib.types.package; + default = config.pkgs.oh-my-posh; + }; + }; + starship = { + enable = lib.mkEnableOption "starship"; + package = lib.mkOption { + type = lib.types.package; + default = config.pkgs.starship; # Or self'.packages.starship, assuming you use flake parts + }; + }; + zoxide = { + enable = lib.mkEnableOption "zoxide"; + package = lib.mkOption { + type = lib.types.package; + default = config.pkgs.zoxide; + }; + flags = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + }; + }; + }; + + completion = { + enable = lib.mkEnableOption "completions"; + init = lib.mkOption { + default = "autoload -U compinit && compinit"; + description = "Initialization commands to run when completion is enabled."; + type = lib.types.lines; + }; + }; + + autoSuggestions = { + enable = lib.mkEnableOption "autoSuggestions"; + highlight = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + example = "fg=#ff00ff,bg=cyan,bold,underline"; + description = "Custom styles for autosuggestion highlighting"; + }; + + strategy = lib.mkOption { + type = lib.types.listOf ( + lib.types.enum [ + "history" + "completion" + "match_prev_cmd" + ] + ); + default = [ "history" ]; + }; + }; + history = { append = lib.mkOption { type = lib.types.bool; @@ -96,30 +168,68 @@ in description = "environment variables to put in .zshenv as an attribute set of strings just like environment.systemVariables"; }; }; + extraRC = lib.mkOption { type = lib.types.lines; default = ""; description = "extra stuff to put in .zshrc, gets appended *after* all of the options"; }; - ".zshrc" = lib.mkOption { - type = wlib.types.file config.pkgs; - default.content = builtins.concatStringsSep "\n" [ - ( - if cfg.keyMap == "viins" then - "bindkey -a" - else if cfg.keyMap == "vicmd" then - "bindkey -v" - else - "bindkey -e" - ) - (lib.concatMapAttrsStringSep "\n" (k: v: ''alias -- ${k}="${v}"'') cfg.shellAliases) - (if cfg.autocd then "setopt autocd" else "") - "HISTSIZE=${toString cfg.history.size}" - "HISTSAVE=${toString cfg.history.save}" - config.extraRC - ]; - }; + ".zshrc" = + let + zoxide-flags = lib.concatStringsSep " " cfg.integrations.zoxide.flags; + ing = cfg.integrations; + in + lib.mkOption { + type = wlib.types.file config.pkgs; + default.content = builtins.concatStringsSep "\n" [ + "# KeyMap" + ( + if cfg.keyMap == "viins" then + "bindkey -a" + else if cfg.keyMap == "vicmd" then + "bindkey -v" + else + "bindkey -e" + ) + (lib.optionalString cfg.autocd "setopt autocd") + + "# Aliases" + + (lib.concatMapAttrsStringSep "\n" (k: v: ''alias -- ${k}="${v}"'') cfg.shellAliases) + + "# Completion" + (lib.optionalString cfg.completion.enable cfg.completion.init) + + "#Autosuggestions" + (lib.optionalString cfg.autoSuggestions.enable '' + source ${config.pkgs.zsh-autosuggestions}/share/zsh-autosuggestions/zsh-autosuggestions.zsh + ${lib.optionalString (cfg.autoSuggestions.strategy != [ ]) '' + ZSH_AUTOSUGGEST_STRATEGY=(${lib.concatStringsSep " " cfg.autoSuggestions.strategy}) + ''} + + ${lib.optionalString (cfg.autoSuggestions.highlight != null) '' + ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE=(${cfg.autoSuggestions.highlight}) + ''} + '') + + "# Integrations" + (lib.optionalString ing.fzf.enable "source <(fzf --zsh)") + (lib.optionalString ing.atuin.enable ''eval "$(atuin init zsh)"'') + (lib.optionalString ing.oh-my-posh.enable ''eval "$(oh-my-posh init zsh)"'') + (lib.optionalString ing.zoxide.enable ''eval "$(zoxide init zsh ${zoxide-flags})"'') + (lib.optionalString ing.starship.enable ''eval "$(starship init zsh)"'') + + "# History" + + "HISTSIZE=${toString cfg.history.size}" + "HISTSAVE=${toString cfg.history.save}" + + "# Extra Content" + + config.extraRC + ]; + }; ".zshenv" = lib.mkOption { type = wlib.types.file config.pkgs; @@ -128,8 +238,20 @@ in ]; }; }; + config = { package = config.pkgs.zsh; + extraPackages = + let + ing = cfg.integrations; + in + lib.optional ing.fzf.enable ing.fzf.package + ++ lib.optional ing.atuin.enable ing.atuin.package + ++ lib.optional ing.zoxide.enable ing.zoxide.package + ++ lib.optional ing.oh-my-posh.enable ing.oh-my-posh.package + ++ lib.optional ing.starship.enable ing.starship.package + ++ lib.optional cfg.completion.enable config.pkgs.nix-zsh-completions; + flags = { "--histfcntllock" = true; "--histappend" = cfg.history.append; @@ -141,6 +263,7 @@ in "--histsavenodups" = cfg.history.saveNoDups; "--histexpand" = cfg.history.expanded; }; + env.ZDOTDIR = builtins.toString ( config.pkgs.linkFarm "zsh-merged-config" [ {