From fed4c281524c8ef8f3c127d65aa1af069c5b6c26 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Tue, 14 Dec 2021 03:29:41 +0100 Subject: [PATCH] Extract some common logic into a lib overlay --- nixpkgs/home.nix | 9 +- nixpkgs/overlays/lib/attrsets.nix | 12 +++ nixpkgs/overlays/lib/default.nix | 9 ++ nixpkgs/overlays/lib/lists.nix | 14 +++ nixpkgs/overlays/lib/strings.nix | 39 ++++++++ nixpkgs/overlays/lib/termColors.nix | 48 +++++++++ nixpkgs/shellOptions.nix | 145 +++++++++++++++++----------- 7 files changed, 214 insertions(+), 62 deletions(-) create mode 100644 nixpkgs/overlays/lib/attrsets.nix create mode 100644 nixpkgs/overlays/lib/default.nix create mode 100644 nixpkgs/overlays/lib/lists.nix create mode 100644 nixpkgs/overlays/lib/strings.nix create mode 100644 nixpkgs/overlays/lib/termColors.nix diff --git a/nixpkgs/home.nix b/nixpkgs/home.nix index f00c033..817cf8b 100644 --- a/nixpkgs/home.nix +++ b/nixpkgs/home.nix @@ -1,8 +1,6 @@ -{ pkgs ? import {}, lib ? pkgs.lib, ... } @ args: - +{ pkgs, lib, ... } @ args: let colorType = with lib.types; (attrsOf str); - colorTheme = import ./common/colors.nix; in { @@ -10,6 +8,11 @@ in inherit colorTheme; }; + # FIXME: this isn't really working? see shellOptions + nixpkgs.overlays = [ + (import ./overlays/lib) + ]; + imports = [ ./shellOptions.nix ./packages.nix diff --git a/nixpkgs/overlays/lib/attrsets.nix b/nixpkgs/overlays/lib/attrsets.nix new file mode 100644 index 0000000..a54acf8 --- /dev/null +++ b/nixpkgs/overlays/lib/attrsets.nix @@ -0,0 +1,12 @@ +self: super: +let + inherit (super.lib.attrsets) listToAttrs nameValuePair; + inherit (super.lib.lists) foldr; +in super.lib.attrsets // { + # a -> [String] -> AttrSet{a} + mapToAttrsWithConst = constant: items: + listToAttrs (map (name: nameValuePair name constant) items); + + # [AttrSet] -> AttrSet + concatAttrs = foldr (a: b: a // b) {}; +} diff --git a/nixpkgs/overlays/lib/default.nix b/nixpkgs/overlays/lib/default.nix new file mode 100644 index 0000000..41a2936 --- /dev/null +++ b/nixpkgs/overlays/lib/default.nix @@ -0,0 +1,9 @@ +self: super: +{ + lib = super.lib // { + attrsets = import ./attrsets.nix self super; + lists = import ./lists.nix self super; + strings = import ./strings.nix self super; + termColors = import ./termColors.nix self super; + }; +} diff --git a/nixpkgs/overlays/lib/lists.nix b/nixpkgs/overlays/lib/lists.nix new file mode 100644 index 0000000..fb9dfad --- /dev/null +++ b/nixpkgs/overlays/lib/lists.nix @@ -0,0 +1,14 @@ +self: super: +let + inherit (super.lib.trivial) const; + inherit (super.lib.lists) range any all; +in super.lib.lists // { + # a -> Int -> [a] + repeat = item: times: map (const item) (range 1 times); + + # [Bool] -> Bool + any' = any (boolean: boolean); + + # [Bool] -> Bool + all' = all (boolean: boolean); +} diff --git a/nixpkgs/overlays/lib/strings.nix b/nixpkgs/overlays/lib/strings.nix new file mode 100644 index 0000000..637b35e --- /dev/null +++ b/nixpkgs/overlays/lib/strings.nix @@ -0,0 +1,39 @@ +self: super: +let + inherit (self.lib.lists) repeat length; + inherit (super.lib.strings) concatStringsSep replaceStrings splitString; +in super.lib.strings // rec { + # String -> [String] + lines = splitString "\n"; + + # String -> (String -> String) -> String -> String + splitMap = splitter: f: string: + concatStringsSep splitter (map f (splitString splitter string)); + + # (String -> String) -> String -> String + mapLines = splitMap "\n" + + # String -> Int -> String + repeatString = string: times: concatStringsSep "" (repeat string times); + + # Replaces any occurences in a list of strings with a single replacement. + # NOTE: This function does not support regex patterns. + # + # [String] -> String -> String -> String + replaceStrings' = from: to: replaceStrings from (repeat to (length from)); + + # [String] -> String + unlines = concatStringsSep "\n"; + + # [String] -> String + unwords = concatStringsSep " "; + + # String -> [String] + words = builtins.split "\\s+"; + + # String -> String -> String -> String + wrap = start: end: string: start + string + end; + + # String -> String -> String + wrap' = wrapper: wrap wrapper wrapper; +} diff --git a/nixpkgs/overlays/lib/termColors.nix b/nixpkgs/overlays/lib/termColors.nix new file mode 100644 index 0000000..0879ac5 --- /dev/null +++ b/nixpkgs/overlays/lib/termColors.nix @@ -0,0 +1,48 @@ +self: super: +let + inherit (self.lib.strings) wrap; + inherit (super.lib.attrsets) mapAttrs' nameValuePair; +in rec { + # String + escapeCharacter = ""; + + # String -> String + escapeColor = color: "${escapeCharacter}[${color}m"; + + # String + resetCharacter = escapeColor "0"; + + # String -> String -> String + wrapWithColor = color: wrap color resetCharacter; + + # String -> String -> String + wrapWithColor' = color: wrap (escapeColor color) resetCharacter; + + # AttrSet{String} + colorMappings = { + "black" = "0"; + "red" = "1"; + "green" = "2"; + "yellow" = "3"; + "blue" = "4"; + "magenta" = "5"; + "cyan" = "6"; + "white" = "7"; + }; + + # AttrSet{(String -> String)} + front = let + # AttrSet{(String -> String)} + names = mapAttrs' (n: v: nameValuePair n (wrapWithColor' ("3" + v))) colorMappings; + + # AttrSet{(String -> String)} + numbers = mapAttrs' (n: v: nameValuePair v (wrapWithColor' ("3" + v))) colorMappings; + in names // numbers; + back = let + # AttrSet{(String -> String)} + names = mapAttrs' (n: v: nameValuePair n (wrapWithColor' ("4" + v))) colorMappings; + + # AttrSet{(String -> String)} + numbers = mapAttrs' (n: v: nameValuePair v (wrapWithColor' ("4" + v))) colorMappings; + in names // numbers; +} diff --git a/nixpkgs/shellOptions.nix b/nixpkgs/shellOptions.nix index 2cb2210..7c30903 100644 --- a/nixpkgs/shellOptions.nix +++ b/nixpkgs/shellOptions.nix @@ -1,5 +1,11 @@ -{ pkgs ? import {}, lib ? pkgs.lib, config ? pkgs.config, ... }: +{ config, ... }: let + # TODO: These should really be inputs in the main function, and the + # overlaying should be happening in home.nix. I wasn't able to + # make it work though. + pkgs = import { overlays = [(import ./overlays/lib)]; }; + lib = pkgs.lib; + sedColor = color: inputPattern: @@ -10,13 +16,10 @@ let colorSlashes = colorRed "/" {middle = "/";}; - red = s: "${s}"; - green = s: "${s}"; - blue = s: "${s}"; - # Context Functors functors = let inherit (lib.strings) concatStringsSep; + inherit (lib.termColors.front) blue; in { shellPipe = { wrap = s: { @@ -32,16 +35,13 @@ let value = s; }; apply = f: concatStringsSep " " f.value; - stringify = f: concatStringsSep (" \\\n " f.value; + stringify = f: concatStringsSep " \\\n " f.value; }; }; # AttrSet -> Bool isFunctor = attrset: if !(attrset ? "type") then false else lib.lists.any (f: (f.wrap "").type == attrset.type) (lib.attrsets.attrValues functors); - repeatItem = n: item: map (lib.trivial.const item) (lib.lists.range 1 n); - repeatString = n: string: lib.strings.concatStrings (repeatItem n string); - in rec { _module.args.shellOptions = { aliases = let @@ -141,7 +141,7 @@ in rec { "ls -l /proc/$(pidof dropbox)/fd" "egrep -v 'pipe:|socket:|/dev'" "grep \"${config.services.dropbox.path}/[^.]\"" - ]; + ]; subdirs-to-cbz = join [ "for dir in \"./*\"; do" @@ -240,24 +240,44 @@ in rec { "Generated" = { "cds" = let - inherit (lib.strings) concatStrings concatStringsSep; - inherit (lib.lists) range flatten; - inherit (lib.attrsets) nameValuePair; + inherit (lib.strings) concatStringsSep repeatString; + inherit (lib.lists) range flatten repeat; + inherit (lib.attrsets) nameValuePair listToAttrs; nthCds = n: [ - ("cd" + (repeatString (n + 1) ".")) + ("cd" + (repeatString "." (n + 1))) ("cd." + toString n) - (repeatString (n + 1) ".") + (repeatString "." (n + 1)) ("." + toString n) (".." + toString n) ]; - realCommand = n: "cd " + (concatStringsSep "/" (repeatItem n "..")); + realCommand = n: "cd " + (concatStringsSep "/" (repeat ".." n)); nthCdsAsNameValuePairs = n: map (cmd: nameValuePair cmd (realCommand n)) (nthCds n); - allCdNameValuePairs = (flatten (map nthCdsAsNameValuePairs (range 1 9))); + allCdNameValuePairs = flatten (map nthCdsAsNameValuePairs (range 1 9)); in - lib.attrsets.listToAttrs allCdNameValuePairs; + listToAttrs allCdNameValuePairs; }; + "Package Managers" = let + inherit (lib.attrsets) nameValuePair listToAttrs; + + packageManagers = [ + "apt" + "dpkg" + "flatpak" + "pacman" + "pamac" + "paru" + "rpm" + "snap" + "xbps" + "yay" + "yum" + ]; + + command = "${coreutils}/bin/cat $HOME/${config.home.file.packageManagerLecture.target}"; + nameValuePairs = map (pm: nameValuePair pm command) packageManagers; + in listToAttrs nameValuePairs; }; # TODO: flatten functions @@ -282,8 +302,7 @@ in rec { }; flattened.aliases = let - inherit (lib.attrsets) mapAttrs attrValues filterAttrs isAttrs; - inherit (lib.lists) foldr partition; + inherit (lib.attrsets) mapAttrs attrValues filterAttrs isAttrs concatAttrs; inherit (lib.strings) isString concatStringsSep; applyFunctor = attrset: functors.${attrset.type}.apply attrset; @@ -307,53 +326,61 @@ in rec { recursedAliasSets = filteredAliases ++ (remainingFunctors) ++ (map allAttrValuesAreStrings remainingAliasSets); - in foldr (a: b: a // b) {} recursedAliasSets; + in concatAttrs recursedAliasSets; in allAttrValuesAreStrings _module.args.shellOptions.aliases; }; - home.file.aliases = { - text = let - inherit (lib.strings) concatStringsSep replaceStrings substring stringLength; - inherit (lib.attrsets) attrValues mapAttrs isAttrs; - inherit (lib.lists) remove length range tail; - inherit (lib.trivial) const; + home.file = { + aliases = { + target = ".local/share/aliases"; + text = let + inherit (lib.strings) unlines wrap' replaceStrings' stringLength repeatString; + inherit (lib.attrsets) attrValues mapAttrs isAttrs; + inherit (lib.lists) remove; + inherit (lib.trivial) mapNullable; + inherit (lib.termColors.front) red green blue; - # int -> String -> AttrSet -> String - stringifyCategory = level: name: category: - concatStringsSep "\n" - (["${repeatString level " "}[${green name}]"] ++ - (attrValues (mapAttrs (n: v: let - # String - indent = repeatString level " "; + # int -> String -> AttrSet -> String + stringifyCategory = level: name: category: + unlines + (["${repeatString " " level}[${green name}]"] ++ + (attrValues (mapAttrs (n: v: let + # String + indent = repeatString " " level; - # String -> String -> String - wrap' = w: s: w + s + w; + # String -> String + removeNixLinks = text: let + maybeMatches = builtins.match "(|.*[^)])(/nix/store/.*/bin/).*" text; + matches = mapNullable (remove "") maybeMatches; + in if (maybeMatches == null) + then text + else replaceStrings' matches "" text; - # String -> String - removeNixLinks = text: let - maybeMatches = (builtins.match "(|.*[^)])(/nix/store/.*/bin/).*" text); - matches = if (maybeMatches == null) then null else remove "" maybeMatches; - listOfEmptyStrings = map (const "") (range 1 (length matches)); + applyFunctor = attrset: let + applied = functors.${attrset.type}.stringify attrset; + indent' = "${indent} ${repeatString " " (stringLength n)}"; + in replaceStrings' ["\n"] ("\n" + indent') applied; + + recurse = stringifyCategory (level + 1) n v; in - if (maybeMatches == null) - then text - else replaceStrings matches listOfEmptyStrings text; - - applyFunctor = attrset: let - applied = functors.${attrset.type}.stringify attrset; - indent' = indent + " " + (repeatString (stringLength n) " "); - indented = replaceStrings ["\n"] [("\n" + indent')] applied; - in indented; - - recurse = stringifyCategory (level + 1) n v; - in - if !(isAttrs v) then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks v)}" else - if isFunctor v then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks (applyFunctor v))}" else - recurse) category))); - in - (stringifyCategory 0 "Aliases" _module.args.shellOptions.aliases) + "\n"; - target = ".local/share/aliases"; + if !(isAttrs v) then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks v)}" else + if isFunctor v then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks (applyFunctor v))}" else + recurse) category))); + in + (stringifyCategory 0 "Aliases" _module.args.shellOptions.aliases) + "\n"; + }; + packageManagerLecture = { + target = ".local/share/package-manager.lecture"; + text = let + inherit (lib.strings) unlines; + inherit (lib.termColors.front) red blue; + in unlines [ + ((red "This package manager is not installed on ") + (blue "NixOS") + (red ".")) + ((red "Either use ") + ("\"nix-env -i\"") + (red "or install it through a configuration file.")) + "" + ]; + }; }; }