From 437ea9cdda6cd54a8148e57378157dfde75825d5 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Mon, 13 Dec 2021 00:35:22 +0100 Subject: [PATCH] Modularize nix config more --- nixpkgs/home.nix | 173 +++------ nixpkgs/packages.nix | 116 ++++++ nixpkgs/programs/zsh.nix | 174 +-------- nixpkgs/secret/default.nix | 1 + nixpkgs/secret/programs/newsboat/default.nix | 2 +- nixpkgs/shellOptions.nix | 359 +++++++++++++++++++ 6 files changed, 546 insertions(+), 279 deletions(-) create mode 100644 nixpkgs/packages.nix create mode 100644 nixpkgs/shellOptions.nix diff --git a/nixpkgs/home.nix b/nixpkgs/home.nix index ff6eb24..f00c033 100644 --- a/nixpkgs/home.nix +++ b/nixpkgs/home.nix @@ -1,4 +1,4 @@ -{ lib, pkgs, ... } @ args: +{ pkgs ? import {}, lib ? pkgs.lib, ... } @ args: let colorType = with lib.types; (attrsOf str); @@ -6,9 +6,14 @@ let colorTheme = import ./common/colors.nix; in { - _module.args.colorTheme = colorTheme; + _module.args = { + inherit colorTheme; + }; imports = [ + ./shellOptions.nix + ./packages.nix + ./misc/mimetypes.nix ./programs/alacritty.nix @@ -32,17 +37,17 @@ in ./services/stalonetray.nix ./services/sxhkd.nix - ./secret/ssh/hosts + ./secret ]; - xsession = { - pointerCursor = { - package = pkgs.capitaine-cursors; - name = "capitaine-cursors"; - size = 16; - }; + home = { + stateVersion = "21.05"; + username = "h7x4"; + homeDirectory = "/home/h7x4"; }; + news.display = "silent"; + programs = { home-manager.enable = true; @@ -84,118 +89,6 @@ in zoxide.enable = true; }; - home = { - stateVersion = "21.05"; - username = "h7x4"; - homeDirectory = "/home/h7x4"; - packages = with pkgs; [ - ahoviewer - anki - asciidoctor - audacity - beets - biber - calibre - castnow - citra - cool-retro-term - copyq - czkawka - darktable - desmume - discord - diskonaut - diskus - docker - du-dust - fcitx - fd - ffmpeg - geogebra - gnome.gnome-font-viewer - google-chrome - # gpgtui - graphviz - # hck - hexyl - imagemagick - inkscape - insomnia - jq - kepubify - kid3 - koreader - krita - ktouch - lastpass-cli - lazydocker - libreoffice-fresh - light - lolcat - maim - mdcat - mdp - mediainfo - megacmd - megasync - micro - minecraft - mkvtoolnix - mmv - mopidy - mopidy-mpd - mopidy-soundcloud - mopidy-spotify - mopidy-youtube - mpc_cli - mps-youtube - neofetch - nmap - nyxt - osu-lazer - pandoc - pulseaudio - pulsemixer - python3 - ripgrep - rsync - sc-im - scrcpy - slack - slack-term - # steam-tui - sxiv - tagainijisho - taisei - tealdeer - teams - # tenacity - # tv-renamer - toilet - tokei - touchegg - w3m - waifu2x-converter-cpp - wavemon - xcalib - xclip - xdotool - youtube-dl - # yuzu-mainline - zeal - zoom-us - zotero - - # Needed for VSCode liveshare - desktop-file-utils - krb5 - zlib - icu - openssl - xorg.xprop - ]; - }; - services = { gnome-keyring.enable = true; dropbox.enable = true; @@ -203,5 +96,41 @@ in # redshift.enable = true; }; -} + manual = { + html.enable = true; + manpages.enable = true; + json.enable = true; + }; + gtk = { + enable = true; + font = { + name = "Droid Sans"; + }; + iconTheme = { + package = pkgs.papirus-icon-theme; + name = "Papirus"; + }; + theme = { + package = pkgs.vimix-gtk-themes; + name = "VimixDark"; + }; + }; + + qt = { + enable = true; + platformTheme = "gtk"; + style = { + name = "adwaita-dark"; + package = pkgs.adwaita-qt; + }; + }; + + xsession = { + pointerCursor = { + package = pkgs.capitaine-cursors; + name = "capitaine-cursors"; + size = 16; + }; + }; +} diff --git a/nixpkgs/packages.nix b/nixpkgs/packages.nix new file mode 100644 index 0000000..6a0e618 --- /dev/null +++ b/nixpkgs/packages.nix @@ -0,0 +1,116 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + ahoviewer + anki + asciidoctor + audacity + beets + biber + calibre + castnow + citra + cool-retro-term + copyq + czkawka + darktable + desmume + discord + diskonaut + diskus + docker + du-dust + fcitx + fd + ffmpeg + geogebra + gnome.gnome-font-viewer + google-chrome + # gpgtui + graphviz + # hck + hexyl + imagemagick + inkscape + insomnia + jq + kepubify + kid3 + koreader + krita + ktouch + lastpass-cli + lazydocker + libreoffice-fresh + light + lolcat + maim + mdcat + mdp + mediainfo + megacmd + megasync + micro + minecraft + mkvtoolnix + mmv + mopidy + mopidy-mpd + mopidy-soundcloud + mopidy-spotify + mopidy-youtube + mpc_cli + mps-youtube + neofetch + nmap + nyxt + osu-lazer + ouch + pandoc + pulseaudio + pulsemixer + python3 + ripgrep + rsync + sc-im + scrcpy + slack + slack-term + # steam-tui + sxiv + tagainijisho + taisei + tealdeer + teams + # tenacity + # tv-renamer + toilet + tokei + touchegg + w3m + waifu2x-converter-cpp + wavemon + xcalib + xclip + xdotool + xfce.thunar + xfce.thunar-archive-plugin + xfce.thunar-dropbox-plugin + xfce.thunar-media-tags-plugin + xfce.thunar-volman + youtube-dl + # yuzu-mainline + zeal + zoom-us + zotero + + # Needed for VSCode liveshare + desktop-file-utils + krb5 + zlib + icu + openssl + xorg.xprop + ]; +} + diff --git a/nixpkgs/programs/zsh.nix b/nixpkgs/programs/zsh.nix index a772358..0b45f06 100644 --- a/nixpkgs/programs/zsh.nix +++ b/nixpkgs/programs/zsh.nix @@ -1,4 +1,4 @@ -{ pkgs, lib, config, ... }: +{ pkgs, lib, config, shellOptions, ... }: { programs.zsh = rec { enable = true; @@ -39,163 +39,25 @@ # } ]; - localVariables = { - POWERLEVEL9K_LEFT_PROMPT_ELEMENTS = ["dir" "vcs"]; - # NIX_PATH = ''$HOME/.nix-defexpr/channels$\{NIX_PATH:+:}$NIX_PATH''; - }; + localVariables = shellOptions.variables; - shellAliases = with pkgs; let - - sedColor = - color: - inputPattern: - outputPattern: - "-e \"s|${inputPattern}|${outputPattern.before or ""}$(tput setaf ${toString color})${outputPattern.middle}$(tput op)${outputPattern.after or ""}|g\""; - - colorRed = sedColor 1; - - shellPipe = lib.strings.concatStringsSep " | "; - join = lib.strings.concatStringsSep " "; - - in { - - # This for some reason uses an outdated version of hm - # hs = "${pkgs.home-manager}/bin/home-manager switch"; - - hms = "home-manager switch"; - nxr = "sudo ${nixos-rebuild}/bin/nixos-rebuild switch"; - nxc = "sudoedit /etc/nixos/configuration.nix"; - ns = "nix-shell"; - - # Having 'watch' with a space after as an alias, enables it to expand other aliases - watch = "${procps}/bin/watch "; - - m = "${ncmpcpp}/bin/ncmpcpp"; - p = "${python39Packages.ipython}/bin/ipython"; - - lls = "${coreutils}/bin/ls"; - ls = "${exa}/bin/exa"; - la = "${exa}/bin/exa -lah --changed --time-style long-iso --git --group"; - lsa = "la"; - - killall = "echo \"killall is dangerous on non-gnu platforms. Using 'pkill -x'\"; pkill -x"; - - youtube-dl-list = join [ - "${youtube-dl}/bin/youtube-dl" - "-f \"bestvideo[ext=mp4]+bestaudio[e=m4a]/bestvideo+bestaudio\"" - "-o \"%(playlist_index)s-%(title)s.%(ext)s\"" - ]; - - music-dl = "${youtube-dl}/bin/youtube-dl --extract-audio -f \"bestaudio[ext=m4a]/best\""; - music-dl-list = join [ - "${youtube-dl}/bin/youtube-dl" - "--extract-audio" - "-f \"bestaudio[ext=m4a]/best\"" - "-o \"%(playlist_index)s-%(title)s.%(ext)s\"" - ]; - - skusho = "${maim}/bin/maim --hidecursor --nokeyboard $(echo $SCREENSHOT_DIR)/$(date_%s).png"; - skushoclip = shellPipe [ - "${maim}/bin/maim --hidecursor --nokeyboard --select" - "${xclip}/bin/xclip -selection clipboard -target image/png -in" - - ]; - - view-latex = "${texlive.combined.scheme-full}/bin/latexmk -pdf -pvc main.tex"; - - reload-tmux = "${tmux}/bin/tmux source $HOME/.config/tmux/tmux.conf"; - - ag="${ripgrep}/bin/rg"; - - dp = "${dropbox-cli}/bin/dropbox"; - - cd = "z"; - - ccp = "${coreutils}/bin/cp"; - cp = "${rsync}/bin/rsync --progress --human-readable"; - cpr = "${rsync}/bin/rsync --progress --human-readable --recursive"; - - ccat = "${coreutils}/bin/cat"; - cat = "${bat}/bin/bat"; - - htop = "${bottom}/bin/bottom"; - - ps = "${procs}/bin/procs"; - - fin = "${fd}/bin/fd"; - - ip = "ip -c"; - - regex-escapechars = "echo \"[\\^$.|?*+()\""; - - connectedIps = shellPipe [ - "netstat -tn 2>/dev/null" - "grep :$1" - "awk '{print $5}'" - "cut -d: -f1" - "sort" - "uniq -c" - "sort -nr" - "head" - ]; - - path = let - colorSlashes = colorRed "/" {middle = "/";}; - in - "echo $PATH | sed -e 's/:/\\n/g' ${colorSlashes} | sort"; - - aliases = let - colorAliasNames = colorRed "\\(^[^=]*\\)=" {middle = "\\1"; after = "\\t";}; - - # The '[^]]' (character before /nix should not be ']') is there so that this alias' - # definition won't be removed. - removeNixLinks = "-e 's|\\([^]]\\)/nix/store/.*/bin/|\\1|'"; - in - shellPipe [ - "alias" - "sed ${colorAliasNames} ${removeNixLinks}" - "column -ts $'\\t'" - ]; - - - ports = let - colorSlashes = colorRed "/" {middle = "/";}; - colorFirstColumn = colorRed "(^[^ ]+)" {middle = "\\1";}; - in - shellPipe [ - "sudo netstat -tulpn" - "grep LISTEN" - "sed -r 's/\\s+/ /g'" - "cut -d' ' -f 4,7" - "column -t" - "sed -r ${colorFirstColumn} ${colorSlashes}" - ]; - - } - // - (let - inherit (lib.strings) concatStrings concatStringsSep; - inherit (lib.lists) range flatten; - inherit (lib.attrsets) nameValuePair; - inherit (lib.trivial) const; - - repeatItem = n: item: map (const item) (range 1 n); - repeatString = n: string: concatStrings (repeatItem n string); - - nthCds = n: [ - ("cd" + (repeatString (n + 1) ".")) - ("cd." + toString n) - (repeatString (n + 1) ".") - ("." + toString n) - (".." + toString n) - ]; - realCommand = n: "cd " + (concatStringsSep "/" (repeatItem n "..")); - - nthCdsAsNameValuePairs = n: map (cmd: nameValuePair cmd (realCommand n)) (nthCds n); - allCdNameValuePairs = (flatten (map nthCdsAsNameValuePairs (range 1 9))); - in - lib.attrsets.listToAttrs allCdNameValuePairs); + shellAliases = shellOptions.flattened.aliases; + # initExtra = let + # functions = { + # # TODO: make 'join' available. + # md-to-pdf = join [ + # "pandoc \"$1\"" + # "-f gfm" + # "-V linkcolor:blue" + # "-V geometry:a4paper" + # "-V geometry:margin=2cm" + # "-V mainfont=\"Droid Sans\"" + # "--pdf-engine=xelatex" + # "-o \"$2\"" + # ]; + # }; + # in '' initExtra = '' source ${config.home.homeDirectory}/${dotDir}/p10k.zsh ''; diff --git a/nixpkgs/secret/default.nix b/nixpkgs/secret/default.nix index c32f2a1..1064a12 100644 --- a/nixpkgs/secret/default.nix +++ b/nixpkgs/secret/default.nix @@ -3,5 +3,6 @@ imports = [ ./programs ./ssh/hosts + ./gtk/bookmarks.nix ]; } diff --git a/nixpkgs/secret/programs/newsboat/default.nix b/nixpkgs/secret/programs/newsboat/default.nix index cf263d9..b2330c5 100644 --- a/nixpkgs/secret/programs/newsboat/default.nix +++ b/nixpkgs/secret/programs/newsboat/default.nix @@ -1,6 +1,6 @@ { ... }: { imports = [ - ./sources + ./sources.nix ]; } diff --git a/nixpkgs/shellOptions.nix b/nixpkgs/shellOptions.nix new file mode 100644 index 0000000..2cb2210 --- /dev/null +++ b/nixpkgs/shellOptions.nix @@ -0,0 +1,359 @@ +{ pkgs ? import {}, lib ? pkgs.lib, config ? pkgs.config, ... }: +let + sedColor = + color: + inputPattern: + outputPattern: + "-e \"s|${inputPattern}|${outputPattern.before or ""}$(tput setaf ${toString color})${outputPattern.middle}$(tput op)${outputPattern.after or ""}|g\""; + + colorRed = sedColor 1; + + colorSlashes = colorRed "/" {middle = "/";}; + + red = s: "${s}"; + green = s: "${s}"; + blue = s: "${s}"; + + # Context Functors + functors = let + inherit (lib.strings) concatStringsSep; + in { + shellPipe = { + wrap = s: { + type = "shellPipe"; + value = s; + }; + apply = f: concatStringsSep " | " f.value; + stringify = f: concatStringsSep (blue "\n| ") f.value; + }; + join = { + wrap = s: { + type = "join"; + value = s; + }; + apply = f: concatStringsSep " " 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 + shellPipe = functors.shellPipe.wrap; + join = functors.join.wrap; + in with pkgs; { + + # ░█▀▄░█▀▀░█▀█░█░░░█▀█░█▀▀░█▀▀░█▄█░█▀▀░█▀█░▀█▀░█▀▀ + # ░█▀▄░█▀▀░█▀▀░█░░░█▀█░█░░░█▀▀░█░█░█▀▀░█░█░░█░░▀▀█ + # ░▀░▀░▀▀▀░▀░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░▀░░▀░░▀▀▀ + + # Replacing all of coreutils with rust, lol + + "System Tool Replacements" = { + cd = "z"; + + ccp = "${coreutils}/bin/cp"; + cp = "${rsync}/bin/rsync --progress --human-readable"; + cpr = "${rsync}/bin/rsync --progress --human-readable --recursive"; + + ccat = "${coreutils}/bin/cat"; + cat = "${bat}/bin/bat"; + + htop = "${bottom}/bin/btm"; + + # This is potentially dangerous, as procs flags are totally different + ps = "${procs}/bin/procs"; + + # Find flags are so different that I've renamed fd to fin for time being + fin = "${fd}/bin/fd"; + + ag="${ripgrep}/bin/rg"; + + lls = "${coreutils}/bin/ls --color=always"; + ls = "${exa}/bin/exa"; + la = "${exa}/bin/exa -lah --changed --time-style long-iso --git --group"; + lsa = "la"; + + killall = "echo \"killall is dangerous on non-gnu platforms. Using 'pkill -x'\"; pkill -x"; + }; + + # ░█▀▀░█▀█░█░░░█▀█░█▀▄░▀█▀░▀▀█░█▀▀░█▀▄ + # ░█░░░█░█░█░░░█░█░█▀▄░░█░░▄▀░░█▀▀░█░█ + # ░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀▀░ + + # Normal commands, just with colors. + + "Colorized" = { + ip = "ip --color=always"; + diff = "diff --color=auto"; + grep = "grep --color=always"; + make = "${colormake}/bin/colormake"; + }; + + # ░█▀▄░█▀▀░█▄█░▀█▀░█▀█░█▀▄░█▀▀░█▀▄░█▀▀ + # ░█▀▄░█▀▀░█░█░░█░░█░█░█░█░█▀▀░█▀▄░▀▀█ + # ░▀░▀░▀▀▀░▀░▀░▀▀▀░▀░▀░▀▀░░▀▀▀░▀░▀░▀▀▀ + + # Stuff that I constantly forget... + + "Reminders" = { + regex-escapechars = "echo \"[\\^$.|?*+()\""; + aliases = "${coreutils}/bin/cat $HOME/${home.file.aliases.target}"; + }; + + # ░█▀█░▀█▀░█░█ + # ░█░█░░█░░▄▀▄ + # ░▀░▀░▀▀▀░▀░▀ + + # Nix related aliases + + "Nix Stuff" = { + # This for some reason uses an outdated version of hm + # hs = "${pkgs.home-manager}/bin/home-manager switch"; + hms = "home-manager switch"; + nxr = "sudo ${nixos-rebuild}/bin/nixos-rebuild switch"; + nxc = "sudoedit /etc/nixos/configuration.nix"; + nxh = "vim ~/.config/nixpkgs/home.nix"; + ns = "nix-shell"; + }; + + # ░█▀▀░█▀█░█▀▀░▀█▀░█░█░█▀█░█▀▄░█▀▀ + # ░▀▀█░█░█░█▀▀░░█░░█▄█░█▀█░█▀▄░█▀▀ + # ░▀▀▀░▀▀▀░▀░░░░▀░░▀░▀░▀░▀░▀░▀░▀▀▀ + + # Aliases that are so long/piped that they could be considered new software. + + "Software" = { + + skusho = "${maim}/bin/maim --hidecursor --nokeyboard $(echo $SCREENSHOT_DIR)/$(date_%s).png"; + skushoclip = shellPipe [ + "${maim}/bin/maim --hidecursor --nokeyboard --select" + "${xclip}/bin/xclip -selection clipboard -target image/png -in" + ]; + + dp-check = shellPipe [ + "ls -l /proc/$(pidof dropbox)/fd" + "egrep -v 'pipe:|socket:|/dev'" + "grep \"${config.services.dropbox.path}/[^.]\"" + ]; + + subdirs-to-cbz = join [ + "for dir in \"./*\"; do" + " ${zip}/bin/zip -r \"$dir.cbz\" \"$d\";" + "done" + ]; + + connectedIps = shellPipe [ + "netstat -tn 2>/dev/null" + "grep :$1" + "awk '{print $5}'" + "cut -d: -f1" + "sort" + "uniq -c" + "sort -nr" + "head" + ]; + + path = "echo $PATH | sed -e 's/:/\\n/g' ${colorSlashes} | sort"; + + wowify = "${toilet}/bin/toilet -f pagga | ${lolcat}/bin/lolcat"; + + aliasc = let + colorAliasNames = colorRed "\\(^[^=]*\\)=" {middle = "\\1"; after = "\\t";}; + # The '[^]]' (character before /nix should not be ']') is there so that this + # alias definition won't be removed. + removeNixLinks = "-e 's|\\([^]]\\)/nix/store/.*/bin/|\\1|'"; + in + shellPipe [ + "alias" + "sed ${colorAliasNames} ${removeNixLinks}" + "column -ts $'\\t'" + ]; + + ports = let + colorFirstColumn = colorRed "(^[^ ]+)" {middle = "\\1";}; + in + shellPipe [ + "sudo netstat -tulpn" + "grep LISTEN" + "sed -r 's/\\s+/ /g'" + "cut -d' ' -f 4,7" + "column -t" + "sed -r ${colorFirstColumn} ${colorSlashes}" + ]; + }; + + # ░█▀█░█░░░▀█▀░█▀█░█▀▀░█▀▀░█▀▀ + # ░█▀█░█░░░░█░░█▀█░▀▀█░█▀▀░▀▀█ + # ░▀░▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀ + + # Normal commands that are just shortened. What would normally be considered + # the "technically correct definition" of an alias + + "Actual Aliases" = { + dp = "${dropbox-cli}/bin/dropbox"; + + # Having 'watch' with a space after as an alias, enables it to expand other aliases + watch = "${procps}/bin/watch "; + + m = "${ncmpcpp}/bin/ncmpcpp"; + p = "${python39Packages.ipython}/bin/ipython"; + }; + + # ░█▄█░▀█▀░█▀▀░█▀▀ + # ░█░█░░█░░▀▀█░█░░ + # ░▀░▀░▀▀▀░▀▀▀░▀▀▀ + + # I didn't know where else to put these ¯\_(ツ)_/¯ + + "Misc" = { + youtube-dl-list = join [ + "${youtube-dl}/bin/youtube-dl" + "-f \"bestvideo[ext=mp4]+bestaudio[e=m4a]/bestvideo+bestaudio\"" + "-o \"%(playlist_index)s-%(title)s.%(ext)s\"" + ]; + + music-dl = "${youtube-dl}/bin/youtube-dl --extract-audio -f \"bestaudio[ext=m4a]/best\""; + music-dl-list = join [ + "${youtube-dl}/bin/youtube-dl" + "--extract-audio" + "-f \"bestaudio[ext=m4a]/best\"" + "-o \"%(playlist_index)s-%(title)s.%(ext)s\"" + ]; + + view-latex = "${texlive.combined.scheme-full}/bin/latexmk -pdf -pvc main.tex"; + + reload-tmux = "${tmux}/bin/tmux source $HOME/.config/tmux/tmux.conf"; + }; + + # ░█▀▀░█▀▀░█▀█░█▀▀░█▀▄░█▀█░▀█▀░█▀▀░█▀▄ + # ░█░█░█▀▀░█░█░█▀▀░█▀▄░█▀█░░█░░█▀▀░█░█ + # ░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░▀░▀░▀░░▀░░▀▀▀░▀▀░ + + # Code generated commands + + "Generated" = { + "cds" = let + inherit (lib.strings) concatStrings concatStringsSep; + inherit (lib.lists) range flatten; + inherit (lib.attrsets) nameValuePair; + + nthCds = n: [ + ("cd" + (repeatString (n + 1) ".")) + ("cd." + toString n) + (repeatString (n + 1) ".") + ("." + toString n) + (".." + toString n) + ]; + realCommand = n: "cd " + (concatStringsSep "/" (repeatItem n "..")); + + nthCdsAsNameValuePairs = n: map (cmd: nameValuePair cmd (realCommand n)) (nthCds n); + allCdNameValuePairs = (flatten (map nthCdsAsNameValuePairs (range 1 9))); + in + lib.attrsets.listToAttrs allCdNameValuePairs; + }; + }; + + # TODO: flatten functions + functions = { + all = { + md-to-pdf = functors.join.wrap [ + "pandoc \"$1\"" + "-f gfm" + "-V linkcolor:blue" + "-V geometry:a4paper" + "-V geometry:margin=2cm" + "-V mainfont=\"Droid Sans\"" + "--pdf-engine=xelatex" + "-o \"$2\"" + ]; + }; + }; + + variables = { + POWERLEVEL9K_LEFT_PROMPT_ELEMENTS = ["dir" "vcs"]; + # NIX_PATH = ''$HOME/.nix-defexpr/channels$\{NIX_PATH:+:}$NIX_PATH''; + }; + + flattened.aliases = let + inherit (lib.attrsets) mapAttrs attrValues filterAttrs isAttrs; + inherit (lib.lists) foldr partition; + inherit (lib.strings) isString concatStringsSep; + + applyFunctor = attrset: functors.${attrset.type}.apply attrset; + + # TODO: better naming + allAttrValuesAreStrings = attrset: let + + # [ {String} ] + filteredAliases = [(filterAttrs (n: v: isString v) attrset)]; + + # [ {String} ] + remainingFunctors = let + functorSet = filterAttrs (n: v: isAttrs v && isFunctor v) attrset; + appliedFunctorSet = mapAttrs (n: v: applyFunctor v) functorSet; + in [ appliedFunctorSet ]; + + # [ {AttrSet} ] + remainingAliasSets = attrValues (filterAttrs (n: v: isAttrs v && !(isFunctor v)) attrset); + + # [ {String} ] + recursedAliasSets = filteredAliases + ++ (remainingFunctors) + ++ (map allAttrValuesAreStrings remainingAliasSets); + in foldr (a: b: a // b) {} 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; + + # int -> String -> AttrSet -> String + stringifyCategory = level: name: category: + concatStringsSep "\n" + (["${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 = if (maybeMatches == null) then null else remove "" maybeMatches; + listOfEmptyStrings = map (const "") (range 1 (length matches)); + 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"; + }; +}