about summary refs log tree commit diff stats
path: root/pkgs/sources/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/sources/scripts')
-rw-r--r--pkgs/sources/scripts/default.nix412
-rwxr-xr-xpkgs/sources/scripts/source/apps/aumo.sh28
-rwxr-xr-xpkgs/sources/scripts/source/apps/con2pdf.sh234
-rw-r--r--pkgs/sources/scripts/source/apps/fupdate.1.md70
-rwxr-xr-xpkgs/sources/scripts/source/apps/fupdate.sh197
-rwxr-xr-xpkgs/sources/scripts/source/apps/git-edit-index.sh98
-rwxr-xr-xpkgs/sources/scripts/source/small_functions/brightness.sh80
-rwxr-xr-xpkgs/sources/scripts/source/small_functions/nato.py106
-rwxr-xr-xpkgs/sources/scripts/source/small_functions/screenshot_persistent.sh22
-rwxr-xr-xpkgs/sources/scripts/source/small_functions/screenshot_temporary.sh8
-rwxr-xr-xpkgs/sources/scripts/source/small_functions/update-sys.sh85
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/neorg_id_function.sh16
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/sh/functions/add.sh23
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/sh/functions/context.sh43
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/sh/functions/dmenu.sh14
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/sh/functions/f_start.sh7
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/sh/functions/f_stop.sh7
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/sh/functions/list.sh8
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/sh/functions/project.sh41
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/sh/functions/review.sh12
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/sh/functions/utils.sh40
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/sh/functions/workspace.sh9
-rwxr-xr-xpkgs/sources/scripts/source/specific/neorg/sh/main.sh164
-rwxr-xr-xpkgs/sources/scripts/source/specific/spodi/sh/download.sh58
-rwxr-xr-xpkgs/sources/scripts/source/specific/spodi/sh/update.sh52
-rwxr-xr-xpkgs/sources/scripts/source/specific/spodi/spodi.sh71
-rwxr-xr-xpkgs/sources/scripts/source/specific/ytcc/description.sh8
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/battery.sh11
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/hibernate.sh15
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/ll.sh14
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/lock.sh18
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/lyrics.sh11
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/mpc-fav.sh16
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/mpc-rm.sh10
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/mpc.sh20
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/show.sh9
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/sort_song.sh34
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/virsh-del.sh10
-rwxr-xr-xpkgs/sources/scripts/source/wrappers/yti.sh33
39 files changed, 2114 insertions, 0 deletions
diff --git a/pkgs/sources/scripts/default.nix b/pkgs/sources/scripts/default.nix
new file mode 100644
index 00000000..09c8d411
--- /dev/null
+++ b/pkgs/sources/scripts/default.nix
@@ -0,0 +1,412 @@
+{
+  sysLib,
+  homeConfig,
+  nixosConfig,
+}: [
+  (
+    final: prev: let
+      inherit (prev) lib;
+
+      write_shell = {
+        name,
+        path,
+        dependencies ? [],
+        keepPath ? false,
+        completions ? false,
+      }:
+        sysLib.writeShellScript {
+          inherit name keepPath;
+          src = ./source/${path}/${name}.sh;
+          dependencies = dependencies ++ [prev.dash];
+          generateCompletions = completions;
+        };
+      write_python = {
+        name,
+        path,
+        dependencies_system ? [],
+        dependencies_python ? _: [],
+        keepPath ? false,
+      }: let
+        src = ./source/${path}/${name}.py;
+        dependencies =
+          [(prev.python3.withPackages dependencies_python)]
+          ++ dependencies_system;
+        path_setting =
+          if keepPath
+          then "--prefix PATH :"
+          else "--set PATH";
+      in
+        prev.runCommandLocal name {
+          nativeBuildInputs = [prev.makeWrapper] ++ dependencies;
+        }
+        ''
+          install -m755 ${src} -D "$out/bin/${name}"
+          patchShebangs "$out/bin/${name}"
+          wrapProgram "$out/bin/${name}" ${path_setting} ${prev.lib.makeBinPath dependencies};
+        '';
+
+      ## Begin of shell scripts
+      aumo-scr = write_shell {
+        name = "aumo";
+        path = "apps";
+        dependencies = builtins.attrValues {
+          inherit
+            (prev)
+            udisks
+            findutils
+            rofi
+            ;
+        };
+      };
+
+      battery-scr = write_shell {
+        name = "battery";
+        path = "wrappers";
+        dependencies = [];
+      };
+
+      brightness-scr = lib.mkIf nixosConfig.soispha.laptop.enable (write_shell {
+        name = "brightness";
+        path = "small_functions";
+        generateCompletions = true;
+        dependencies = [];
+        replacementStrings = {BACKLIGHT_NAME = nixosConfig.soispha.laptop.backlight;};
+      });
+
+      con2pdf-scr = sysLib.writeShellScript {
+        name = "con2pdf";
+        src = ./source/apps/con2pdf.sh;
+        dependencies = builtins.attrValues {inherit (prev) sane-backends imagemagick coreutils fd;};
+        generateCompletions = true;
+        replacementStrings = {
+          DEVICE_FUNCTION =
+            # This is here, because escaping the whole function, to use it in the shell script
+            # directly just isn't possible
+            prev.writeText "DEVICE_FUNCTION"
+            /*
+            bash
+            */
+            ''
+              scanimage -L | awk 'BEGIN { FS = "`" } { gsub(/'.*/, "", $2); print $2 }'
+            '';
+        };
+      };
+
+      description-scr = write_shell {
+        name = "description";
+        path = "specific/ytcc";
+        dependencies = builtins.attrValues {
+          inherit (prev) jq fmt less locale;
+        };
+      };
+
+      fupdate-scr = write_shell {
+        name = "fupdate";
+        path = "apps";
+        keepPath = true;
+        completions = true;
+        dependencies = builtins.attrValues {
+          inherit
+            (prev)
+            dash
+            nix
+            gnugrep
+            fd
+            coreutils
+            bat # used by batgrep
+            gnused # required by batgrep
+            git # needed to fetch through git
+            ;
+          inherit (prev.bat-extras) batgrep;
+        };
+      };
+
+      git-edit-index-scr = write_shell {
+        name = "git-edit-index";
+        path = "apps";
+        completions = true;
+        # This starts neovim, wich might want to shell out
+        keepPath = true;
+        dependencies = builtins.attrValues {
+          inherit
+            (prev)
+            git
+            gnused
+            # $EDITOR
+
+            ;
+        };
+      };
+
+      hibernate-scr = write_shell {
+        name = "hibernate";
+        path = "wrappers";
+        dependencies = builtins.attrValues {
+          inherit
+            (prev)
+            systemd
+            taskwarrior
+            ;
+        };
+      };
+
+      ll-scr = sysLib.writeShellScript {
+        name = "ll";
+        src = ./source/wrappers/ll.sh;
+        wrap = false;
+      };
+
+      # TODO: this need to be replaced with a wayland alternative
+      #  llp-scr = write_shell {
+      #     name = "llp";
+      #     path = "wrappers";
+      #     dependencies = builtins.attrValues {inherit (prev) lf ueberzug;};
+      #   };
+
+      lock-scr = write_shell {
+        name = "lock";
+        path = "wrappers";
+        dependencies = builtins.attrValues {
+          inherit
+            (prev)
+            taskwarrior
+            swaylock
+            ;
+        };
+      };
+
+      lyrics-scr = write_shell {
+        name = "lyrics";
+        path = "wrappers";
+        dependencies = builtins.attrValues {
+          inherit
+            (prev)
+            exiftool
+            mpc-cli
+            jq
+            less
+            locale # dependency of less
+            ;
+        };
+      };
+
+      mpc-fav-scr = write_shell {
+        name = "mpc-fav";
+        path = "wrappers";
+        dependencies = builtins.attrValues {
+          inherit
+            (prev)
+            mpc-cli
+            ;
+        };
+      };
+
+      mpc-rm-scr = write_shell {
+        name = "mpc-rm";
+        path = "wrappers";
+        dependencies = builtins.attrValues {
+          inherit
+            (prev)
+            mpc-cli
+            trash-cli
+            ;
+        };
+      };
+
+      mpc-scr = write_shell {
+        name = "mpc";
+        path = "wrappers";
+        dependencies = [
+          mpc-fav-scr
+          mpc-rm-scr
+          prev.mpc-cli
+        ];
+      };
+
+      nato-scr = write_python {
+        name = "nato";
+        path = "small_functions";
+        dependencies_python = ps: [];
+      };
+
+      neorg-scr = sysLib.writeShellScriptMultiPart {
+        name = "neorg";
+        keepPath = true;
+        src = ./source/specific/neorg/sh;
+        baseName = "main.sh";
+        cmdPrefix = "functions";
+        cmdNames = [
+          "add.sh"
+          "context.sh"
+          "dmenu.sh"
+          "f_start.sh"
+          "f_stop.sh"
+          "list.sh"
+          "project.sh"
+          "review.sh"
+          "utils.sh"
+          "workspace.sh"
+        ];
+        dependencies = with prev; [
+          cocogitto
+          rofi
+          libnotify
+        ];
+        generateCompletions = true;
+        replacementStrings = {
+          DEFAULT_NEORG_PROJECT_DIR =
+            homeConfig.programs.nixvim.plugins.neorg.modules."core.dirman".config.workspaces.projects;
+          HOME_TASKRC = "${homeConfig.xdg.configHome}/task/home-manager-taskrc";
+          NEORG_REVIEW_PATH = "${homeConfig.xdg.dataHome}/neorg/review";
+          ALL_PROJECTS_NEWLINE = "${homeConfig.soispha.taskwarrior.projects.projects_newline}";
+          ALL_PROJECTS_COMMA = "${homeConfig.soispha.taskwarrior.projects.projects_comma}";
+          ALL_PROJECTS_PIPE = "${homeConfig.soispha.taskwarrior.projects.projects_pipe}";
+          ALL_WORKSPACES = "${lib.strings.concatStringsSep "|" (builtins.attrNames homeConfig.programs.nixvim.plugins.neorg.modules."core.dirman".config.workspaces)}";
+          ID_GENERATION_FUNCTION = "${sysLib.writeShellScript {
+            name = "neorg_id_function";
+            src = ./source/specific/neorg/neorg_id_function.sh;
+            dependencies = with prev; [
+              taskwarrior
+              gawk
+              findutils # xargs
+            ];
+          }}/bin/neorg_id_function";
+
+          # TODO: Replace the hard-coded path here with some reference <2023-10-20>
+          TASK_PROJECT_FILE = "/home/soispha/repos/nix/nixos-config/hm/soispha/conf/taskwarrior/projects/default.nix";
+        };
+      };
+
+      screenshot_persistent-scr = write_shell {
+        name = "screenshot_persistent";
+        path = "small_functions";
+        keepPath = true;
+        dependencies = builtins.attrValues {
+          inherit
+            (prev)
+            grim
+            slurp
+            alacritty
+            rofi
+            libnotify
+            lf # TODO: add llp
+            ;
+        };
+      };
+
+      screenshot_temporary-scr = write_shell {
+        name = "screenshot_temporary";
+        path = "small_functions";
+        dependencies = builtins.attrValues {inherit (prev) grim slurp wl-clipboard;};
+      };
+
+      show-scr = write_shell {
+        name = "show";
+        path = "wrappers";
+        keepPath = true; # I might want to use nvim in less (and shell escapes)
+        dependencies = builtins.attrValues {inherit (prev) less locale;};
+      };
+
+      sort_song-scr = write_shell {
+        name = "sort_song";
+        path = "wrappers";
+        dependencies = builtins.attrValues {inherit (prev) mediainfo jq gawk;};
+      };
+
+      spodi-scr = sysLib.writeShellScriptMultiPart {
+        name = "spodi";
+        keepPath = false;
+        src = ./source/specific/spodi;
+        baseName = "spodi.sh";
+        cmdPrefix = "sh";
+        cmdNames = [
+          "download.sh"
+          "update.sh"
+        ];
+        dependencies = with prev; [
+          gawk
+          expect
+          spotdl
+          fd
+          coreutils
+        ];
+        generateCompletions = true;
+        replacementStrings = {
+          XDG_CACHE_HOME = homeConfig.xdg.cacheHome;
+          XDG_MUSIC_DIR = homeConfig.xdg.userDirs.music;
+        };
+      };
+
+      update-sys-scr = write_shell {
+        name = "update-sys";
+        path = "small_functions";
+        completions = true;
+        dependencies = builtins.attrValues {
+          inherit
+            (prev)
+            git
+            nixos-rebuild
+            sudo
+            openssh
+            coreutils
+            mktemp
+            gnugrep
+            gnused
+            systemd
+            ;
+        };
+      };
+
+      virsh-del-scr = write_shell {
+        name = "virsh-del";
+        path = "wrappers";
+        dependencies = builtins.attrValues {inherit (prev) libvirt;};
+      };
+
+      yti-scr = write_shell {
+        name = "yti";
+        path = "wrappers";
+        dependencies = builtins.attrValues {inherit (prev) gawk expect yt-dlp;};
+      };
+    in {
+      scripts = {
+        # llp = llp-scr; # TODO: see above
+        aumo = aumo-scr;
+        battery = battery-scr;
+        brightness = brightness-scr;
+        con2pdf = con2pdf-scr;
+        description = description-scr;
+        fupdate = fupdate-scr;
+        git-edit-index = git-edit-index-scr;
+        hibernate = hibernate-scr;
+        ll = ll-scr;
+        lock = lock-scr;
+        lyrics = lyrics-scr;
+        mpc = mpc-scr;
+        mpc-fav = mpc-fav-scr;
+        mpc-rm = mpc-rm-scr;
+        nato = nato-scr;
+        neorg = neorg-scr;
+        screenshot_persistent = screenshot_persistent-scr;
+        screenshot_temporary = screenshot_temporary-scr;
+        show = show-scr;
+        sort_song = sort_song-scr;
+        spodi = spodi-scr;
+        update-sys = update-sys-scr;
+        virsh-del = virsh-del-scr;
+        yti = yti-scr;
+      };
+    }
+  )
+]
+
+
+    pkgs = import nixpkgs (import ./sys/nixpkgs {
+      inherit (nixpkgs) lib;
+      inherit system sysLib;
+
+      # FIXME: Don't unconditionally use tiamat here <2024-02-24>
+      homeConfig = self.nixosConfigurations.tiamat.config.home-manager.users.soispha;
+      nixosConfig = self.nixosConfigurations.tiamat.config;
+      overlays = [];
+    });
diff --git a/pkgs/sources/scripts/source/apps/aumo.sh b/pkgs/sources/scripts/source/apps/aumo.sh
new file mode 100755
index 00000000..84d39deb
--- /dev/null
+++ b/pkgs/sources/scripts/source/apps/aumo.sh
@@ -0,0 +1,28 @@
+#! /usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+unmounting() {
+    disk_name="$(find /dev/disk/by-label -type l -printf "%P|" | rofi -sep "|" -dmenu -p "Select disk to mount")"
+
+    udisksctl unmount --block-device "/dev/disk/by-label/$disk_name"
+}
+
+mounting() {
+    disk_name="$(find /dev/disk/by-label -type l -printf "%P|" | rofi -sep "|" -dmenu -p "Select disk to mount")"
+
+    udisksctl mount --block-device "/dev/disk/by-label/$disk_name"
+}
+
+case "$1" in
+"mount")
+    mounting
+    ;;
+"unmount" | "umount")
+    unmounting
+    ;;
+*)
+    die "Usage: $NAME mount|unmount"
+    ;;
+esac
diff --git a/pkgs/sources/scripts/source/apps/con2pdf.sh b/pkgs/sources/scripts/source/apps/con2pdf.sh
new file mode 100755
index 00000000..08bf8998
--- /dev/null
+++ b/pkgs/sources/scripts/source/apps/con2pdf.sh
@@ -0,0 +1,234 @@
+#! /usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+# needed for help() and version
+# shellcheck disable=2034
+AUTHORS="Soispha"
+# shellcheck disable=2034
+YEARS="2023"
+# shellcheck disable=2034
+VERSION="1.0.0"
+
+# NAME is from the wrapper
+# shellcheck disable=SC2269
+NAME="$NAME"
+help() {
+    cat <<EOF
+Scan images and turn them into a pdf.
+
+Usage:
+    $NAME [OPTIONS] --name --device
+
+OPTIONS:
+    --out-dir | -o [FILE]
+                            Path to place the generated pdf files (default: ./pdf).
+
+    --name | -n NAME
+                            Name for the pdf files (e.g. <NAME>_1.pdf).
+
+    --num-pages | -p NUM
+                            Number of pages to merge into one pdf (default: 1).
+
+    --device | -d DEVICE
+                            Device used for scanning.
+
+    --method | -m METHOD
+                            Method to use for scanning (default: ADF).
+
+    --help | -h
+                            Display this help and exit.
+
+    --version | -v
+                            Display version and copyright information and exit.
+ARGUMENTS:
+    FILE := [[fd . --max-depth 3]]
+                            A name of a file to store, default is: ./pdf
+
+    NAME | * := [[fd . --max-depth 3]]
+                            The basename of the generated files
+
+    NUM | *([0-9]) := 0 | 1 | 2 | 3 | 4
+                            Possible numbers of pages, can be more than 4
+
+    DEVICE := [[$(cat %DEVICE_FUNCTION)]]
+                            Possible scanner names
+
+    METHOD := ADF | Flatbed
+                            The scanning method to use, not all scanners support both of
+                            these. The default is ADF
+EOF
+}
+
+scan_adf() {
+    device="$1"
+    sides_per_page="$2"
+    method="ADF"
+    for i in $(seq "$sides_per_page"); do
+        do_until_success \
+            "scanimage --format=tiff --progress --source='$method' --device='$device' --batch=%d.tif --batch-increment='$sides_per_page' --batch-start='$i'" \
+            "warn 'Retrying scan, as we assume a network error!'"
+
+        if [ "$sides_per_page" -ne 1 ]; then
+            msg "Finished turn, please change side!"
+            readp "Press enter to continue" noop
+        fi
+    done
+}
+process_images_adf() {
+    tiff_temp_path="$1"
+    output_directory="$2"
+    name="$3"
+
+    counter=0
+    pdf_counter=0
+    image_cache="$(mktmp)"
+    while read -r scanned_image; do
+        dbg "$scanned_image (scanned_image) at $counter (counter)"
+        echo "$scanned_image" >>"$image_cache"
+        : $((counter += 1))
+        if [ "$counter" = "$number_of_pages" ]; then
+            dbg "$counter == $number_of_pages"
+            counter=0
+            convert_images "$image_cache" "${name}_$pdf_counter" "$output_directory"
+            : $((pdf_counter += 1))
+            printf "" >"$image_cache"
+        fi
+    done <"$(tmp_pipe fd . "$tiff_temp_path" "|" sort -V)"
+}
+
+scan_flatbed() {
+    device="$1"
+    number_of_pages"$2"
+    method="Flatbed"
+    for i in $(seq "$number_of_pages"); do
+        do_until_success \
+            "scanimage --format=tiff --progress --source='$method' --device='$device' --output-file=$i.tiff" \
+            "warn 'Retrying scan, as we assume a network error!'"
+        if [ "$number_of_pages" -ne 1 ]; then
+            msg "Finished turn, please change side!"
+            readp "Press enter to continue" noop
+        fi
+    done
+}
+process_images_flatbed() {
+    tiff_temp_path="$1"
+    output_directory="$2"
+    name="$3"
+
+    counter=0
+    image_cache="$(mktmp)"
+    while read -r scanned_image; do
+        echo "$scanned_image" >>"$image_cache"
+        : $((counter += 1))
+        if [ "$counter" = "$number_of_pages" ]; then
+            counter=0
+            convert_images "$image_cache" "$name" "$output_directory"
+            printf "" >"$image_cache"
+        fi
+    done <"$(tmp_pipe fd . "$tiff_temp_path" "|" sort -V)"
+}
+convert_images() {
+    image_cache="$1"
+    pdf_name="$2"
+    output_dir="$3"
+
+    set --
+    while read -r image; do
+        dbg "setting image: $image"
+        set -- "$@" "$image"
+    done <"$image_cache"
+
+    while [ -e "$output_dir/${pdf_name}.pdf" ]; do
+        pdf_name="${pdf_name}_$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 25)"
+    done
+    dbg "using pdf_name: $pdf_name"
+    convert "$@" -compress jpeg -quality 100 "$output_dir/${pdf_name}.pdf"
+}
+
+scan() {
+    number_of_pages="$1"
+    device="$2"
+    output_directory="$(readlink -f "$3")"
+    name="$4"
+    method="$5"
+
+    [ -z "$number_of_pages" ] && die "Parameter 'number_of_pages' is not set!"
+    [ -z "$device" ] && die "Parameter 'device' is not set!"
+    [ -z "$output_directory" ] && die "Parameter 'output_directory' is not set!"
+    [ -z "$name" ] && die "Parameter 'name' is not set!"
+    [ -z "$method" ] && die "Parameter 'method' is not set!"
+
+    tiff_temp_path="$(mktmp -d)"
+    cd "$tiff_temp_path" || die "Bug"
+
+    msg "Started scanning..."
+    if [ "$method" = "Flatbed" ]; then
+        scan_flatbed "$device" "$number_of_pages"
+    else
+        scan_adf "$device" "$number_of_pages"
+    fi
+
+    msg "Creating output directory..."
+    mkdir "$output_directory"
+    cd "$output_directory" || die "Bug"
+
+    msg "Converting images to pdfs..."
+    if [ "$method" = "Flatbed" ]; then
+        process_images_flatbed "$tiff_temp_path" "$output_directory" "$name"
+    else
+        process_images_adf "$tiff_temp_path" "$output_directory" "$name"
+    fi
+}
+
+for input in "$@"; do
+    case "$input" in
+    "--help" | "-h")
+        help
+        exit 0
+        ;;
+    "--version" | "-v")
+        version
+        exit 0
+        ;;
+    esac
+done
+
+number_of_pages="1"
+unset device
+output_directory="$(pwd)/pdf"
+unset name
+method="ADF"
+
+while [ "$#" -ne 0 ]; do
+    case "$1" in
+    "--help" | "-h") ;;
+    "--version" | "-v") ;;
+    "--out-dir" | "-o")
+        shift 1
+        output_directory="$1"
+        ;;
+    "--name" | "-n")
+        shift 1
+        name="$1"
+        ;;
+    "--num-pages" | "-p")
+        shift 1
+        number_of_pages="$1"
+        ;;
+    "--device" | "-d")
+        shift 1
+        device="$1"
+        ;;
+    "--method" | "-m")
+        shift 1
+        method="$1"
+        ;;
+    *)
+        die "Command line arg $1 does not exist. See --help for a list."
+        ;;
+    esac
+    shift 1
+done
+scan "$number_of_pages" "$device" "$output_directory" "$name" "$method"
diff --git a/pkgs/sources/scripts/source/apps/fupdate.1.md b/pkgs/sources/scripts/source/apps/fupdate.1.md
new file mode 100644
index 00000000..710e8fb7
--- /dev/null
+++ b/pkgs/sources/scripts/source/apps/fupdate.1.md
@@ -0,0 +1,70 @@
+% FUPDATE(1) fupdate 1.0.0
+% Soispha
+% May 2023
+
+# NAME
+
+fupdate - updates your flake, while checking for common mistakes
+
+# SYNOPSIS
+
+**fupdate** list of \[*flake*|*\<some word>*|*--help*|*-h*\]
+
+# DESCRIPTION
+
+Argument can be stacked, this makes it possible to specify multiple targets to be updated in succession. See the Examples section for further details.
+
+No argument or *flake*
+: **fupdate**, when executed without arguments or with *flake*, will update your *flake.lock*, check for duplicate flake inputs, i.e., an input has an input declared, which you have also declared as input, and will run a script called *update.sh*, if you allow it.
+The allowance for the script is asked, when you run **fupdate** and the found script is not yet allowed. Furthermore, the allowance is based on the concrete sha256 hash of the script, so any changes will require another allowance.
+
+**\<some word>** as argument
+: If the executable **update-\<some word>** is reachable thought the PATH variable, than this is run. Otherwise, the program will exit.
+
+# OPTIONS
+
+**--help**, **-h**
+: Displays a help message and exit.
+
+**--version**, **-v**
+: Displays the software version and exit.
+
+# EXAMPLES
+
+**fupdate** or **fupdate flake**
+: Updates your *flake.lock*. See the Description section for further details.
+
+**fupdate sys**
+: Run the executable **update-sys**, if it exists. See the Description section for further details.
+
+**fupdate flake sys docs**
+: First updates your flake, then, if the command succeeded, runs **update-sys**, afterweich **update-docs** is run.
+
+# FILES
+
+*update.sh*
+: This is supposed to be a shell script located in your flake base directory, i.e., the directory which contains both a *flake.nix* and a *flake.lock* file.
+
+*~/.local/share/flake-update/*
+: **fupdate** will store the hashes to the allowed *update.sh* files here.
+
+# BUGS
+
+Report bugs to <https://codeberg.org/soispha/flake_update/issues>.
+
+# COPYRIGHT
+
+Copyright (C) 2023  Soispha
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <https://www.gnu.org/licenses/>.
diff --git a/pkgs/sources/scripts/source/apps/fupdate.sh b/pkgs/sources/scripts/source/apps/fupdate.sh
new file mode 100755
index 00000000..4322610a
--- /dev/null
+++ b/pkgs/sources/scripts/source/apps/fupdate.sh
@@ -0,0 +1,197 @@
+#! /usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+UPDATE_SCRIPT_NAME="update.sh"
+CONFIG_DIRECTORY_PATH="$HOME/.local/share/flake-update"
+
+# Both are used in version()
+# shellcheck disable=SC2034
+AUTHORS="Soispha"
+# shellcheck disable=SC2034
+YEARS="2023"
+
+UPDATE_SCRIPT_NOT_WANTED=false
+
+# Searches upward for a `UPDATE_SCRIPT_NAME` script
+# Returns a path to the script if it exists, otherwise nothing is returned
+check_for_update_script() {
+    dirname="$(search_upward_files "$UPDATE_SCRIPT_NAME")"
+    if [ "$dirname" ]; then
+        printf "%s/%s" "$dirname" "$UPDATE_SCRIPT_NAME"
+    fi
+}
+
+# Checks if a given path to the update script is allowed.
+# Takes the path as input
+# Return 0, if allowed, 1 if not.
+check_for_allowed_update_script() {
+    update_script="$1"
+    config_path="${CONFIG_DIRECTORY_PATH}${update_script}"
+    update_script_hash="$(sha256sum "$update_script")"
+    if [ -f "$config_path" ]; then
+        if [ "$(cat "$config_path")" = "$update_script_hash" ]; then
+            dbg "Recorded hash matches"
+            return 0
+        else
+            dbg "Recorded hash \'$(cat "$config_path")\' does not match real hash \'$update_script_hash\', assuming not allowed"
+            return 1
+        fi
+    else
+        dbg "Path \'$config_path\' does not exist, assuming not allowed"
+        return 1
+    fi
+}
+
+# Asks the user if they want to allow a given script.
+# Takes the path as input
+ask_to_allow_update_script() {
+    update_script="$1"
+    config_path="${CONFIG_DIRECTORY_PATH}${update_script}"
+    update_script_hash="$(sha256sum "$update_script")"
+    println "\033[2J" # clear the screen
+    cat "$update_script"
+    readp "Do you want to allow this script?[N/y]: " allow
+    # shellcheck disable=SC2154
+    dbg "allow is: $allow"
+    case "$allow" in
+    [yY])
+        dbg "allowed script"
+        dbg "storing contents in: $config_path"
+        mkdir --parents "$(dirname "$config_path")"
+        print "$update_script_hash" >"$config_path"
+        ;;
+    *)
+        UPDATE_SCRIPT_NOT_ALLOWED=true
+        ;;
+    esac
+}
+
+# Runs the provided script and continues to update the nix flake
+# Takes the path to the script and the directory to the flake as arguments
+# If the path to the update script is empty, it will be ignored
+update() {
+    update_script="$1"
+    flake_base_dir="$2"
+    shift 2
+    dbg "Provided following args to update script: '$*'"
+
+    cd "$flake_base_dir" || die "Provided dir \'$flake_base_dir\' can not be accessed"
+    dbg "changed directory to: $flake_base_dir"
+
+    nix flake update
+
+    if ! [ "$update_script" = "" ] && ! [ "$UPDATE_SCRIPT_NOT_WANTED" = "true" ]; then
+        "$update_script" "$@"
+    fi
+
+    if grep '[^0-9]_[0-9]' flake.lock >/dev/null; then
+        batgrep '[^0-9]_[0-9]' flake.lock
+        die "Your flake.nix contains duplicate inputs!"
+    fi
+}
+
+help() {
+    cat <<EOF
+This is a Nix flake update manager.
+
+USAGE:
+    $NAME [--help | --version] [flake [--no-script] | <some other command>]
+
+OPTIONS:
+    --help   | -h
+                            Display this help and exit.
+
+    --version   | -v
+                            Display version and copyright information and exit.
+
+    --no-script
+                            Avoid running the 'update.sh' script
+COMMANDS:
+    flake
+                            update the flake project
+
+    <some other command>
+                            runs a executable called "update-<some other command>", if it exists
+EOF
+}
+
+main() {
+    if ! [ "$UPDATE_SCRIPT_NOT_ALLOWED" = true ]; then
+        update_script="$(check_for_update_script)"
+        flake_base_dir="$(search_flake_base_dir)" # Assume, that the update script is in the base dir
+        dbg "update_script is: $update_script"
+        dbg "flake_base_dir is: $flake_base_dir"
+
+        if [ "$update_script" = "" ]; then
+            update "" "$flake_base_dir" "$@"
+        elif check_for_allowed_update_script "$update_script" && ! [ "$update_script" = "" ]; then
+            update "$update_script" "$flake_base_dir" "$@"
+        else
+            ask_to_allow_update_script "$update_script"
+            main "$@"
+        fi
+    fi
+}
+
+if [ "$#" -eq 0 ]; then
+    main
+    exit 0
+fi
+
+for input in "$@"; do
+    case "$input" in
+    "--help" | "-h")
+        help
+        exit 0
+        ;;
+    "--version" | "-v")
+        version
+        exit 0
+        ;;
+    "--no-script" | "-n")
+        UPDATE_SCRIPT_NOT_WANTED=true
+        ;;
+    "--")
+        end_of_cli_options=true
+
+        # Stop processing args after that marker.
+        break
+        ;;
+    esac
+    [ "$end_of_cli_options" = "true" ] && break
+done
+
+case "$1" in
+"flake")
+    shift 1
+
+    # Filter out fupdate specific flags
+    while [ "$1" != "--" ]; do
+        # FIXME: This check allows to add a flag multiple times, but this should probably
+        # not be allowed <2024-03-29>
+        case "$1" in
+        "--no-script" | "-n")
+            shift 1
+            ;;
+        *)
+            break
+            ;;
+        esac
+    done
+
+    [ "$1" = "--" ] && shift 1
+    main "$@"
+    ;;
+*)
+    command="$1"
+    shift 1
+    [ "$1" = "--" ] && shift 1
+    if which update-"$command" >/dev/null 2>&1; then
+        update-"$command" "$@"
+    else
+        die "command \"update-$command\" is not executable, or does not exist"
+    fi
+    ;;
+esac
diff --git a/pkgs/sources/scripts/source/apps/git-edit-index.sh b/pkgs/sources/scripts/source/apps/git-edit-index.sh
new file mode 100755
index 00000000..e73dc53c
--- /dev/null
+++ b/pkgs/sources/scripts/source/apps/git-edit-index.sh
@@ -0,0 +1,98 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+# needed for help() and version
+# shellcheck disable=2034
+AUTHORS="Soispha"
+# shellcheck disable=2034
+YEARS="2024"
+# shellcheck disable=2034
+VERSION="1.0.0"
+
+# NAME is from the wrapper
+# shellcheck disable=SC2269
+NAME="$NAME"
+
+help() {
+    cat <<EOF
+Edit a file from the index. This script does not touch the unstaged variant of the file.
+
+USAGE:
+    $NAME [OPTIONS] [--] FILES..
+
+OPTIONS:
+    --
+                            Stop parsing options and interpret everything as an file.
+
+    --help | -h
+                            Display this help and exit.
+
+    --version | -v
+                            Display version and copyright information and exit.
+ARGUMENTS:
+    FILES := [[ git diff --name-only --cached --diff-filter=AM ]]
+                            The files to edit.
+
+EOF
+}
+
+GIT_DIR="$(git rev-parse --show-toplevel)"
+materialize_file() {
+    git diff --cached "$1" >"$GIT_DIR/.git/EDIT_INDEX_PATCH"
+
+    git add "$1"
+    git restore --staged "$1"
+    cat "$1" >"$GIT_DIR/.git/EDIT_INDEX_FILE"
+    git restore "$1"
+
+    git apply "$GIT_DIR/.git/EDIT_INDEX_PATCH"
+    "$EDITOR" "$1"
+
+    git add "$1"
+    mv "$GIT_DIR/.git/EDIT_INDEX_FILE" "$1"
+}
+
+edit() {
+    files_to_add="$(mktmp)"
+    realpath --relative-to=. "$@" >"$files_to_add"
+
+    index_files="$(mktmp)"
+    git diff --name-only --cached --diff-filter=AM >"$index_files"
+
+    while read -r file; do
+        if grep -q "$file" "$files_to_add"; then
+            sed -i "s|$file||" "$files_to_add"
+            materialize_file "$file"
+        fi
+    done <"$index_files"
+
+    files_to_check="$(mktmp)"
+    clean "$files_to_add" >"$files_to_check"
+    if [ "$(wc -l <"$files_to_check")" -gt 0 ]; then
+        warn "Could not edit every file:"
+        cat "$files_to_add"
+    fi
+}
+
+for arg in "$@"; do
+    case "$arg" in
+    "--help" | "-h")
+        help
+        exit 0
+        ;;
+    "--version" | "-v")
+        version
+        exit 0
+        ;;
+    "--")
+        end_of_cli_options=true
+        ;;
+    esac
+    [ "$end_of_cli_options" = "true" ] && break
+done
+
+edit "$@"
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/small_functions/brightness.sh b/pkgs/sources/scripts/source/small_functions/brightness.sh
new file mode 100755
index 00000000..a7272279
--- /dev/null
+++ b/pkgs/sources/scripts/source/small_functions/brightness.sh
@@ -0,0 +1,80 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+help() {
+    cat <<EOF
+This is a system brightness manager
+
+USAGE:
+    $NAME up [VALUE] | down [VALUE]
+
+OPTIONS:
+    --help   | -h
+                                Output this help and exit.
+
+    --version   | -v
+                                Output the version and exit.
+
+COMMANDS:
+    up [VALUE]
+                                Increase the brightness by VALUE or 5%.
+
+    down [VALUE]
+                                Decrease the brightness by VALUE or 5%.
+
+ARGUMENTS:
+    VALUE := [[seq 0 100]]
+                                The amount to increase/decrease the brightness. In percentage
+EOF
+}
+
+BACKLIGHT="/sys/class/%BACKLIGHT_NAME"
+
+brightness() {
+    offset="$1"
+
+    max="$(cat $BACKLIGHT/max_brightness)"
+    cur="$(cat $BACKLIGHT/brightness)"
+    percentage="$(echo | awk --assign=cur="$cur" --assign=max="$max" '{printf cur / max}')"
+
+    new="$(echo | awk --assign=per="$percentage" --assign=offset="$offset" '{printf per + (offset / 10)}')"
+
+    output="$(echo | awk --assign=new="$new" --assign=max="$max" '{printf max * new}')"
+
+    msg "echo \"$output\" > $BACKLIGHT/brightness"
+}
+
+for arg in "$@"; do
+    case "$arg" in
+    "--help" | "-h")
+        help
+        exit 0
+        ;;
+    "--version" | "-v")
+        version
+        exit 0
+        ;;
+    esac
+done
+
+case "$1" in
+"up")
+    shift 1
+    value="5"
+    [ -n "$1" ] && value="$1"
+    brightness "+$value"
+    ;;
+"down")
+    shift 1
+    value="-5"
+    [ -n "$1" ] && value="$1"
+    brightness "-$value"
+    ;;
+*)
+    die "The command '$1' does not exist! See '--help' for a list"
+    ;;
+esac
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/small_functions/nato.py b/pkgs/sources/scripts/source/small_functions/nato.py
new file mode 100755
index 00000000..e9d15f56
--- /dev/null
+++ b/pkgs/sources/scripts/source/small_functions/nato.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python3
+# originally from here: https://cgit.pacien.net/desktop-utilities/
+
+import sys
+
+alphabet = {
+    "nato": {
+        "A": "Alfa",  # No idea why this is not just 'Alpha' ..
+        "B": "Bravo",
+        "C": "Charlie",
+        "D": "Delta",
+        "E": "Echo",
+        "F": "Foxtrot",
+        "G": "Golf",
+        "H": "Hotel",
+        "I": "India",
+        "J": "Juliett",
+        "K": "Kilo",
+        "L": "Lima",
+        "M": "Mike",
+        "N": "November",
+        "O": "Oscar",
+        "P": "Papa",
+        "Q": "Quebec",
+        "R": "Romeo",
+        "S": "Sierra",
+        "T": "Tango",
+        "U": "Uniform",
+        "V": "Victor",
+        "W": "Whiskey",
+        "X": "X-ray",
+        "Y": "Yankee",
+        "Z": "Zulu",
+        "0": "Nadazero",
+        "1": "Unaone",
+        "2": "Bissotwo",
+        "3": "Terrathree",
+        "4": "Kartefour",
+        "5": "Pantafive",
+        "6": "Soxisix",
+        "7": "Setteseven",
+        "8": "Oktoeight",
+        "9": "Novenine",
+        ",": "Comma",
+        "/": "Forward slash",
+        ".": "Stop/Decimal",
+    },
+    "german": {
+        "A": "Aachen",
+        "Ä": "Umlaut Aachen",
+        "B": "Berlin",
+        "C": "Chemnitz",
+        "D": "Düsseldorf",
+        "E": "Essen",
+        "F": "Frankfurt",
+        "G": "Goslar",
+        "H": "Hamburg",
+        "I": "Ingelheim",
+        "J": "Jena",
+        "K": "Köln",
+        "L": "Leipzig",
+        "M": "München",
+        "N": "Nürnberg",
+        "O": "Offenbach",
+        "Ö": "Umlaut Offenbach",
+        "P": "Potsdam",
+        "Q": "Quickborn",
+        "R": "Rostock",
+        "S": "Salzwedel",
+        "ẞ": "Eszett",
+        "T": "Tübingen",
+        "U": "Unna",
+        "Ü": "Umlaut Unna",
+        "V": "Völklingen",
+        "W": "Wuppertal",
+        "X": "Xanten",
+        "Y": "Ypsilon",
+        "Z": "Zwickau",
+    },
+}
+
+
+def str_to_telephony(phrase, language):
+    language_alphabet = alphabet[language]
+
+    return [
+        language_alphabet[c] if c in language_alphabet else c for c in phrase.upper()
+    ]
+
+
+language = sys.argv[1]
+if language not in ["nato", "german"]:
+    print(
+        f"Langugae '{language}' is not a valid language, only 'nato' and 'german' are!",
+        file=sys.stderr,
+    )
+    exit(1)
+
+print(
+    "\n".join(
+        str_to_telephony(
+            " ".join(sys.argv[2:]),
+            language,
+        )
+    )
+)
diff --git a/pkgs/sources/scripts/source/small_functions/screenshot_persistent.sh b/pkgs/sources/scripts/source/small_functions/screenshot_persistent.sh
new file mode 100755
index 00000000..4308b8d2
--- /dev/null
+++ b/pkgs/sources/scripts/source/small_functions/screenshot_persistent.sh
@@ -0,0 +1,22 @@
+#! /usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+# only generate a path (this could lead to a time-of-check/time-of-use bug)
+tmp="$(mktmp --dry-run)"
+
+if grim -g "$(slurp)" "$tmp"; then
+    name="$(rofi -dmenu -p "Name of screenshot: " -l 0)"
+    screen_shot_path="$HOME/media/pictures/screenshots/$name.png"
+    while [ -f "$screen_shot_path" ]; do
+        notify-send "Warning" 'Screenshot name already in use!'
+        name="$(rofi -dmenu -p "New name of screenshot: " -l 0)"
+        screen_shot_path="$HOME/media/pictures/screenshots/$name.png"
+    done
+
+    mv "$tmp" "$screen_shot_path"
+    alacritty -e lf -command ":{{ set sortby atime; set reverse!; }}"
+fi
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/small_functions/screenshot_temporary.sh b/pkgs/sources/scripts/source/small_functions/screenshot_temporary.sh
new file mode 100755
index 00000000..8968ca79
--- /dev/null
+++ b/pkgs/sources/scripts/source/small_functions/screenshot_temporary.sh
@@ -0,0 +1,8 @@
+#! /usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+grim -g "$(slurp)" | wl-copy
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/small_functions/update-sys.sh b/pkgs/sources/scripts/source/small_functions/update-sys.sh
new file mode 100755
index 00000000..d28247f6
--- /dev/null
+++ b/pkgs/sources/scripts/source/small_functions/update-sys.sh
@@ -0,0 +1,85 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+help() {
+    cat <<EOF
+This is a NixOS System flake update manager.
+
+USAGE:
+    $NAME [--branch <branchname>] [--help]
+
+OPTIONS:
+    --branch | -b  BRANCHNAME
+                                select a branch to update from.
+
+    --mode   | -m  MODE
+                                select a mode to update with
+
+    --help   | -h
+                                output this help.
+ARGUMENTS:
+    BRANCHNAME := [[ git branch --list --format '%(refname:short)' ]]
+                                The name of the branch to deploy the config from
+
+    MODE := switch|boot|test|build|dry-build|dry-activate|edit|repl|build-vm|build-vm-with-bootloader
+                                See the 'nixos-rebuild' manpage for more information about these modes.
+EOF
+    exit "$1"
+}
+default_branch=$(mktmp)
+BRANCH=""
+
+while [ "$#" -gt 0 ]; do
+    case "$1" in
+    "--help" | "-h")
+        help 0
+        ;;
+    "--branch" | "-b")
+        if [ -n "$2" ]; then
+            BRANCH="$2"
+        else
+            error "$1 requires an argument"
+            help 1
+        fi
+        shift 2
+        ;;
+    "--mode" | "-m")
+        if [ -n "$2" ]; then
+            MODE="$2"
+        else
+            error "$1 requires an argument"
+            help 1
+        fi
+        shift 2
+        ;;
+    *)
+        error "the option $1 does not exist!"
+        help 1
+        ;;
+    esac
+done
+
+cd /etc/nixos || die "No /etc/nixos"
+msg "Starting system update..."
+git remote update origin --prune >/dev/null 2>&1
+if ! [ "$BRANCH" = "" ]; then
+    git switch "$BRANCH" >/dev/null 2>&1 && msg2 "Switched to branch '$BRANCH'"
+fi
+msg2 "Updating git repository..."
+git pull --rebase
+
+git remote show origin | grep 'HEAD' | cut -d':' -f2 | sed -e 's/^ *//g' -e 's/ *$//g' >"$default_branch" &
+
+msg2 "Updating system..."
+if [ -n "$MODE" ]; then
+    nixos-rebuild "$MODE"
+else
+    nixos-rebuild switch
+fi
+
+git switch "$(cat "$default_branch")" >/dev/null 2>&1 && msg2 "Switched to branch '$(cat "$default_branch")'"
+msg "Finished Update!"
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/specific/neorg/neorg_id_function.sh b/pkgs/sources/scripts/source/specific/neorg/neorg_id_function.sh
new file mode 100755
index 00000000..865ecacf
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/neorg_id_function.sh
@@ -0,0 +1,16 @@
+#! /usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+context="$(task _get rc.context)"
+if [ "$context" ]; then
+    filter="project:$context"
+else
+    filter="0-10000"
+fi
+tasks="$(task "$filter" _ids)"
+
+if [ "$tasks" ]; then
+    echo "$tasks" | xargs task _zshids | awk -F: -v q="'" '{gsub(/'\''/, q "\\" q q ); print $1 ":" q $2 q}'
+fi
diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/add.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/add.sh
new file mode 100755
index 00000000..5a830a10
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/add.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env dash
+
+add0open_taskwarrior_project_file() {
+    task_project_file="%TASK_PROJECT_FILE"
+
+    cd "$(dirname $task_project_file)" || die "BUG: task_project_file ('$task_project_file') can't be accessed"
+
+    git_dir="$(search_flake_base_dir)"
+    [ "$git_dir" ] || die "(BUG): No git directory?"
+    cd "$git_dir" || die "Unreachable, this MUST exists"
+
+    nvim "$task_project_file"
+    git add "$task_project_file"
+
+    base_task_project_file_path="$(awk "{ gsub(\"$git_dir/\", \"\", \$0); print }" "$(ptmp "$task_project_file")")"
+    git add $task_project_file
+
+    # Check that only the project file has been added (and that our file is actually
+    # modified)
+    if git status --porcelain=v2 | awk -v path="$base_task_project_file_path" 'BEGIN { hit = 0 } { if ($2 ~ /A./ || $2 ~ /M./) { if ($NF ~ path) { hit = 1 } else { hit = 0; exit 1 } } } END { if (hit == 1) { exit 0 } else { exit 1 } }'; then
+        git commit --verbose --message="chore($(dirname "$base_task_project_file_path")): Update"
+    fi
+}
diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/context.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/context.sh
new file mode 100755
index 00000000..7095847d
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/context.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env dash
+
+context0open_current_task_context() {
+    current_context="$(utils0get_current_context)"
+
+    if [ "$current_context" ]; then
+        context_path="$(utils0get_current_context_path "$current_context")"
+
+        extended_neorg_project_dir="$(utils0get_neorg_project_dir)"
+        cd "$extended_neorg_project_dir" || die "(BUG?): Can not access the project dir: $extended_neorg_project_dir"
+
+        nvim "$extended_neorg_project_dir/$context_path"
+
+        git add .
+        git commit --message="chore($(dirname "$context_path")): Update" --no-gpg-sign
+    else
+        warn "No context active"
+    fi
+}
+
+context0open_current_task_context_at_task_id() {
+    task_id="$1"
+    current_context="$(utils0get_current_context)"
+
+    if [ "$current_context" ]; then
+        context_path="$(utils0get_current_context_path "$current_context")"
+        extended_neorg_project_dir="$(utils0get_neorg_project_dir)"
+        task_uuid="$(task "$task_id" uuids)"
+
+        cd "$extended_neorg_project_dir" || die "(BUG?): Can not access the project dir: $extended_neorg_project_dir"
+
+        if ! grep -q "% $task_uuid" "$extended_neorg_project_dir/$context_path"; then
+            echo "* TITLE (% $task_uuid)" >>"$extended_neorg_project_dir/$context_path"
+        fi
+
+        nvim "$extended_neorg_project_dir/$context_path" -c "/% $task_uuid"
+
+        git add .
+        git commit --message="chore($(dirname "$context_path")): Update" --no-gpg-sign
+    else
+        warn "No context active"
+    fi
+}
diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/dmenu.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/dmenu.sh
new file mode 100755
index 00000000..5a138982
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/dmenu.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env dash
+
+dmenu0open_context_in_browser() {
+    project="$(echo "%ALL_PROJECTS_PIPE" | rofi -sep "|" -dmenu)"
+
+    if [ "$project" ]; then
+        [ -d "%NEORG_REVIEW_PATH" ] || mkdir --parents "%NEORG_REVIEW_PATH"
+        [ -f "%NEORG_REVIEW_PATH/$project.lock" ] || touch "%NEORG_REVIEW_PATH/$project.lock"
+        project0open_project_in_browser "$project"
+    else
+        notify-send "(neorg/dmenu) No project selected"
+        exit 1
+    fi
+}
diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_start.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_start.sh
new file mode 100755
index 00000000..2423dd44
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_start.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env dash
+
+fstart0start_new_task() {
+    task_id="$1"
+    fstop0stop_current_task
+    task start "$task_id"
+}
diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_stop.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_stop.sh
new file mode 100755
index 00000000..e4ff0b94
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/f_stop.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env dash
+
+fstop0stop_current_task() {
+    # we ensured that only one task may be active
+    active="$(task +ACTIVE _ids)"
+    [ "$active" ] && task stop "$active"
+}
diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/list.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/list.sh
new file mode 100755
index 00000000..10659457
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/list.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env dash
+
+list0list_all_contexts_newline() {
+    print "%ALL_PROJECTS_NEWLINE"
+}
+list0list_all_contexts_comma() {
+    print "%ALL_PROJECTS_COMMA"
+}
diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/project.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/project.sh
new file mode 100755
index 00000000..64591850
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/project.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env dash
+
+project0open_current_context_in_browser() {
+    current_context="$(utils0get_current_context)"
+    [ "$current_context" ] || die "No current context to use"
+    project0open_context_in_browser "$(utils0context2project "$current_context")"
+}
+
+project0open_project_in_browser() {
+    project="$1"
+    [ "$project" ] || die "BUG: No context supplied to project0open_context_in_browser"
+
+    old_context="$(utils0get_current_context)"
+    # We have ensured that only one task may be active
+    old_started_task="$(task +ACTIVE _ids)"
+
+    tracking="$(mktmp)"
+    task "project:$project" _ids | xargs --no-run-if-empty task _zshids >"$tracking"
+    task context "$(utils0project2context "$project")"
+
+    while read -r description; do
+        desc="$(echo "$description" | awk -F: '{print $2}')"
+        if [ "$desc" = "tracking" ]; then
+            task_id="$(echo "$description" | awk -F: '{print $1}')"
+            notify-send "(Neorg)" "Starting task $project -> $desc"
+            task start "$task_id"
+            break
+        fi
+    done <"$tracking"
+
+    firefox -P "$project"
+
+    task stop "$task_id"
+    [ "$old_started_task" ] && task start "$old_started_task"
+
+    if [ "$old_context" ]; then
+        task context "$old_context"
+    else
+        task context none
+    fi
+}
diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/review.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/review.sh
new file mode 100755
index 00000000..a0a9ab8d
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/review.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env dash
+
+review0start() {
+    for project in $(list0list_all_contexts_newline); do
+        if [ -f "%NEORG_REVIEW_PATH/$project.lock" ]; then
+            msg "Reviewing '$project'"
+            notify-send "Neorg" "Reviewing '$project'"
+            firefox -P "$project"
+            rm "%NEORG_REVIEW_PATH/$project.lock"
+        fi
+    done
+}
diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/utils.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/utils.sh
new file mode 100755
index 00000000..c3843e8e
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/utils.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env dash
+
+# Runs it's first argument and then the second, regardless if the first failed or
+# succeeded
+utils0chain() {
+    eval "$1"
+    eval "$2"
+}
+
+utils0get_current_context() {
+    current_context="$(task _get rc.context)"
+    printf "%s\n" "$current_context"
+}
+
+utils0get_current_context_path() {
+    current_context="$1"
+    context_path="$(task _get rc.context."$current_context".rc.neorg_path 2>/dev/null)"
+    if ! [ "$context_path" ]; then
+        context_path="$(grep "context.$current_context.rc.neorg_path" "%HOME_TASKRC" | awk 'BEGIN {FS="="} {print $2}')"
+        [ "$context_path" ] || die "All contexts should have a 'neorg_path' set!"
+    fi
+    printf "%s\n" "$context_path"
+}
+
+utils0get_neorg_project_dir() {
+    # Perform shell expansion of Tilde
+    neorg_project_dir="$(sed "s|^~|$HOME|" "$(ptmp "%DEFAULT_NEORG_PROJECT_DIR")")"
+    printf "%s\n" "$neorg_project_dir"
+}
+
+utils0project2context() {
+    project="$1"
+    context="$(sed 's|\.|_|g' "$(ptmp "$project")")"
+    printf "%s\n" "$context"
+}
+utils0context2project() {
+    context="$1"
+    project="$(sed 's|_|\.|g' "$(ptmp "$context")")"
+    printf "%s\n" "$project"
+}
diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/functions/workspace.sh b/pkgs/sources/scripts/source/specific/neorg/sh/functions/workspace.sh
new file mode 100755
index 00000000..d5eb2fca
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/sh/functions/workspace.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env dash
+
+workspace0open_neorg_workspace() {
+    workspace="$1"
+    nvim -c "NeorgStart" -s "$(ptmp ":Neorg workspace $workspace\n")"
+}
+workspace0open_neorg_workspace_prompt() {
+    nvim -c "NeorgStart" -s "$(ptmp ":Neorg workspace ")"
+}
diff --git a/pkgs/sources/scripts/source/specific/neorg/sh/main.sh b/pkgs/sources/scripts/source/specific/neorg/sh/main.sh
new file mode 100755
index 00000000..559351b9
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/neorg/sh/main.sh
@@ -0,0 +1,164 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+# load dependencies
+. ./functions/add.sh
+. ./functions/context.sh
+. ./functions/dmenu.sh
+. ./functions/f_start.sh
+. ./functions/f_stop.sh
+. ./functions/list.sh
+. ./functions/project.sh
+. ./functions/utils.sh
+. ./functions/workspace.sh
+. ./functions/review.sh
+
+# these are used in version()
+# shellcheck disable=2034
+AUTHORS="Soispha"
+# shellcheck disable=2034
+YEARS="2023"
+
+NAME="neorg"
+
+help() {
+    cat <<EOF
+This is the core interface to the system-integrated task management
+
+USAGE:
+    $NAME [OPTIONS] [COMMAND]
+
+OPTIONS:
+    --help      | -h
+                            Display this help and exit.
+
+    --version   | -v
+                            Display version and copyright information and exit.
+COMMANDS:
+    task [ID]
+                            Open the neorg context associated with the current context and
+                            the uuid of the task with id ID. Without ID, it'll open the
+                            current context's norg file.
+                            If no context is set, drops you to the selection prompt
+
+    dmenu
+                            Select a project in dmenu mode. This will give you all projects
+                            and exectute the selected one as in 'neorg projects <selected>'
+
+    workspace [WS]
+                            The neorg workspace (WS) to open at startup, an empty value drops
+                            you at a prompt to enter the workspace yourself.
+
+    project [P]
+                            Opens the webbrowser with either the context (P) or
+                            the current active context as argument if no context is supplied
+
+    list
+                            Lists all available contexts
+
+    add
+                            Allows you to quickly add projects
+
+    fstart ID
+                            Starts the task (ID) but only after it stooped
+                            the previous active task, if it existed.
+
+    fstop
+                            Stops the current active task
+
+    review
+                            Review all firefox tabs
+ARGUMENTS:
+    ID | *([0-9]) := [[%ID_GENERATION_FUNCTION]]
+                            The function displays all possible IDs of the eligable tasks.
+
+    WS := %ALL_WORKSPACES
+                            All possible workspaces
+
+    P := %ALL_PROJECTS_PIPE
+                            The possible project
+
+EOF
+}
+
+for arg in "$@"; do
+    case "$arg" in
+    "--help" | "-h")
+        help
+        exit 0
+        ;;
+    "--version" | "-v")
+        version
+        exit 0
+        ;;
+    esac
+done
+
+while [ "$#" -ne 0 ]; do
+    case "$1" in
+    "t"*) # task
+        shift 1
+        task_id="$1"
+        [ "$task_id" ] || utils0chain context0open_current_task_context "exit 0"
+        context0open_current_task_context_at_task_id "$task_id"
+        exit 0
+        ;;
+    "w"*) # workspace
+        shift 1
+        workspace_to_open="$1"
+        # TODO: Exit with 1 on error, instead of the 0 <2023-10-20>
+        [ "$workspace_to_open" ] || utils0chain workspace0open_neorg_workspace_prompt "exit 0"
+        workspace0open_neorg_workspace "$workspace_to_open"
+        exit 0
+        ;;
+    "p"*) # project
+        shift 1
+        project_to_open="$1"
+        # TODO: Exit with 1 on error, instead of the 0 <2023-10-20>
+        [ "$project_to_open" ] || utils0chain project0open_current_context_in_browser "exit 0"
+        if ! grep -q "$project_to_open" "$(ptmp "%ALL_PROJECTS_NEWLINE")"; then
+            die "Your project ('$project_to_open') is not in the list of available projects:
+%ALL_PROJECTS_COMMA"
+        fi
+        project0open_project_in_browser "$project_to_open"
+        exit 0
+        ;;
+    "l"*) # list
+        list0list_all_contexts_newline
+        exit 0
+        ;;
+    "a"*) # add-project
+        add0open_taskwarrior_project_file
+        exit 0
+        ;;
+    "d"*) # dmenu
+        dmenu0open_context_in_browser
+        exit 0
+        ;;
+    "fsta"*) # fstart
+        shift 1
+        task_id="$1"
+        [ "$task_id" ] || die "No task id provided to fstart"
+        fstart0start_new_task "$task_id"
+        exit 0
+        ;;
+    "fsto"*) # fstop
+        fstop0stop_current_task
+        exit 0
+        ;;
+    "r"*) # review
+        shift 1
+        review0start
+        exit 0
+        ;;
+    *)
+        die "Command '$1' does not exist! Please look at:\n $NAME --help"
+        exit 0
+        ;;
+    esac
+done
+
+context0open_current_task_context
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/specific/spodi/sh/download.sh b/pkgs/sources/scripts/source/specific/spodi/sh/download.sh
new file mode 100755
index 00000000..fe9746c8
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/spodi/sh/download.sh
@@ -0,0 +1,58 @@
+#!/usr/bin/env dash
+
+download_to_down() {
+    DOWNLOAD_DIRECTORY="%XDG_MUSIC_DIR/down/spotify"
+
+    already_downloaded_files="$(mktmp)"
+    fd . "$DOWNLOAD_DIRECTORY" --exclude spotdl.log --exclude spotdl-errors.log >"$already_downloaded_files"
+    if [ -z "$NO_CHECK" ] && [ "$(wc -l <"$already_downloaded_files")" -ne 0 ]; then
+        die "something is already downloaded"
+    fi
+    # [ -e "$DOWNLOAD_DIRECTORY/spotdl.log" ] && rm "$DOWNLOAD_DIRECTORY/spotdl.log"
+
+    download "$1" "$DOWNLOAD_DIRECTORY"
+}
+
+download() {
+    download_url="$1"
+    output_path="$2"
+
+    config="$(mktmp)"
+    cat <<EOF | clean >"$config"
+# Main options
+--audio slider-kz bandcamp youtube-music piped youtube soundcloud
+--lyrics genius musixmatch azlyrics synced
+
+# FFmpeg options
+--ffmpeg ffmpeg
+--threads 16
+--bitrate 256k
+
+# Spotify options
+--cache-path %XDG_CACHE_HOME/spotdl/.spotipy
+
+# Output options
+--preload
+--format opus
+--output {artists}_-_{title}
+--print-errors
+--save-errors $output_path/spotdl-errors.log
+# TODO: Reactive whence spotdl support for these has improved <2023-12-19>
+# --generate-lrc
+--overwrite skip
+
+# Misc options
+--log-level INFO
+EOF
+
+    cd "$output_path" || die "BUG: no $output_path"
+    touch "$output_path/spotdl-errors.log"
+
+    # The sub shell needs to be unquoted, as the arguments may not be treated as one.
+    # shellcheck disable=2046
+    unbuffer spotdl $(cat "$config") download "$download_url" | tee "$output_path/spotdl.log"
+
+    [ -d ~/.spotdl ] && rm -r ~/.spotdl
+}
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/specific/spodi/sh/update.sh b/pkgs/sources/scripts/source/specific/spodi/sh/update.sh
new file mode 100755
index 00000000..a289cf58
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/spodi/sh/update.sh
@@ -0,0 +1,52 @@
+#!/usr/bin/env dash
+
+update() {
+    UPDATE_DIRECTORY="%XDG_MUSIC_DIR/artists"
+    UPDATE_CONFIG_FILE="%XDG_MUSIC_DIR/artists/update.conf"
+
+    if ! [ -f "$UPDATE_CONFIG_FILE" ]; then
+        error="$(
+            cat <<EOF
+Please provide an update config file at: '$UPDATE_CONFIG_FILE'.
+
+The 'update.conf' file should follow this pattern:
+<path_to_artist>/<artist_name>|<spotify_url>
+
+All comments and empty lines are ignored
+EOF
+        )"
+        die "$error"
+    fi
+
+    config_file="$(mktmp)"
+    clean "$UPDATE_CONFIG_FILE" >"$config_file"
+
+    while IFS="|" read -r artist url; do
+        full_artist="$UPDATE_DIRECTORY/$artist"
+        [ -d "$full_artist" ] || mkdir --parents "$full_artist"
+        [ -d "$full_artist/update" ] || mkdir --parents "$full_artist/update"
+        [ -d "$full_artist/all" ] || mkdir --parents "$full_artist/all"
+        [ -d "$full_artist/filtered" ] || mkdir --parents "$full_artist/filtered"
+
+        while read -r file; do
+            ln --symbolic --relative "$file" "$full_artist/update/$(basename "$file")"
+        done <"$(tmp fd --type file --extension opus . "$full_artist/all")"
+
+        msg2 "Updating $artist with url: '$url'"
+        download "$url" "$full_artist/update"
+
+        while read -r file; do
+            mv "$file" "$full_artist/all"
+            ln --symbolic --relative "$full_artist/all/$(basename "$file")" "$full_artist/filtered/$(basename "$file")"
+        done <"$(tmp fd --type file --extension opus . "$full_artist/update")"
+
+        while read -r file; do
+            rm "$file"
+        done <"$(tmp fd --type symlink --extension opus . "$full_artist/update")"
+
+        cp "$full_artist/update/spotdl.log" "$full_artist/all/spotdl.$(date +%Y_%m_%d).log"
+        cp "$full_artist/update/spotdl-errors.log" "$full_artist/all/spotdl-errors.$(date +%Y_%m_%d).log"
+    done <"$config_file"
+}
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/specific/spodi/spodi.sh b/pkgs/sources/scripts/source/specific/spodi/spodi.sh
new file mode 100755
index 00000000..475fd48a
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/spodi/spodi.sh
@@ -0,0 +1,71 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+# these are used in version()
+# shellcheck disable=2034
+AUTHORS="Soispha"
+# shellcheck disable=2034
+YEARS="2023"
+
+# load dependencies
+. ./sh/update.sh
+. ./sh/download.sh
+
+help() {
+    cat <<EOF
+This is a small wrapper around downloading things from spotify
+
+USAGE:
+    $NAME [OPTIONS] COMMAND
+
+OPTIONS:
+    --help      | -h
+                            Display this help and exit.
+
+    --version   | -v
+                            Display version and copyright information and exit.
+COMMANDS:
+    update
+                            Read the artist.conf file and download all newly released things
+
+    download URL
+                            Download a specific url to the DOWNLOAD_DIRECTORY
+EOF
+}
+
+for arg in "$@"; do
+    case "$arg" in
+    "--help" | "-h")
+        help
+        exit 0
+        ;;
+    "--version" | "-v")
+        version
+        exit 0
+        ;;
+    esac
+done
+
+case "$1" in
+"update")
+    shift 1
+    update
+    exit 0
+    ;;
+"download")
+    shift 1
+    download_url="$1"
+    [ -z "$download_url" ] && die "You need to provide a download url"
+    download_to_down "$download_url"
+    exit 0
+    ;;
+*)
+    die "Command '$1' is not know"
+    help
+    exit 1
+    ;;
+esac
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/specific/ytcc/description.sh b/pkgs/sources/scripts/source/specific/ytcc/description.sh
new file mode 100755
index 00000000..ae9107b9
--- /dev/null
+++ b/pkgs/sources/scripts/source/specific/ytcc/description.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+jq --raw-output '.description' "$XDG_RUNTIME_DIR/ytcc/running" | fmt -u -s | less
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/battery.sh b/pkgs/sources/scripts/source/wrappers/battery.sh
new file mode 100755
index 00000000..e650ba5d
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/battery.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+capacity="$(cat /sys/class/power_supply/BAT0/capacity)"
+status="$(cat /sys/class/power_supply/BAT0/status)"
+
+printf "%s%% (%s)\n" "$capacity" "$status"
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/hibernate.sh b/pkgs/sources/scripts/source/wrappers/hibernate.sh
new file mode 100755
index 00000000..30868fd1
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/hibernate.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+context="$(task _get rc.context)"
+[ "$context" ] && task context none
+
+# We have ensured that only one task is active
+active="$(task +ACTIVE _ids)"
+[ "$active" ] && task stop "$active"
+
+systemctl hibernate "$@"
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/ll.sh b/pkgs/sources/scripts/source/wrappers/ll.sh
new file mode 100755
index 00000000..f689ba44
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/ll.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+last_directory="$(mktemp)"
+
+command lf -last-dir-path="$last_directory" "$@"
+
+dir="$(cat "$last_directory")"
+cd "$dir" || die "$dir does not exist!"
+rm "$last_directory"
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/lock.sh b/pkgs/sources/scripts/source/wrappers/lock.sh
new file mode 100755
index 00000000..3101ef9a
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/lock.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+context="$(task _get rc.context)"
+[ "$context" ] && task context none
+
+# We have ensured that only one task is active
+active="$(task +ACTIVE _ids)"
+[ "$active" ] && task stop "$active"
+
+swaylock
+
+[ "$active" ] && task start "$active"
+
+[ "$context" ] && task context "$context"
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/lyrics.sh b/pkgs/sources/scripts/source/wrappers/lyrics.sh
new file mode 100755
index 00000000..02a147c8
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/lyrics.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+(
+    cd "$XDG_MUSIC_DIR" || die "No music dir!"
+    exiftool "$(mpc --format '%file%' current)" -json | jq '.[0].Lyrics' -r | less
+)
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/mpc-fav.sh b/pkgs/sources/scripts/source/wrappers/mpc-fav.sh
new file mode 100755
index 00000000..795a4875
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/mpc-fav.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+FAV_DIR="$XDG_MUSIC_DIR/playlists/favourites"
+
+cd "$XDG_MUSIC_DIR" || die "No music dir!"
+
+[ -d "$FAV_DIR" ] || mkdir --parents "$FAV_DIR"
+
+ln -sr "$(mpc --format '%file%' current)" "$FAV_DIR/" || die "Link failed!"
+
+mpc update
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/mpc-rm.sh b/pkgs/sources/scripts/source/wrappers/mpc-rm.sh
new file mode 100755
index 00000000..94e0634b
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/mpc-rm.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+cd "$XDG_MUSIC_DIR" || die "No music dir!"
+trash-put "$(mpc --format '%file%' current)"
+mpc del 0
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/mpc.sh b/pkgs/sources/scripts/source/wrappers/mpc.sh
new file mode 100755
index 00000000..5aae5cdb
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/mpc.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+case "$1" in
+"rm")
+    shift 1
+    mpc-rm "$@"
+    ;;
+"fav")
+    shift 1
+    mpc-fav "$@"
+    ;;
+*)
+    mpc "$@"
+    ;;
+esac
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/show.sh b/pkgs/sources/scripts/source/wrappers/show.sh
new file mode 100755
index 00000000..ae2bdb13
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/show.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+# Maybe add `--quit-if-one-screen`
+less --redraw-on-quit "$@"
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/sort_song.sh b/pkgs/sources/scripts/source/wrappers/sort_song.sh
new file mode 100755
index 00000000..e2978507
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/sort_song.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+case "$("$1" | tr '[:upper:]' '[:lower:]')" in
+"lyrics")
+    filter="LYRICS"
+    directory="lyrics"
+    ;;
+"instrumental")
+    filter="INSTRUMENTAL"
+    directory="instrumental"
+    ;;
+*)
+    die "Expected 'instrumental|lyrics' but got '$1'"
+    ;;
+esac
+
+process() {
+    mediainfo --Output=JSON "$1" | jq '.media.track | map(.Lyrics) | join("")'
+}
+
+mkdir "../$directory"
+
+fd . --extension=opus | while read -r file; do
+    if [ "$(process "$file")" = '""' ] || [ "$(process "$file")" = '"Instrumental"' ] || [ "$(process "$file")" = '"instrumental"' ]; then
+        echo "INSTRUMENTAL::$file"
+    else
+        echo "LYRICS::$file"
+    fi
+done | grep "$filter" | awk 'BEGIN {FS="::"}{print $2}' | while read -r file; do ln -s "../all/$file" "../$directory/$file"; done
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/virsh-del.sh b/pkgs/sources/scripts/source/wrappers/virsh-del.sh
new file mode 100755
index 00000000..c3de5484
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/virsh-del.sh
@@ -0,0 +1,10 @@
+#! /usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+virsh destroy "$1"
+virsh undefine "$1" --nvram
+virsh vol-delete --pool default "$1".qcow2
+
+# vim: ft=sh
diff --git a/pkgs/sources/scripts/source/wrappers/yti.sh b/pkgs/sources/scripts/source/wrappers/yti.sh
new file mode 100755
index 00000000..a69ffa74
--- /dev/null
+++ b/pkgs/sources/scripts/source/wrappers/yti.sh
@@ -0,0 +1,33 @@
+#! /usr/bin/env dash
+
+# shellcheck source=/dev/null
+SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
+
+DOWN_DIR=/home/soispha/media/music/down/youtube
+
+tmp=$(mktmp)
+config=$(mktmp)
+
+for e in "$DOWN_DIR"/*.opus; do echo "$e" >>"$tmp"; done
+[ "$(wc -l "$tmp" | awk '{print $1}')" -gt 2 ] && die "something is already downloaded"
+
+cat <<EO >"$config"
+--paths home:"$DOWN_DIR"
+#--output %(fulltitle)
+--restrict-filenames
+--no-overwrites
+--no-write-info-json
+--clean-info-json
+--prefer-free-formats
+#--format mp3
+--extract-audio
+--audio-quality 0
+--audio-format best
+EO
+
+rm "$DOWN_DIR/yt-dlp.log"
+cd "$DOWN_DIR" || die "BUG: no $DOWN_DIR"
+
+unbuffer yt-dlp --config-location "$config" "$1" | tee "$DOWN_DIR/yt-dlp.log"
+
+# vim: ft=sh