{
  pkgs,
  lib,
  config,
  nixosConfig,
  ...
}:
with pkgs; let
  onlyShare = drv:
    runCommand "${drv.name}-only-share" {} ''
      mkdir -p $out
      ln -s ${drv}/share $out/share
    '';
  mpc-cli-man = onlyShare mpc-cli;

  Gui = {
    Terminals = [
      # foot # wayland native terminal
      alacritty # default terminal
    ];
    Browsers = [
      #ungoogled-chromium # web browser (only for web programming)
      #brave
    ];

    ImageManipulation = [
      #krita # new, and better (KDE)
      #gimp # conservative, and old (GNOME)
    ];

    Social = [
      mumble # voice chat software (client)
      # lutris # multiple game store clients

      # nheko # best matrix client (as of today)
      # element-desktop  # nheko didn't work
      signal-desktop # to avoid encryption problems with signal-bridge
    ];

    Misc = [
      #kalzium # Periodic Table of Elements (`element` is [sort of] better)
      keepassxc # password manager
      #onlykey # OnlyKey Chrome Desktop App
      anki-bin # spaced repetition
    ];
  };

  TuiCli = {
    EyeCandy = [
      #banner # Print large banners to ASCII terminals
      cmatrix # A curses-based scrolling 'Matrix'-like screen
      hyfetch # Neofetch with LGBTQ pride flags.
    ];

    Social = [
      iamb # best tui matrix client (as of today)
    ];

    Pdfs = [
      con2pdf # Scanner implementation
    ];

    Misc = [
      android-file-transfer # Android MTP client with minimalistic UI
      #xdg-ninja # A shell script which checks your $HOME for unwanted files and directories.
      xdg-utils # open urls and such things
      yokadi # Command line oriented, sqlite powered, todo list
      killall # kill a application by name
      snap-sync-forked # A btrfs based backup solution
      bc # Smart calculator
      aumo # Automatic mount
      nato # Encodes a string in the standardized spelling alphabet
      virsh-del # Delete a libvirt virtual machine (not really used anymore).
      jq # Json parser
    ];

    Task = {
      StartStop = [
        hibernate # Hibernate wrapper that automatically stops all active task
        lock # Same as `hibernate`, but for locking
      ];

      Firefox = [
        # `neorg` handles the integration between Firefox profiles and task
        # contexts
        (neorg.override
          {
            defaultNeorgProjectDir = config.programs.nixvim.plugins.neorg.modules."core.dirman".config.workspaces.projects;
            allProjectsNewline = config.soispha.taskwarrior.projects.projects_newline;
            allProjectsComma = config.soispha.taskwarrior.projects.projects_comma;
            allProjectsPipe = config.soispha.taskwarrior.projects.projects_pipe;
            allWorkspaces = config.programs.nixvim.plugins.neorg.modules."core.dirman".config.workspaces;
            xdgConfigHome = config.xdg.configHome;
            xdgDataHome = config.xdg.dataHome;
          })
      ];
    };

    WM = {
      river = [river]; # A dynamic tiling wayland compositor

      CLITools = [
        lswt # List Wayland toplevels.
        wl-clipboard # Command-line copy/paste utilities.
        swaylock # My current lockscreen implementation.
      ];

      Media = [
        wf-recorder # Screen recorder.
        libnotify # a command to send a notification.
        screenshot_persistent # Creates a persisting screenshot.
        screenshot_temporary # Takes a screenshot and stores it in the clipboard.
      ];
    };

    Media = {
      View = [
        imv # Image viewer
        zathura # PDF viewer
      ];

      YouTube = [
        yti # Wrapper around `yt-dlp`.
        yt # A command line YouTube client
      ];

      Listen = [
        spodi # Wrapper around `spotdl`.
        ncmpc # mpd player client
        mpc-cli-man # a cli mpd client (added via a wrapper script)
        mpc # Wrapper around `mpc` that allows the usage of `mpc-{rm,lyrics,searchadd}` without the `-`
        # Removes the currently playing song from the disk and storage
        (mpc-beetrm.override {
          beets = config.programs.beets.package;
        })
        # Works like normal `mpc searchadd` but uses the `beets` query syntax
        (mpc-searchadd.override {
          beets = config.programs.beets.package;
        })
        # Displays the lyrics of the currently playing song
        (mpc-lyrics.override {
          mpd_music_dir = config.services.mpd.musicDirectory;
        })
        sort_song # Sorts songs in the current directory.
      ];
    };

    Hardware = {
      Storage = [
        #compsize # Calculate compression ratio of a set of files on Btrfs
        # TODO: smartmontools # Control and monitor S.M.A.R.T. enabled ATA and SCSI Hard Drives
      ];

      Battery = [
        battery # Check the battery level
      ];

      # TODO: Also support setting the brightness with multiple backlights <2024-05-24>
      Backlight =
        lib.optional nixosConfig.soispha.laptop.enable
        (
          # Set the brightness level
          brightness.override
          {
            backlightName = nixosConfig.soispha.laptop.backlight;
          }
        );

      Input = [
        #piper # GTK application to configure gaming mice
      ];
    };

    SystemUpdate = [
      fupdate # Generic update tool.
      update-sys # System update tool (meant to slot into `fupdate`).
    ];

    FileListers = [
      tree # A directory listing program displaying a depth indented list of files
      fd # Simple, fast and user-friendly alternative to find
      ripgrep # A search tool that combines the usability of ag with the raw speed of grep
      fzf # used to quickly move around with its keybindings
      file # Show information about a file
      ll # Wrapper around `lf` to automatically change the path
      lm # Wrapper around `ll` to automatically cd to the last accessed path
      show # Wrapper around `less` to show a file (similar to the `cat <FILE>` pattern).
    ];

    Editors = [
      ed # A POSIX-compliant line-oriented text editor
      #sed # GNU stream editor
      vim # The original ex/vi text editor (this is `vim` and not `vi`, as `vi` is unfree)
      #neovim # Fork of Vim aiming to improve user experience, plugins, and GUIs
    ];

    Programming = {
      GeneralTools = [
        git # the fast distributed version control system
        git-absorb # git commit --fixup, but automatic
        git-edit-index # Allows you to edit the indexed version of a file
        git-cm # A wrapper that re-adds the last commit's subject
        git-cleanup # An automatic merged branch deleter
        glow # Command-line markdown renderer
      ];
    };
  };
  # TODO: unmaintained, find sth else:
  # handlr # Powerful alternative to xdg-utils written in Rust
  mapFun = x:
    if builtins.isAttrs x
    then
      if lib.isDerivation x
      then [x]
      else builtins.attrValues x
    else [x];
in {
  home.packages =
    []
    ++ (with builtins;
      concatLists
      (concatLists [
        (concatMap mapFun
          (concatMap mapFun
            (concatMap mapFun
              (concatMap mapFun
                (concatMap mapFun
                  (concatMap mapFun
                    (attrValues Gui)))))))

        (concatMap mapFun
          (concatMap mapFun
            (concatMap mapFun
              (concatMap mapFun
                (concatMap mapFun
                  (concatMap mapFun
                    (attrValues TuiCli)))))))
      ]));
}