home/shell: split alias tree functionality into module and config
This commit is contained in:
parent
6663a8f280
commit
f85724dea0
|
@ -5,7 +5,7 @@ in {
|
|||
inherit machineVars;
|
||||
|
||||
imports = [
|
||||
./shellOptions.nix
|
||||
./shell.nix
|
||||
./packages.nix
|
||||
|
||||
./config/ssh/hosts/pvv.nix
|
||||
|
@ -26,6 +26,7 @@ in {
|
|||
|
||||
../modules/machineVars.nix
|
||||
./modules/colors.nix
|
||||
./modules/shellAliases.nix
|
||||
|
||||
inputs.secrets.outputs.home-config
|
||||
] ++ optionals graphics [
|
||||
|
|
|
@ -0,0 +1,259 @@
|
|||
{ pkgs, lib, extendedLib, inputs, config, ... }: let
|
||||
inherit (lib) types mkEnableOption mkOption mdDoc;
|
||||
cfg = config.local.shell;
|
||||
|
||||
# NOTE:
|
||||
# This module is an over-engineered solution to a non-problem.
|
||||
# It is a fun experiment in using the Nix language to create a
|
||||
# shell alias system that organizes aliases into a tree structure,
|
||||
# with categories and subcategories and subsubcategories and so on.
|
||||
#
|
||||
# It also has a lazy join function that will join a list of commands
|
||||
# with a separator, but render it in a prettier way in a documentation
|
||||
# file that you can print out and read.
|
||||
|
||||
isAlias = v: builtins.isAttrs v && v ? "alias" && v ? "type";
|
||||
in {
|
||||
options.local.shell = {
|
||||
aliases = let
|
||||
|
||||
coerceStrToAlias = str: {
|
||||
type = " ";
|
||||
alias = [ str ];
|
||||
};
|
||||
|
||||
aliasType = (types.coercedTo types.str coerceStrToAlias (types.submodule {
|
||||
options = {
|
||||
type = mkOption {
|
||||
type = types.enum [ "|" "&&" ";" " " ];
|
||||
default = ";";
|
||||
description = ''
|
||||
If the alias is a list of commands, this is the kind of separator that will be used.
|
||||
'';
|
||||
};
|
||||
alias = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
};
|
||||
})) // {
|
||||
# NOTE: this check is necessary, because nix will recurse on types.either,
|
||||
# and report that the option does not exist.
|
||||
# See https://discourse.nixos.org/t/problems-with-types-oneof-and-submodules/15197
|
||||
check = v: builtins.isString v || isAlias v;
|
||||
};
|
||||
|
||||
recursingAliasTreeType = types.attrsOf (types.either aliasType recursingAliasTreeType);
|
||||
in mkOption {
|
||||
type = recursingAliasTreeType;
|
||||
description = "A tree of aliases";
|
||||
default = { };
|
||||
example = {
|
||||
"My first alias category" = {
|
||||
cmd1 = ''echo "hello world"'';
|
||||
cmd2 = {
|
||||
type = "|";
|
||||
alias = [
|
||||
"ls -la"
|
||||
"grep -i hello"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
"My second alias category" = {
|
||||
cmd1 = {
|
||||
type = "&&";
|
||||
alias = [
|
||||
''echo "hello world"''
|
||||
''echo "goodbye world"''
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
variables = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
description = "Environment variables";
|
||||
default = { };
|
||||
};
|
||||
|
||||
# TODO: I want a similar system for functions at some point.
|
||||
# functions = {
|
||||
|
||||
# };
|
||||
|
||||
enablePackageManagerLecture = mkEnableOption "distro reminder messages, aliased to common package manager commands";
|
||||
enableAliasOverview = mkEnableOption "`aliases` command that prints out a list of all aliases" // {
|
||||
default = true;
|
||||
example = false;
|
||||
};
|
||||
};
|
||||
|
||||
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 = "/";};
|
||||
|
||||
# Alias type functors
|
||||
# These will help pretty print the commands
|
||||
functors = let
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
inherit (extendedLib.termColors.front) blue;
|
||||
in
|
||||
{
|
||||
"|" = {
|
||||
apply = f: concatStringsSep " | " f.alias;
|
||||
stringify = f: concatStringsSep (blue "\n| ") f.alias;
|
||||
};
|
||||
"&&" = {
|
||||
apply = f: concatStringsSep " && " f.alias;
|
||||
stringify = f: concatStringsSep (blue "\n&& ") f.alias;
|
||||
};
|
||||
";" = {
|
||||
apply = f: concatStringsSep "; " f.alias;
|
||||
stringify = f: concatStringsSep (blue ";\n ") f.alias;
|
||||
};
|
||||
" " = {
|
||||
apply = f: concatStringsSep " " f.alias;
|
||||
stringify = f: concatStringsSep " \\\n " f.alias;
|
||||
};
|
||||
};
|
||||
|
||||
aliasTextOverview = let
|
||||
inherit (lib) stringLength length concatStringsSep replaceStrings
|
||||
attrValues mapAttrs isAttrs remove replicate mapNullable;
|
||||
|
||||
inherit (extendedLib.termColors.front) red green blue;
|
||||
|
||||
# String -> String -> String
|
||||
wrap' = wrapper: str: wrapper + str + wrapper;
|
||||
|
||||
# [String] -> String -> String -> String
|
||||
replaceStrings' = from: to: replaceStrings from (replicate (length from) to);
|
||||
|
||||
# String -> Int -> String
|
||||
repeatString = string: times: concatStringsSep "" (replicate times string);
|
||||
|
||||
# int -> String -> AttrSet -> String
|
||||
stringifyCategory = level: name: category: let
|
||||
title = "${repeatString " " level}[${green name}]";
|
||||
|
||||
commands = attrValues ((lib.flip mapAttrs) category (n: v: let
|
||||
# String
|
||||
indent = repeatString " " level;
|
||||
|
||||
# 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;
|
||||
|
||||
applyFunctor = attrset: let
|
||||
applied = functors.${attrset.type}.stringify attrset;
|
||||
indent' = indent + (repeatString " " ((stringLength " -> \"") + (stringLength n))) + " ";
|
||||
in
|
||||
replaceStrings' ["\n"] ("\n" + indent') applied;
|
||||
|
||||
recurse = stringifyCategory (level + 1) n v;
|
||||
in if isAlias v
|
||||
then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks (applyFunctor v))}"
|
||||
else recurse
|
||||
));
|
||||
in concatStringsSep "\n" ([title] ++ commands) + "\n";
|
||||
in (stringifyCategory 0 "Aliases" cfg.aliases) + "\n";
|
||||
|
||||
flattenedAliases = let
|
||||
inherit (lib) mapAttrs attrValues filterAttrs isAttrs
|
||||
isString concatStringsSep foldr;
|
||||
|
||||
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 (_: v: isAlias v) attrset;
|
||||
appliedFunctorSet = mapAttrs (n: v: applyFunctor v) functorSet;
|
||||
in [ appliedFunctorSet ];
|
||||
|
||||
# [ {AttrSet} ]
|
||||
remainingAliasSets = attrValues (filterAttrs (_: v: isAttrs v && !isAlias v) attrset);
|
||||
|
||||
# [ {String} ]
|
||||
recursedAliasSets = filteredAliases
|
||||
++ (remainingFunctors)
|
||||
++ (map allAttrValuesAreStrings remainingAliasSets);
|
||||
in foldr (a: b: a // b) {} recursedAliasSets;
|
||||
|
||||
in
|
||||
allAttrValuesAreStrings cfg.aliases;
|
||||
|
||||
in {
|
||||
xdg.dataFile = {
|
||||
aliases.text = aliasTextOverview;
|
||||
packageManagerLecture = lib.mkIf cfg.enablePackageManagerLecture {
|
||||
target = "package-manager.lecture";
|
||||
text = let
|
||||
inherit (extendedLib.termColors.front) red blue;
|
||||
in lib.concatStringsSep "\n" [
|
||||
((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."))
|
||||
""
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
local.shell.aliases."Package Managers" = lib.mkIf cfg.enablePackageManagerLecture (let
|
||||
inherit (lib.attrsets) nameValuePair listToAttrs;
|
||||
|
||||
packageManagers = [
|
||||
"apt"
|
||||
"dpkg"
|
||||
"flatpak"
|
||||
"pacman"
|
||||
"pamac"
|
||||
"paru"
|
||||
"rpm"
|
||||
"snap"
|
||||
"xbps"
|
||||
"yay"
|
||||
"yum"
|
||||
];
|
||||
|
||||
command = "${pkgs.coreutils}/bin/cat $HOME/${config.xdg.dataFile.packageManagerLecture.target}";
|
||||
nameValuePairs = map (pm: nameValuePair pm command) packageManagers;
|
||||
in listToAttrs nameValuePairs);
|
||||
|
||||
local.shell.aliases.aliases = lib.mkIf cfg.enableAliasOverview
|
||||
"${pkgs.coreutils}/bin/cat $HOME/${config.xdg.dataFile.aliases.target}";
|
||||
|
||||
programs = {
|
||||
zsh = {
|
||||
shellAliases = flattenedAliases;
|
||||
sessionVariables = cfg.variables;
|
||||
};
|
||||
bash = {
|
||||
shellAliases = flattenedAliases;
|
||||
sessionVariables = cfg.variables;
|
||||
};
|
||||
fish = {
|
||||
shellAliases = flattenedAliases;
|
||||
# TODO: fish does not support session variables?
|
||||
# localVariables = cfg.variables;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
{ pkgs, lib, config, shellOptions, ... }:
|
||||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
programs.zsh = {
|
||||
|
||||
|
@ -58,10 +58,6 @@
|
|||
}
|
||||
];
|
||||
|
||||
localVariables = shellOptions.variables;
|
||||
|
||||
shellAliases = shellOptions.flattened.aliases;
|
||||
|
||||
initExtra = ''
|
||||
source ${./p10k.zsh}
|
||||
|
||||
|
|
|
@ -0,0 +1,303 @@
|
|||
{ config, pkgs, lib, extendedLib, inputs, ... }: let
|
||||
sedColor =
|
||||
color:
|
||||
inputPattern: # sed regex.
|
||||
outputPattern@{ before ? "" , middle ? "", after ? ""}:
|
||||
"-e \"s|${inputPattern}|${before}$(tput setaf ${toString color})${middle}$(tput op)${after}|g\"";
|
||||
|
||||
colorRed = sedColor 1;
|
||||
|
||||
colorSlashes = colorRed "/" { middle = "/"; };
|
||||
in {
|
||||
local.shell.aliases = let
|
||||
p = pkg: "${pkgs.${pkg}}/bin/${pkg}";
|
||||
in {
|
||||
# ░█▀▄░█▀▀░█▀█░█░░░█▀█░█▀▀░█▀▀░█▄█░█▀▀░█▀█░▀█▀░█▀▀
|
||||
# ░█▀▄░█▀▀░█▀▀░█░░░█▀█░█░░░█▀▀░█░█░█▀▀░█░█░░█░░▀▀█
|
||||
# ░▀░▀░▀▀▀░▀░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░▀░░▀░░▀▀▀
|
||||
|
||||
# Replacing all of coreutils with rust, lol
|
||||
|
||||
"System Tool Replacements" = {
|
||||
|
||||
# Convention: if replaced tool is useful in some situations, let it be available
|
||||
# as its own command with its first character doubled.
|
||||
#
|
||||
# Example: cp -> ccp
|
||||
|
||||
cd = "z";
|
||||
|
||||
ccp = "${pkgs.coreutils}/bin/cp";
|
||||
cp = "${p "rsync"} --progress --human-readable";
|
||||
cpr = "${p "rsync"} --progress --human-readable --recursive";
|
||||
|
||||
ccat = "${pkgs.coreutils}/bin/cat";
|
||||
cat = p "bat";
|
||||
|
||||
htop = "${pkgs.bottom}/bin/btm";
|
||||
hhtop = p "htop";
|
||||
|
||||
dig = p "dog";
|
||||
|
||||
# Flags are incompatible, so they are suffixed by -x
|
||||
psx = p "procs";
|
||||
findx = p "fd";
|
||||
|
||||
ag = "${pkgs.ripgrep}/bin/rg";
|
||||
|
||||
lls = "${pkgs.coreutils}/bin/ls --color=always";
|
||||
ls = p "exa";
|
||||
la = "${p "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";
|
||||
# TODO: doesn't work
|
||||
# make = "${colormake}/bin/colormake";
|
||||
};
|
||||
|
||||
# ░█▀▄░█▀▀░█▄█░▀█▀░█▀█░█▀▄░█▀▀░█▀▄░█▀▀
|
||||
# ░█▀▄░█▀▀░█░█░░█░░█░█░█░█░█▀▀░█▀▄░▀▀█
|
||||
# ░▀░▀░▀▀▀░▀░▀░▀▀▀░▀░▀░▀▀░░▀▀▀░▀░▀░▀▀▀
|
||||
|
||||
# Stuff that I constantly forget...
|
||||
|
||||
"Reminders" = {
|
||||
regex-escapechars = "echo \"[\\^$.|?*+()\"";
|
||||
};
|
||||
|
||||
# ░█▀█░▀█▀░█░█
|
||||
# ░█░█░░█░░▄▀▄
|
||||
# ░▀░▀░▀▀▀░▀░▀
|
||||
|
||||
# Nix related aliases
|
||||
|
||||
"Nix Stuff" = {
|
||||
nxr = "sudo nixos-rebuild switch";
|
||||
|
||||
nix-check-syntax = "nix-instantiate --parse-only";
|
||||
|
||||
nxr-hm = "sudo nixos-rebuild switch --flake ~/nix#home-manager-tester";
|
||||
nxr-ks = "sudo nixos-rebuild switch --flake ~/nix#kasei";
|
||||
|
||||
hms = toString inputs.nix-attr-search.packages.${pkgs.system}.home-manager-search;
|
||||
nxo = toString inputs.nix-attr-search.packages.${pkgs.system}.nix-option-search;
|
||||
};
|
||||
|
||||
# ░█▀▀░█░█░█▀▀░▀█▀░█▀▀░█▄█░█▀▄
|
||||
# ░▀▀█░░█░░▀▀█░░█░░█▀▀░█░█░█░█
|
||||
# ░▀▀▀░░▀░░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀░
|
||||
|
||||
# Systemd related aliases
|
||||
|
||||
"Systemd Stuff" = {
|
||||
scr = "sudo systemctl restart";
|
||||
scs = "systemctl status";
|
||||
scc = "systemctl cat";
|
||||
scf = "systemctl list-units --failed";
|
||||
jx = "journalctl -xeu";
|
||||
};
|
||||
|
||||
# ░█▀▀░█▀█░█▀▀░▀█▀░█░█░█▀█░█▀▄░█▀▀
|
||||
# ░▀▀█░█░█░█▀▀░░█░░█▄█░█▀█░█▀▄░█▀▀
|
||||
# ░▀▀▀░▀▀▀░▀░░░░▀░░▀░▀░▀░▀░▀░▀░▀▀▀
|
||||
|
||||
# Aliases that are so long/piped that they could be considered new software.
|
||||
|
||||
"Software" = {
|
||||
skusho = "${p "maim"} --hidecursor --nokeyboard $(echo $SCREENSHOT_DIR)/$(date_%s).png";
|
||||
skushoclip = {
|
||||
type = "|";
|
||||
alias = [
|
||||
"${p "maim"} --hidecursor --nokeyboard --select"
|
||||
"${p "xclip"} -selection clipboard -target image/png -in"
|
||||
];
|
||||
};
|
||||
|
||||
dp-check = {
|
||||
type = "|";
|
||||
alias = [
|
||||
"ls -l /proc/$(pidof dropbox)/fd"
|
||||
"egrep -v 'pipe:|socket:|/dev'"
|
||||
"grep \"${config.services.dropbox.path}/[^.]\""
|
||||
];
|
||||
};
|
||||
|
||||
subdirs-to-cbz = {
|
||||
type = " ";
|
||||
alias = [
|
||||
''for dir in "./*";''
|
||||
'' ${p "zip"} -r "$dir.cbz" "$d";''
|
||||
''done''
|
||||
];
|
||||
};
|
||||
|
||||
connectedIps = {
|
||||
type = "|";
|
||||
alias = [
|
||||
"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 = "${p "toilet"} -f pagga | ${p "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 {
|
||||
type = "|";
|
||||
alias = [
|
||||
"alias"
|
||||
"sed ${colorAliasNames} ${removeNixLinks}"
|
||||
"column -ts $'\\t'"
|
||||
];
|
||||
};
|
||||
|
||||
ports = let
|
||||
colorFirstColumn = colorRed "(^[^ ]+)" {middle = "\\1";};
|
||||
in {
|
||||
type = "|";
|
||||
alias = [
|
||||
"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 = "${pkgs.procps}/bin/watch ";
|
||||
|
||||
concatPdfs = {
|
||||
type = ";";
|
||||
alias = [
|
||||
''echo "${extendedLib.termColors.front.red "Concatenating all pdfs in current directory to 'out.pdf'"}"''
|
||||
"${pkgs.poppler_utils}/bin/pdfunite *.pdf out.pdf"
|
||||
];
|
||||
};
|
||||
|
||||
m = p "ncmpcpp";
|
||||
p = "${pkgs.python39Packages.ipython}/bin/ipython";
|
||||
s = p "sxiv";
|
||||
v = p "mpv";
|
||||
zt = p "zathura";
|
||||
};
|
||||
|
||||
# ░█▄█░▀█▀░█▀▀░█▀▀
|
||||
# ░█░█░░█░░▀▀█░█░░
|
||||
# ░▀░▀░▀▀▀░▀▀▀░▀▀▀
|
||||
|
||||
# I didn't know where else to put these ¯\_(ツ)_/¯
|
||||
|
||||
"Misc" = {
|
||||
youtube-dl-list = {
|
||||
type = " ";
|
||||
alias = [
|
||||
(p "yt-dlp")
|
||||
"-f \"bestvideo[ext=mp4]+bestaudio[e=m4a]/bestvideo+bestaudio\""
|
||||
"-o \"%(playlist_index)s-%(title)s.%(ext)s\""
|
||||
];
|
||||
};
|
||||
|
||||
music-dl = "${p "yt-dlp"} --extract-audio -f \"bestaudio[ext=m4a]/best\"";
|
||||
music-dl-list = {
|
||||
type = " ";
|
||||
alias = [
|
||||
(p "yt-dlp")
|
||||
"--extract-audio"
|
||||
"-f \"bestaudio[ext=m4a]/best\""
|
||||
"-o \"%(playlist_index)s-%(title)s.%(ext)s\""
|
||||
];
|
||||
};
|
||||
|
||||
view-latex = "${pkgs.texlive.combined.scheme-full}/bin/latexmk -pdf -pvc main.tex";
|
||||
|
||||
reload-tmux = "${p "tmux"} source $HOME/.config/tmux/tmux.conf";
|
||||
};
|
||||
|
||||
# ░█▀▀░█▀▀░█▀█░█▀▀░█▀▄░█▀█░▀█▀░█▀▀░█▀▄
|
||||
# ░█░█░█▀▀░█░█░█▀▀░█▀▄░█▀█░░█░░█▀▀░█░█
|
||||
# ░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░▀░▀░▀░░▀░░▀▀▀░▀▀░
|
||||
|
||||
# Code generated commands
|
||||
|
||||
"Generated" = {
|
||||
"cds" = let
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
inherit (extendedLib.strings) repeatString;
|
||||
|
||||
inherit (lib.lists) range flatten replicate;
|
||||
inherit (lib.attrsets) nameValuePair listToAttrs;
|
||||
|
||||
nthCds = n: [
|
||||
("cd" + (repeatString "." (n + 1)))
|
||||
("cd." + toString n)
|
||||
(repeatString "." (n + 1))
|
||||
("." + toString n)
|
||||
(".." + toString n)
|
||||
];
|
||||
realCommand = n: "cd " + (concatStringsSep "/" (replicate n ".."));
|
||||
|
||||
nthCdsAsNameValuePairs = n: map (cmd: nameValuePair cmd (realCommand n)) (nthCds n);
|
||||
allCdNameValuePairs = flatten (map nthCdsAsNameValuePairs (range 1 9));
|
||||
in
|
||||
listToAttrs allCdNameValuePairs;
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: flatten functions
|
||||
# local.shell.functions = {
|
||||
# all = {
|
||||
# md-to-pdf = functors.shellJoin.wrap [
|
||||
# "pandoc \"$1\""
|
||||
# "-f gfm"
|
||||
# "-V linkcolor:blue"
|
||||
# "-V geometry:a4paper"
|
||||
# "-V geometry:margin=2cm"
|
||||
# "-V mainfont=\"Droid Sans\""
|
||||
# "--pdf-engine=xelatex"
|
||||
# "-o \"$2\""
|
||||
# ];
|
||||
# };
|
||||
# };
|
||||
|
||||
# local.shell.variables = {
|
||||
# POWERLEVEL9K_LEFT_PROMPT_ELEMENTS = ["dir" "vcs"];
|
||||
# NIX_PATH = ''$HOME/.nix-defexpr/channels$\{NIX_PATH:+:}$NIX_PATH'';
|
||||
# };
|
||||
}
|
|
@ -1,433 +0,0 @@
|
|||
{ pkgs, lib, extendedLib, inputs, 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 = "/";};
|
||||
|
||||
# Context Functors
|
||||
functors = let
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
inherit (extendedLib.termColors.front) blue;
|
||||
genWrapper = type: value: { inherit type; inherit value; };
|
||||
in
|
||||
{
|
||||
shellPipe = {
|
||||
wrap = genWrapper "shellPipe";
|
||||
apply = f: concatStringsSep " | " f.value;
|
||||
stringify = f: concatStringsSep (blue "\n| ") f.value;
|
||||
};
|
||||
shellAnd = {
|
||||
wrap = genWrapper "shellAnd";
|
||||
apply = f: concatStringsSep " && " f.value;
|
||||
stringify = f: concatStringsSep (blue "\n&& ") f.value;
|
||||
};
|
||||
shellThen = {
|
||||
wrap = genWrapper "shellThen";
|
||||
apply = f: concatStringsSep "; " f.value;
|
||||
stringify = f: concatStringsSep (blue ";\n ") f.value;
|
||||
};
|
||||
shellJoin = {
|
||||
wrap = genWrapper "shellJoin";
|
||||
apply = f: concatStringsSep " " f.value;
|
||||
stringify = f: concatStringsSep " \\\n " f.value;
|
||||
};
|
||||
};
|
||||
|
||||
# AttrSet -> Bool
|
||||
isFunctor = let
|
||||
inherit (lib.lists) any;
|
||||
inherit (lib.attrsets) attrValues;
|
||||
in
|
||||
attrset:
|
||||
if !(attrset ? "type")
|
||||
then false
|
||||
else any (f: (f.wrap "").type == attrset.type) (attrValues functors);
|
||||
|
||||
in rec {
|
||||
_module.args.shellOptions = {
|
||||
aliases = let
|
||||
shellPipe = functors.shellPipe.wrap;
|
||||
shellJoin = functors.shellJoin.wrap;
|
||||
shellAnd = functors.shellAnd.wrap;
|
||||
shellThen = functors.shellThen.wrap;
|
||||
in with pkgs; {
|
||||
|
||||
# ░█▀▄░█▀▀░█▀█░█░░░█▀█░█▀▀░█▀▀░█▄█░█▀▀░█▀█░▀█▀░█▀▀
|
||||
# ░█▀▄░█▀▀░█▀▀░█░░░█▀█░█░░░█▀▀░█░█░█▀▀░█░█░░█░░▀▀█
|
||||
# ░▀░▀░▀▀▀░▀░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░▀░░▀░░▀▀▀
|
||||
|
||||
# Replacing all of coreutils with rust, lol
|
||||
|
||||
"System Tool Replacements" = {
|
||||
|
||||
# Convention: if replaced tool is useful in some situations, let it be available
|
||||
# as its own command with its first character doubled.
|
||||
#
|
||||
# Example: cp -> ccp
|
||||
|
||||
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";
|
||||
hhtop = "${htop}/bin/htop";
|
||||
|
||||
dig = "${dog}/bin/dog";
|
||||
|
||||
# Flags are incompatible, so they are suffixed by -x
|
||||
psx = "${procs}/bin/procs";
|
||||
findx = "${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";
|
||||
# TODO: doesn't work
|
||||
# make = "${colormake}/bin/colormake";
|
||||
};
|
||||
|
||||
# ░█▀▄░█▀▀░█▄█░▀█▀░█▀█░█▀▄░█▀▀░█▀▄░█▀▀
|
||||
# ░█▀▄░█▀▀░█░█░░█░░█░█░█░█░█▀▀░█▀▄░▀▀█
|
||||
# ░▀░▀░▀▀▀░▀░▀░▀▀▀░▀░▀░▀▀░░▀▀▀░▀░▀░▀▀▀
|
||||
|
||||
# Stuff that I constantly forget...
|
||||
|
||||
"Reminders" = {
|
||||
regex-escapechars = "echo \"[\\^$.|?*+()\"";
|
||||
aliases = "${coreutils}/bin/cat $HOME/${config.xdg.dataFile.aliases.target}";
|
||||
};
|
||||
|
||||
# ░█▀█░▀█▀░█░█
|
||||
# ░█░█░░█░░▄▀▄
|
||||
# ░▀░▀░▀▀▀░▀░▀
|
||||
|
||||
# Nix related aliases
|
||||
|
||||
"Nix Stuff" = {
|
||||
nxr = "sudo nixos-rebuild switch";
|
||||
|
||||
nix-check-syntax = "nix-instantiate --parse-only";
|
||||
|
||||
nxr-hm = "sudo nixos-rebuild switch --flake ~/nix#home-manager-tester";
|
||||
nxr-ks = "sudo nixos-rebuild switch --flake ~/nix#kasei";
|
||||
|
||||
hms = toString inputs.nix-attr-search.packages.${pkgs.system}.home-manager-search;
|
||||
nxo = toString inputs.nix-attr-search.packages.${pkgs.system}.nix-option-search;
|
||||
};
|
||||
|
||||
# ░█▀▀░█░█░█▀▀░▀█▀░█▀▀░█▄█░█▀▄
|
||||
# ░▀▀█░░█░░▀▀█░░█░░█▀▀░█░█░█░█
|
||||
# ░▀▀▀░░▀░░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀░
|
||||
|
||||
# Systemd related aliases
|
||||
|
||||
"Systemd Stuff" = {
|
||||
scr = "sudo systemctl restart";
|
||||
scs = "systemctl status";
|
||||
scc = "systemctl cat";
|
||||
scf = "systemctl list-units --failed";
|
||||
jx = "journalctl -xeu";
|
||||
};
|
||||
|
||||
# ░█▀▀░█▀█░█▀▀░▀█▀░█░█░█▀█░█▀▄░█▀▀
|
||||
# ░▀▀█░█░█░█▀▀░░█░░█▄█░█▀█░█▀▄░█▀▀
|
||||
# ░▀▀▀░▀▀▀░▀░░░░▀░░▀░▀░▀░▀░▀░▀░▀▀▀
|
||||
|
||||
# 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 = shellJoin [
|
||||
"for dir in \"./*\";"
|
||||
" ${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 ";
|
||||
|
||||
concatPdfs = shellThen [
|
||||
"echo \"${extendedLib.termColors.front.red "Concatenating all pdfs in current directory to 'out.pdf'"}\""
|
||||
"${poppler_utils}/bin/pdfunite *.pdf out.pdf"
|
||||
];
|
||||
|
||||
m = "${ncmpcpp}/bin/ncmpcpp";
|
||||
p = "${python39Packages.ipython}/bin/ipython";
|
||||
s = "${sxiv}/bin/sxiv";
|
||||
v = "${mpv}/bin/mpv";
|
||||
zt = "${zathura}/bin/zathura";
|
||||
};
|
||||
|
||||
# ░█▄█░▀█▀░█▀▀░█▀▀
|
||||
# ░█░█░░█░░▀▀█░█░░
|
||||
# ░▀░▀░▀▀▀░▀▀▀░▀▀▀
|
||||
|
||||
# I didn't know where else to put these ¯\_(ツ)_/¯
|
||||
|
||||
"Misc" = {
|
||||
youtube-dl-list = shellJoin [
|
||||
"${yt-dlp}/bin/yt-dlp"
|
||||
"-f \"bestvideo[ext=mp4]+bestaudio[e=m4a]/bestvideo+bestaudio\""
|
||||
"-o \"%(playlist_index)s-%(title)s.%(ext)s\""
|
||||
];
|
||||
|
||||
music-dl = "${yt-dlp}/bin/yt-dlp --extract-audio -f \"bestaudio[ext=m4a]/best\"";
|
||||
music-dl-list = shellJoin [
|
||||
"${yt-dlp}/bin/yt-dlp"
|
||||
"--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) concatStringsSep;
|
||||
inherit (extendedLib.strings) repeatString;
|
||||
|
||||
inherit (lib.lists) range flatten replicate;
|
||||
inherit (lib.attrsets) nameValuePair listToAttrs;
|
||||
|
||||
nthCds = n: [
|
||||
("cd" + (repeatString "." (n + 1)))
|
||||
("cd." + toString n)
|
||||
(repeatString "." (n + 1))
|
||||
("." + toString n)
|
||||
(".." + toString n)
|
||||
];
|
||||
realCommand = n: "cd " + (concatStringsSep "/" (replicate n ".."));
|
||||
|
||||
nthCdsAsNameValuePairs = n: map (cmd: nameValuePair cmd (realCommand n)) (nthCds n);
|
||||
allCdNameValuePairs = flatten (map nthCdsAsNameValuePairs (range 1 9));
|
||||
in
|
||||
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.xdg.dataFile.packageManagerLecture.target}";
|
||||
nameValuePairs = map (pm: nameValuePair pm command) packageManagers;
|
||||
in listToAttrs nameValuePairs;
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: flatten functions
|
||||
functions = {
|
||||
all = {
|
||||
md-to-pdf = functors.shellJoin.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 (extendedLib.attrsets) concatAttrs;
|
||||
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 concatAttrs recursedAliasSets;
|
||||
|
||||
in
|
||||
allAttrValuesAreStrings _module.args.shellOptions.aliases;
|
||||
};
|
||||
|
||||
xdg.dataFile = {
|
||||
aliases = {
|
||||
text = let
|
||||
inherit (lib.strings) stringLength;
|
||||
inherit (extendedLib.strings) unlines wrap' replaceStrings' repeatString;
|
||||
inherit (lib.attrsets) attrValues mapAttrs isAttrs;
|
||||
inherit (lib.lists) remove;
|
||||
inherit (lib.trivial) mapNullable;
|
||||
inherit (extendedLib.termColors.front) red green blue;
|
||||
|
||||
# int -> String -> AttrSet -> String
|
||||
stringifyCategory = level: name: category:
|
||||
unlines
|
||||
(["${repeatString " " level}[${green name}]"] ++
|
||||
(attrValues (mapAttrs (n: v: let
|
||||
# String
|
||||
indent = repeatString " " level;
|
||||
|
||||
# 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;
|
||||
|
||||
applyFunctor = attrset: let
|
||||
applied = functors.${attrset.type}.stringify attrset;
|
||||
indent' = indent + (repeatString " " ((stringLength " -> \"") + (stringLength n))) + " ";
|
||||
in
|
||||
replaceStrings' ["\n"] ("\n" + indent') applied;
|
||||
|
||||
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";
|
||||
};
|
||||
packageManagerLecture = {
|
||||
target = "package-manager.lecture";
|
||||
text = let
|
||||
inherit (extendedLib.strings) unlines;
|
||||
inherit (extendedLib.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."))
|
||||
""
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue