Extract some common logic into a lib overlay

This commit is contained in:
Oystein Kristoffer Tveit 2021-12-14 03:29:41 +01:00
parent e0e34a98ac
commit fed4c28152
7 changed files with 214 additions and 62 deletions

View File

@ -1,8 +1,6 @@
{ pkgs ? import <nixpkgs> {}, lib ? pkgs.lib, ... } @ args: { pkgs, lib, ... } @ args:
let let
colorType = with lib.types; (attrsOf str); colorType = with lib.types; (attrsOf str);
colorTheme = import ./common/colors.nix; colorTheme = import ./common/colors.nix;
in in
{ {
@ -10,6 +8,11 @@ in
inherit colorTheme; inherit colorTheme;
}; };
# FIXME: this isn't really working? see shellOptions
nixpkgs.overlays = [
(import ./overlays/lib)
];
imports = [ imports = [
./shellOptions.nix ./shellOptions.nix
./packages.nix ./packages.nix

View File

@ -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) {};
}

View File

@ -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;
};
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,5 +1,11 @@
{ pkgs ? import <nixos> {}, lib ? pkgs.lib, config ? pkgs.config, ... }: { config, ... }:
let 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 <nixos> { overlays = [(import ./overlays/lib)]; };
lib = pkgs.lib;
sedColor = sedColor =
color: color:
inputPattern: inputPattern:
@ -10,13 +16,10 @@ let
colorSlashes = colorRed "/" {middle = "/";}; colorSlashes = colorRed "/" {middle = "/";};
red = s: "${s}";
green = s: "${s}";
blue = s: "${s}";
# Context Functors # Context Functors
functors = let functors = let
inherit (lib.strings) concatStringsSep; inherit (lib.strings) concatStringsSep;
inherit (lib.termColors.front) blue;
in { in {
shellPipe = { shellPipe = {
wrap = s: { wrap = s: {
@ -32,16 +35,13 @@ let
value = s; value = s;
}; };
apply = f: concatStringsSep " " f.value; apply = f: concatStringsSep " " f.value;
stringify = f: concatStringsSep (" \\\n " f.value; stringify = f: concatStringsSep " \\\n " f.value;
}; };
}; };
# AttrSet -> Bool # AttrSet -> Bool
isFunctor = attrset: if !(attrset ? "type") then false else lib.lists.any (f: (f.wrap "").type == attrset.type) (lib.attrsets.attrValues functors); 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 { in rec {
_module.args.shellOptions = { _module.args.shellOptions = {
aliases = let aliases = let
@ -141,7 +141,7 @@ in rec {
"ls -l /proc/$(pidof dropbox)/fd" "ls -l /proc/$(pidof dropbox)/fd"
"egrep -v 'pipe:|socket:|/dev'" "egrep -v 'pipe:|socket:|/dev'"
"grep \"${config.services.dropbox.path}/[^.]\"" "grep \"${config.services.dropbox.path}/[^.]\""
]; ];
subdirs-to-cbz = join [ subdirs-to-cbz = join [
"for dir in \"./*\"; do" "for dir in \"./*\"; do"
@ -240,24 +240,44 @@ in rec {
"Generated" = { "Generated" = {
"cds" = let "cds" = let
inherit (lib.strings) concatStrings concatStringsSep; inherit (lib.strings) concatStringsSep repeatString;
inherit (lib.lists) range flatten; inherit (lib.lists) range flatten repeat;
inherit (lib.attrsets) nameValuePair; inherit (lib.attrsets) nameValuePair listToAttrs;
nthCds = n: [ nthCds = n: [
("cd" + (repeatString (n + 1) ".")) ("cd" + (repeatString "." (n + 1)))
("cd." + toString n) ("cd." + toString n)
(repeatString (n + 1) ".") (repeatString "." (n + 1))
("." + toString n) ("." + toString n)
(".." + 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); 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 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 # TODO: flatten functions
@ -282,8 +302,7 @@ in rec {
}; };
flattened.aliases = let flattened.aliases = let
inherit (lib.attrsets) mapAttrs attrValues filterAttrs isAttrs; inherit (lib.attrsets) mapAttrs attrValues filterAttrs isAttrs concatAttrs;
inherit (lib.lists) foldr partition;
inherit (lib.strings) isString concatStringsSep; inherit (lib.strings) isString concatStringsSep;
applyFunctor = attrset: functors.${attrset.type}.apply attrset; applyFunctor = attrset: functors.${attrset.type}.apply attrset;
@ -307,53 +326,61 @@ in rec {
recursedAliasSets = filteredAliases recursedAliasSets = filteredAliases
++ (remainingFunctors) ++ (remainingFunctors)
++ (map allAttrValuesAreStrings remainingAliasSets); ++ (map allAttrValuesAreStrings remainingAliasSets);
in foldr (a: b: a // b) {} recursedAliasSets; in concatAttrs recursedAliasSets;
in in
allAttrValuesAreStrings _module.args.shellOptions.aliases; allAttrValuesAreStrings _module.args.shellOptions.aliases;
}; };
home.file.aliases = { home.file = {
text = let aliases = {
inherit (lib.strings) concatStringsSep replaceStrings substring stringLength; target = ".local/share/aliases";
inherit (lib.attrsets) attrValues mapAttrs isAttrs; text = let
inherit (lib.lists) remove length range tail; inherit (lib.strings) unlines wrap' replaceStrings' stringLength repeatString;
inherit (lib.trivial) const; 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 # int -> String -> AttrSet -> String
stringifyCategory = level: name: category: stringifyCategory = level: name: category:
concatStringsSep "\n" unlines
(["${repeatString level " "}[${green name}]"] ++ (["${repeatString " " level}[${green name}]"] ++
(attrValues (mapAttrs (n: v: let (attrValues (mapAttrs (n: v: let
# String # String
indent = repeatString level " "; indent = repeatString " " level;
# String -> String -> String # String -> String
wrap' = w: s: w + s + w; 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 applyFunctor = attrset: let
removeNixLinks = text: let applied = functors.${attrset.type}.stringify attrset;
maybeMatches = (builtins.match "(|.*[^)])(/nix/store/.*/bin/).*" text); indent' = "${indent} ${repeatString " " (stringLength n)}";
matches = if (maybeMatches == null) then null else remove "" maybeMatches; in replaceStrings' ["\n"] ("\n" + indent') applied;
listOfEmptyStrings = map (const "") (range 1 (length matches));
recurse = stringifyCategory (level + 1) n v;
in in
if (maybeMatches == null) if !(isAttrs v) then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks v)}" else
then text if isFunctor v then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks (applyFunctor v))}" else
else replaceStrings matches listOfEmptyStrings text; recurse) category)));
in
applyFunctor = attrset: let (stringifyCategory 0 "Aliases" _module.args.shellOptions.aliases) + "\n";
applied = functors.${attrset.type}.stringify attrset; };
indent' = indent + " " + (repeatString (stringLength n) " "); packageManagerLecture = {
indented = replaceStrings ["\n"] [("\n" + indent')] applied; target = ".local/share/package-manager.lecture";
in indented; text = let
inherit (lib.strings) unlines;
recurse = stringifyCategory (level + 1) n v; inherit (lib.termColors.front) red blue;
in in unlines [
if !(isAttrs v) then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks v)}" else ((red "This package manager is not installed on ") + (blue "NixOS") + (red "."))
if isFunctor v then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks (applyFunctor v))}" else ((red "Either use ") + ("\"nix-env -i\"") + (red "or install it through a configuration file."))
recurse) category))); ""
in ];
(stringifyCategory 0 "Aliases" _module.args.shellOptions.aliases) + "\n"; };
target = ".local/share/aliases";
}; };
} }