diff --git a/README.md b/README.md
index c86639b1..82bb904e 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ This repository contains the definition of my machines using [nix](https://nixos
| `laptop` | AMD Ryzen™ 7 7840HS | 32GB | AMD Radeon™ 780M | NVIDIA® GeForce RTX™ 4060 8GB | ❄️ |
| `work-macos` | Apple M2 Pro 8-core CPU | 16GB | Apple M2 Pro 10-core GPU | | 🍏 |
-# Flake Outputs
+# 📦 Flake Outputs
Listing only the most relevant outputs. See the source-code for more details.
@@ -29,10 +29,11 @@ Listing only the most relevant outputs. See the source-code for more details.
- `fzf-rg`: [`fzf`](https://github.com/junegunn/fzf) + [`ripgrep`](https://github.com/BurntSushi/ripgrep). Includes `fish` widget.
- `fzf-fd`: [`fzf`](https://github.com/junegunn/fzf) + [`fd`](https://github.com/sharkdp/fd). Includes `fish` widget.
- `preview`: Custom _barebones_ terminal file previewer to together with the other widgets. I really like [`yazi`](https://yazi-rs.github.io/) previewer but can't use it in isolation.
+- `dunst-volume`: Custom wrapper to send notifications whenever I set the volume.
Tryout using:
```shell
-nix run github:bphenriques/dotfiles#{package}
+nix run github:bphenriques/dotfiles#{package} -- {args}
```
### [Home Manager](https://github.com/nix-community/home-manager) modules
diff --git a/config/home-manager/coding/default.nix b/config/home-manager/coding/default.nix
deleted file mode 100644
index a39cc534..00000000
--- a/config/home-manager/coding/default.nix
+++ /dev/null
@@ -1,35 +0,0 @@
-{ lib, pkgs, config, network-devices, ... }:
-let
- mkSSHMatchBlock = deviceCfg: {
- inherit (deviceCfg) hostname;
- inherit (deviceCfg.ssh) user port;
- };
-in
-{
- imports = [
- ./git.nix
- ./scala
- ./helix.nix
- ];
-
- programs.ssh = {
- enable = true;
- serverAliveInterval = 60;
- matchBlocks = {
- home-nas = mkSSHMatchBlock network-devices.home-nas;
- pi-zero = mkSSHMatchBlock network-devices.pi-zero;
- rg353m = mkSSHMatchBlock network-devices.rg353m;
- deck = mkSSHMatchBlock network-devices.deck;
- };
-
- extraConfig = ''
- Include ''${HOME}/.ssh/config.local
- '';
- };
-
- home.packages = with pkgs; [
- jetbrains.idea-community
- ] ++ lib.optionals (pkgs.stdenv.isLinux) [
- filezilla # Access remote files
- ];
-}
diff --git a/config/home-manager/coding/scala/ammonite-predef.sc b/config/home-manager/coding/scala/ammonite-predef.sc
deleted file mode 100644
index 98b1b836..00000000
--- a/config/home-manager/coding/scala/ammonite-predef.sc
+++ /dev/null
@@ -1,19 +0,0 @@
-object load {
- def fs2Version(version: String): Unit = {
- repl.load.apply(s"""
- import $$ivy.`co.fs2::fs2-core:$version`
- import $$ivy.`co.fs2::fs2-reactive-streams:$version`
- import $$ivy.`co.fs2::fs2-io:$version`
-
- import cats.syntax.all._
- import cats.effect.{IO, Resource}
- import fs2.io.file.{Files, Path}
- import fs2.{Stream, text}
-
- // For unsafeRunSync
- implicit val runtime = cats.effect.unsafe.IORuntime.global
- """)
- }
-
- def fs2: Unit = fs2Version("3.11.0")
-}
diff --git a/config/home-manager/default.nix b/config/home-manager/default.nix
deleted file mode 100644
index 05e819a1..00000000
--- a/config/home-manager/default.nix
+++ /dev/null
@@ -1,60 +0,0 @@
-{ pkgs, lib, config, ... }:
-{
- imports = [
- ./coding
- ./internet
- ./media
- ./terminal
- ./desktop
- ];
-
- # XDG Compliance to tidy up $HOME.
- xdg.enable = true;
- home.preferXdgDirectories = true;
-
- # Default apps and directories
- xdg.mimeApps.enable = pkgs.stdenv.isLinux;
-
- home.packages = with pkgs; [
- # Consistent UNIX command line tools regardless of the OS
- coreutils
- findutils
- gnugrep
- watch
- tree
- parallel
- gnused
- dateutils
- unzip
- xclip
-
- # Archive
- p7zip # 7zip for linux
- unrar # Still need it
- ] ++ lib.optionals pkgs.stdenv.isLinux [
- (nerdfonts.override { fonts = [ "Hack" "JetBrainsMono" ]; })
- baobab # Visual disk space analyzer
- ];
- fonts.fontconfig.enable = true;
-
- # Gpg
- programs.gpg.enable = pkgs.stdenv.isLinux;
- services.gpg-agent = {
- enable = pkgs.stdenv.isLinux;
- pinentryPackage = pkgs.pinentry-gnome3;
- };
-
- home.sessionVariables = {
- LANG = "en_US.UTF-8";
- LC_ALL = "en_US.UTF-8";
- };
-
- # Do not need the whole home-manager configuration reference.
- manual.manpages.enable = false;
-
- # Tighten permissions to private keys
- systemd.user.tmpfiles.rules = lib.optionals pkgs.stdenv.isLinux [
- "z ${config.home.homeDirectory}/.ssh 0700 ${config.home.username} users"
- "z ${config.home.homeDirectory}/.gnupg 0700 ${config.home.username} users"
- ];
-}
diff --git a/config/home-manager/desktop/default.nix b/config/home-manager/desktop/default.nix
deleted file mode 100644
index 7fd3e39d..00000000
--- a/config/home-manager/desktop/default.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-{ config, lib, pkgs, ... }:
-{
- imports = [ ./wofi.nix ];
-}
\ No newline at end of file
diff --git a/config/home-manager/desktop/wayland/README.md b/config/home-manager/desktop/wayland/README.md
deleted file mode 100644
index e1f3ca86..00000000
--- a/config/home-manager/desktop/wayland/README.md
+++ /dev/null
@@ -1,65 +0,0 @@
-# THIS LOOKS REALLY GOOD
-https://github.com/shazow/nixfiles/blob/main/home/common/wayland.nix
-https://github.com/Misterio77/nix-config/blob/main/home/gabriel/features/desktop/common/wayland-wm/default.nix
-https://github.com/bashfulrobot/nixos/blob/main/modules/desktops/addons/wayland/default.nix
-
-
-
-https://github.com/bbigras/nix-config/tree/master/users/bbigras/graphical/sway
-https://github.com/bbigras/nix-config/blob/master/users/bbigras/graphical/common.nix
-https://codeberg.org/adamcstephens/dotfiles/src/branch/main/apps/waybar
-https://codeberg.org/adamcstephens/dotfiles/src/branch/main/apps/waylock/waylock.toml
-
-https://github.com/iynaix/dotfiles/tree/f0f8918caed8f4c245fa82fc505ae0de09a32f5c/home-manager/hyprland
-# https://github.com/edmundmiller/dotfiles/blob/main/modules/desktop/apps/rofi.nix
-https://github.com/Misterio77/nix-config/blob/cdc35ca281891268c6e9772cca1e66fb39de04ab/home/misterio/features/desktop/hyprland/default.nix
-https://github.com/prescientmoon/everything-nix/tree/develop/home/features/wayland
-https://gitlab.com/usmcamp0811/dotfiles/-/blob/nixos/modules/nixos/desktop/hyperland/default.nix?ref_type=heads
-https://codeberg.org/adamcstephens/dotfiles/src/branch/main/apps/waybar
-https://codeberg.org/adamcstephens/dotfiles/src/branch/main/apps/wofi
-https://codeberg.org/adamcstephens/dotfiles/src/branch/main/bin
-# File browser: https://github.com/iynaix/dotfiles/blob/e441ab4ff7a775b57b6c79a2fa6be99e3ab2d58b/home-manager/programs/nemo.nix#L79
-https://github.com/0xcharly/nix-config/blob/a8e1427a67494ad5de3d639d94ee619ca69f51c7/users/delay/wayland.nix
-
-
-
-https://github.com/namishh/crystal/blob/main/home/namish/conf/ui/hyprland/default.nix
-https://github.com/yusdacra/ark/blob/e49b560d6b1f2612ed27070b49d8a43d038532c4/users/modules/dunst/default.nix
-https://github.com/Mbhon1/Osama-Flake/blob/0b58a55a38d186b13cddfdda7f73ad23a48214d8/hyprland/default.nix
-https://github.com/shazow/nixfiles/blob/main/common/desktop-wayland.nix#L21
-
-
-
-https://github.com/Mic92/dotfiles/blob/main/home-manager/modules/waybar.nix
-
-
- Notification daemon? https://github.com/fufexan/dotfiles/blob/main/home/services/system/dunst.nix#L7
- More misc: https://github.com/fufexan/dotfiles/blob/main/home/services/wayland/swayidle.nix
- Too many things: https://github.com/bashfulrobot/nixos/tree/main/home/modules/wayland
- https://github.com/NickCao/flakes/blob/d99c0a28b9357adce9749ca49364038184a1b95e/nixos/mainframe/home.nix#L22
-
-
- https://github.com/fufexan/dotfiles/tree/main/home/programs/wayland
- Notification daemon? https://github.com/fufexan/dotfiles/blob/main/home/services/system/dunst.nix#L7
- More misc: https://github.com/fufexan/dotfiles/blob/main/home/services/wayland/swayidle.nix
- Too many things: https://github.com/bashfulrobot/nixos/tree/main/home/modules/wayland
- https://github.com/NickCao/flakes/blob/d99c0a28b9357adce9749ca49364038184a1b95e/nixos/mainframe/home.nix#L22
-
-Waybar
-https://github.com/NickCao/flakes/blob/d99c0a28b9357adce9749ca49364038184a1b95e/nixos/mainframe/waybar.nix
-https://github.com/NickCao/flakes/blob/d99c0a28b9357adce9749ca49364038184a1b95e/nixos/mainframe/waybar.css
-
-
-
-https://github.com/fufexan/dotfiles/tree/main/home/programs/wayland
-
-Sway
-https://github.com/NickCao/flakes/blob/d99c0a28b9357adce9749ca49364038184a1b95e/nixos/mainframe/home.nix#L22
-
-
-Wofi:
-# https://github.com/shazow/nixfiles/blob/main/home/bin/volumectl
-# https://github.com/mitchellh/nixos-config/blob/main/users/mitchellh/rofi
-
-
-https://github.com/wochap/nix-config/blob/main/hosts/glegion/hardware.nix#L65
\ No newline at end of file
diff --git a/config/home-manager/desktop/wofi.nix b/config/home-manager/desktop/wofi.nix
deleted file mode 100644
index 25a6e2af..00000000
--- a/config/home-manager/desktop/wofi.nix
+++ /dev/null
@@ -1,72 +0,0 @@
-{ config, lib, pkgs, ... }:
-let
- font = {
- variable = "Hack Nerd Font Mono";
- };
- colorScheme = {
- palette = {
- base00 = "#000000";
- base01 = "#100323";
- base02 = "#3C3C3C";
- base03 = "#595959";
- base04 = "#BEBCBF";
- base05 = "#FFFFFF";
- base06 = "#EDEAEF";
- base07 = "#FFFFFF";
- base08 = "#FF8059";
- base09 = "#EF8B50";
- base0A = "#D0BC00";
- base0B = "#44BC44";
- base0C = "#00D3D0";
- base0D = "#2FAFFF";
- base0E = "#FEACD0";
- base0F = "#B6A0FF";
- };
- };
-in
-{
- programs.wofi = {
- enable = pkgs.stdenv.isLinux;
- settings = {
- width = 800;
- height = 400;
- insensitive = true;
- mode = "drun,run";
- };
-
- style = ''
- window {
- border: 2px solid #${colorScheme.palette.base03};
- background-color: #${colorScheme.palette.base00};
- }
-
- #input {
- color: #${colorScheme.palette.base09};
- border: 2px solid #${colorScheme.palette.base03};
- background-color: #${colorScheme.palette.base00};
- font-size: 13px;
- font-family: ${font.variable};
- }
-
- #outer-box {
- margin: 10px;
- }
-
- #scroll {
- margin: 5px 0px;
- font-size: 13px;
- font-family: ${font.variable};
- color: #${colorScheme.palette.base06};
- }
-
- #scroll label {
- margin: 2px 0px;
- }
-
- #entry:selected {
- color: #${colorScheme.palette.base06};
- background-color: #${colorScheme.palette.base00};
- }
- '';
- };
-}
diff --git a/config/home-manager/internet/default.nix b/config/home-manager/internet/default.nix
deleted file mode 100644
index a8df1d10..00000000
--- a/config/home-manager/internet/default.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-{ config, pkgs, lib, ... }:
-{
- imports = [
- ./firefox
- ];
-
- home.packages = with pkgs; lib.optionals (pkgs.stdenv.isLinux) [
- qbittorrent # Torrent client
- filezilla # Access files remotely
- newsflash # RSS Reader
- vesktop # Lightweight discord
- ];
-
- xdg.mimeApps.defaultApplications."x-scheme-handler/discord" = [ "vesktop.desktop" ];
-}
\ No newline at end of file
diff --git a/config/home-manager/media/default.nix b/config/home-manager/media/default.nix
deleted file mode 100644
index 1df7d56f..00000000
--- a/config/home-manager/media/default.nix
+++ /dev/null
@@ -1,12 +0,0 @@
-{ lib, ... }: {
- imports = [
- ./notes
- ./music.nix
- ./image.nix
- ./video.nix
- ./documents.nix
- ];
-
- custom.xdgDefaultApps.archive = lib.mkBefore [ "org.kde.ark.desktop" ];
- custom.xdgDefaultApps.fileBrowser = lib.mkBefore [ "org.kde.dolphin.desktop" "org.gnome.baobab.desktop" "yazi.desktop" ];
-}
diff --git a/config/home-manager/media/image.nix b/config/home-manager/media/image.nix
deleted file mode 100644
index 440b0ee8..00000000
--- a/config/home-manager/media/image.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-{ pkgs, lib, config, ... }:
-{
- home.packages = with pkgs; [
- exiftool
- ];
-
- programs.imv.enable = pkgs.stdenv.isLinux;
- home.shellAliases = lib.optionalAttrs (pkgs.stdenv.isLinux) {
- "webp_to_png" = ''nix-shell -p libwebp -p parallel --command "parallel dwebp {} -o {.}.png ::: *.webp"'';
- };
-
- custom.xdgDefaultApps.image = lib.mkBefore [ "imv.desktop" ];
-}
diff --git a/config/home-manager/media/music.nix b/config/home-manager/media/music.nix
deleted file mode 100644
index fe3bbb86..00000000
--- a/config/home-manager/media/music.nix
+++ /dev/null
@@ -1,85 +0,0 @@
-{ pkgs, lib, config, ... }:
-let
- inherit (lib) foldl';
-
- musicLibrary = "${config.xdg.userDirs.music}/library";
- playlistsDirectory = "${config.xdg.userDirs.music}/playlists";
-
- # Beets require absolute paths: https://github.com/beetbox/beets/issues/133
- # If needed:
- # 1. Find the base path in the db: beet list -f '$path' artist:beatles | head -n 1
- # 2. Manualyl update the databaseL
- # sqlite3 $XDG_DATA_HOME/beets/library.db "UPDATE items SET path = replace(path, '/home/bphenriques/Music/Library', '/home/bphenriques/music/library');"
- # sqlite3 $XDG_DATA_HOME/beets/library.db "UPDATE albums SET artpath = replace(artpath, '/home/bphenriques/Music/Library', '/home/bphenriques/music/library');"
- #
- # 3. Confirm if everything is alright. The following command should not hint that files should be deleted.
- # beets update -p
- beets = {
- database = "${config.xdg.dataHome}/beets/library.db";
- databaseBackup = "${config.xdg.userDirs.music}/beets.db.backup";
-
- # Healthcheck: beet bad && beet duplicates
- # Update files: beet fetchart && beet fingerprint && beet embedart && beet scrub
- # Docs: https://beets.readthedocs.io/en/stable/plugins/index.html
- plugins = let
- providers = [ "chroma" "spotify" "deezer" ];
- metadata = [ "fetchart" "embedart" "lyrics" "mbsync" ]; # lastgenre
- health = [ "duplicates" "badfiles" ];
- utility = [ "edit" "playlist" "scrub" "fish" ]; # https://beets.readthedocs.io/en/stable/plugins/smartplaylist.html
- in (providers ++ health ++ metadata ++ utility);
- basePackage = pkgs.beets-unstable.override {
- # Reference: https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/audio/beets/builtin-plugins.nix
- pluginOverrides = foldl' (acc: plugin: acc // { "${plugin}".enable = true; }) { } beets.plugins;
- };
-
- # Sanity check + backup database file to NAS. Can't store the DB file in the NAS as it leads to lock issues.
- finalPackage = (pkgs.writeScriptBin "beet" ''
- #!${pkgs.stdenv.shell}
- if [ ! -d "${musicLibrary}" ]; then
- echo "${musicLibrary} does not exist!"
- exit 1
- fi
-
- ${lib.getExe beets.basePackage} "$@"
- status=$?
- if [ $status -eq 0 ] && [ -f "${beets.database}" ] && ([ ! -f "${beets.databaseBackup}" ] || [[ "$(md5sum "${beets.databaseBackup}")" = "$(md5sum "${beets.database}")" ]]); then
- echo "Backing up beets library: ${beets.database}"
- cp -f "${beets.database}" "${beets.databaseBackup}"
- fi
- exit $status
- '');
- };
-in
-{
- home.packages = lib.optionals (pkgs.stdenv.isLinux) [
- pkgs.feishin # Jellyfin player
- pkgs.cmus # TUI based music player
- ];
-
- programs.beets = {
- enable = pkgs.stdenv.isLinux;
- package = beets.finalPackage;
- settings = {
- library = beets.database;
- directory = musicLibrary;
- paths = {
- default = "$albumartist/$album%aunique{}/$track $title";
- singleton = "$artist/Non-Album/$title";
- comp = "Compilations/$album%aunique{}/$track $title";
- };
- plugins = builtins.concatStringsSep " " beets.plugins;
- playlist = {
- auto = true; # Automatically remove/move items inside the playlists in case they move.
- relative_to = musicLibrary;
- playlist_dir = playlistsDirectory;
- };
- fetchart = {
- auto = true;
- cautious = true;
- };
- musicbrainz = {
- extra_tags = ["date" "year" "originalyear" "originalartist" "originalalbum" "artists"];
- };
- };
- };
-}
diff --git a/config/home-manager/media/notes/default.nix b/config/home-manager/media/notes/default.nix
deleted file mode 100644
index 7a9dbd03..00000000
--- a/config/home-manager/media/notes/default.nix
+++ /dev/null
@@ -1,4 +0,0 @@
-{ ... }:
-{
- imports = [ ./logseq ];
-}
\ No newline at end of file
diff --git a/config/home-manager/terminal/default.nix b/config/home-manager/terminal/default.nix
deleted file mode 100644
index 68142e28..00000000
--- a/config/home-manager/terminal/default.nix
+++ /dev/null
@@ -1,127 +0,0 @@
-{ pkgs, config, lib, self, ... }:
-{
- imports = [
- ./fish.nix
- ./ghostty.nix
- ./yazi.nix
- ];
-
- programs.bat.enable = true; # Better file previewer
- programs.fd.enable = true; # Better `find`.
- programs.jq.enable = true; # JSON query.
- programs.htop.enable = true; # Fancy `top`.
- programs.man.enable = true; # RTFM
- custom.programs.project.enable = true; # Easier way to navigate jump through different projects
- custom.programs.fzf-fd.enable = true; # Fuzzy fd
- custom.programs.fzf-rg.enable = true; # Fuzzy ripgrep
-
- programs.ripgrep = {
- enable = true;
- arguments = [
- "--max-columns=150"
- "--max-columns-preview"
- "--glob=!.git"
- "--smart-case"
- ];
- };
-
- programs.tealdeer = {
- enable = true;
- settings = {
- display = {
- compact = false;
- use_pager = true;
- };
-
- updates.auto_update = false;
- };
- };
-
- programs.zoxide = {
- enable = true;
- options = [ "--cmd j" ];
- };
-
- # Interesting for Android dev: https://git.belanyi.fr/ambroisie/nix-config/src/branch/main/modules/home/direnv/lib/android.sh
- programs.direnv = {
- enable = true; # Automatically load .envrc or .env.
- nix-direnv.enable = true; # Faster direnv for nix environments.
- silent = true; # Disable verbose messages when entering a directory.
- config.whitelist.prefix = [ config.custom.dotfiles.directory ]; # Surpress prompt in my private dotfiles
- };
-
- # Fuzzy matching
- programs.fzf = {
- enable = true;
- defaultCommand = "${lib.getExe pkgs.fd} --type file --hidden --exclude=.git";
- enableFishIntegration = true;
-
- defaultOptions = [
- "--height='80%'"
- "--marker='* '"
- "--pointer='▶'"
- "--preview-window='right:60%'"
- "--bind='ctrl-p:toggle-preview'"
- "--bind='alt-a:select-all'"
- "--bind='alt-n:deselect-all'"
- "--bind='ctrl-f:jump'"
- ];
- };
-
- home = {
- packages = with pkgs; [
- # Security
- openssl # Generate keys with openssl rand -hex 32
-
- # Text Processors
- yq-go # Query YAML.
- vim # Basic editor
-
- # Monitoring
- procs # Fancy `ps`.
- ];
-
- sessionVariables = {
- VISUAL = "$EDITOR"; # Set within the editor config.
- PAGER = "less -iMR";
-
- # Colors
- CLICOLOR = 1; # Enable ls colors in MacOS.
- LS_COLORS ="$(${pkgs.vivid}/bin/vivid generate snazzy)"; # LS_COLORS generator because I refuse to maintain one >.<
- } // (lib.optionalAttrs pkgs.config.allowUnfree {
- NIXPKGS_ALLOW_UNFREE = 1;
- });
-
- shellAliases = {
- # Default colorizatio
- diff = "diff --color=auto";
- grep = "grep --color=auto";
- egrep = "egrep --color=auto";
- fgrep = "fgrep --color=auto";
- ls = "ls --color=auto";
-
- # The usual aliases
- l = "ls -alh";
- ll = "ls -l";
-
- # Quality of life
- mkdir = "mkdir -pv";
- ".." = "cd ..";
- "..." = "cd ../..";
- ":q" = "exit";
- tmpdir = "cd (mktemp -d)";
-
- # Text Processor
- e = "$EDITOR";
-
- # Nix utility functions to set the SHELL automatically
- nix-shell = "nix-shell --run $SHELL";
- devshell = "nix develop --command $SHELL";
- whatsmyip = "${lib.getExe pkgs.curl} ifconfig.me";
- } // (lib.optionalAttrs pkgs.stdenv.isLinux {
- pbcopy = lib.getExe pkgs.xclip;
- pbpaste = "${lib.getExe pkgs.xclip} -o";
- }
- );
- };
-}
diff --git a/config/nixos/default.nix b/config/nixos/default.nix
deleted file mode 100644
index 61fa459a..00000000
--- a/config/nixos/default.nix
+++ /dev/null
@@ -1,97 +0,0 @@
-{ pkgs, lib, network-devices, ... }:
-{
- nix = {
- gc = {
- automatic = true;
- dates = "weekly";
- options = "--delete-older-than 7d";
- };
- };
-
- home-manager.useGlobalPkgs = true; # Use pkgs set within nixpkgs.
- home-manager.useUserPackages = true; # Install packages defined in home-manager.
-
- # Not enabling useTmpfs despite having enough RAM. Might consider it.
- boot.tmp.cleanOnBoot = true;
-
- hardware.pulseaudio.enable = false; # Disable PulseAudio: https://nixos.wiki/wiki/PulseAudio
- security.rtkit.enable = true; # Recommended for pipewire
- services.pipewire = {
- enable = true; # Enable pipewire
- alsa.enable = true; # For better compatibility
- alsa.support32Bit = true; # For better compatibility
- pulse.enable = true; # For better compatibility
- wireplumber.enable = true; # Audio routing policy if I understood correctly.
- };
-
- # Network
- networking = {
- networkmanager.enable = true;
- extraHosts = ''
- ${network-devices.home-nas.hostname} home-nas
- ${network-devices.pi-zero.hostname} pi-zero
- ${network-devices.rg353m.hostname} rg353m
- '';
- };
-
- # Input - More on https://wiki.archlinux.org/title/Xorg/Keyboard_configuration
- services.xserver = {
- #exportConfiguration = true; # Do I need this?
- xkb.layout = "us,pt"; # localectl list-x11-keymap-layouts and
- xkb.variant = "euro,"; # localectl list-x11-keymap-variants us
- xkb.options = builtins.concatStringsSep " " [
- "caps:ctrl_modifier" # Replace caps-lock for Ctrl
- "grp:ralt_rshift_toggle" # Right Alt + Right Shift: Switch keyboard layouts. See more using `xkeyboard-config`
- ];
-
- excludePackages = [ pkgs.xterm ];
- };
-
- # Programs
- programs.fish.enable = true; # System level/
- programs.fish.vendor.functions.enable = true; # Ensure completions/functions are automatically set.
- programs.partition-manager.enable = true;
- environment.systemPackages = with pkgs; [
- # Suport exFAT and NTFS formatted drives (pendisks + external disks)
- exfat
- ntfs3g
-
- powertop # Check what is consuming too much energy
- usbutils # USB utilities
- ];
-
- # Services
- services.fwupd.enable = true; # Updates firmwares: `fwupdmgr`
-
- # Localization
- time.timeZone = "Europe/Lisbon";
- i18n = {
- defaultLocale = "en_GB.UTF-8";
- extraLocaleSettings = {
- LC_ADDRESS = "pt_PT.UTF-8";
- LC_IDENTIFICATION = "pt_PT.UTF-8";
- LC_MEASUREMENT = "pt_PT.UTF-8";
- LC_MONETARY = "pt_PT.UTF-8";
- LC_NAME = "pt_PT.UTF-8";
- LC_NUMERIC = "pt_PT.UTF-8";
- LC_PAPER = "pt_PT.UTF-8";
- LC_TELEPHONE = "pt_PT.UTF-8";
- LC_TIME = "pt_PT.UTF-8";
- };
- };
-
- services.journald.extraConfig = ''
- MaxRetentionSec=1month
- SystemMaxUse=1G
- '';
-
- security.sudo.extraConfig = "Defaults lecture=never";
-
- # To install or run some programs, it is easier to this way. The exception.
- # Follow with: flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
- services.flatpak.enable = true;
-
- # Disabling some defaults
- programs.command-not-found.enable = false;
- programs.nano.enable = false;
-}
diff --git a/config/darwin/default.nix b/darwin/default.nix
similarity index 97%
rename from config/darwin/default.nix
rename to darwin/default.nix
index 6cd20ebb..372ade79 100644
--- a/config/darwin/default.nix
+++ b/darwin/default.nix
@@ -96,7 +96,8 @@
# Fonts (system-wide)
fonts.packages = with pkgs; [
- (nerdfonts.override { fonts = [ "Hack" "JetBrainsMono" ]; })
+ pkgs.nerd-fonts.hack
+ pkgs.nerd-fonts.jetbrains-mono
];
homebrew = {
@@ -109,9 +110,9 @@
brews = [ ];
casks = [
"rectangle" # Window Manager
+ "ghostty" # Terminal
"vlc" # Media player
"intellij-idea-ce" # JVM IDE
- "ngrok" # Useful
];
};
}
diff --git a/modules/darwin/default.nix b/darwin/modules/default.nix
similarity index 100%
rename from modules/darwin/default.nix
rename to darwin/modules/default.nix
diff --git a/modules/darwin/system/desktop.nix b/darwin/modules/system/desktop.nix
similarity index 100%
rename from modules/darwin/system/desktop.nix
rename to darwin/modules/system/desktop.nix
diff --git a/modules/darwin/system/screencapture.nix b/darwin/modules/system/screencapture.nix
similarity index 100%
rename from modules/darwin/system/screencapture.nix
rename to darwin/modules/system/screencapture.nix
diff --git a/flake.lock b/flake.lock
index db13a9f1..ed18de88 100644
--- a/flake.lock
+++ b/flake.lock
@@ -7,11 +7,11 @@
]
},
"locked": {
- "lastModified": 1729382845,
- "narHash": "sha256-REiWck1zIOnZIgGmmOWfwvkQw1f4UrBsxxOSKVSAG4w=",
+ "lastModified": 1736085891,
+ "narHash": "sha256-bTl9fcUo767VaSx4Q5kFhwiDpFQhBKna7lNbGsqCQiA=",
"owner": "lnl7",
"repo": "nix-darwin",
- "rev": "a001f44cfc47164839eb61c6b1e7f4288813f7e8",
+ "rev": "ba9b3173b0f642ada42b78fb9dfc37ca82266f6c",
"type": "github"
},
"original": {
@@ -28,11 +28,11 @@
]
},
"locked": {
- "lastModified": 1729281548,
- "narHash": "sha256-MuojlSnwAJAwfhgmW8ZtZrwm2Sko4fqubCvReqbUzYw=",
+ "lastModified": 1735468753,
+ "narHash": "sha256-2dt1nOe9zf9pDkf5Kn7FUFyPRo581s0n90jxYXJ94l0=",
"owner": "nix-community",
"repo": "disko",
- "rev": "a6a3179ddf396dfc28a078e2f169354d0c137125",
+ "rev": "84a5b93637cc16cbfcc61b6e1684d626df61eb21",
"type": "github"
},
"original": {
@@ -48,11 +48,11 @@
]
},
"locked": {
- "lastModified": 1726997277,
- "narHash": "sha256-Nw6ty7JDN/ihNECORC1SHhDPZmnkhSaTFYXwxQJ55yA=",
+ "lastModified": 1729850443,
+ "narHash": "sha256-8zZGD9i/P4acfnxA0SZj97b1PkajD3XM7/uRe2+5+uc=",
"ref": "refs/heads/main",
- "rev": "1cf2f395c2d1638cf50322e997aee5a218a1591f",
- "revCount": 11,
+ "rev": "5d4427c5a641d83606cd7cb766fc9ea2d8d2012f",
+ "revCount": 12,
"type": "git",
"url": "ssh://git@github.com/bphenriques/dotfiles-private"
},
@@ -61,44 +61,27 @@
"url": "ssh://git@github.com/bphenriques/dotfiles-private"
}
},
- "flake-utils": {
+ "flake-parts": {
"inputs": {
- "systems": "systems"
+ "nixpkgs-lib": [
+ "nur",
+ "nixpkgs"
+ ]
},
"locked": {
- "lastModified": 1705309234,
- "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
+ "lastModified": 1733312601,
+ "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
"type": "github"
},
"original": {
- "owner": "numtide",
- "repo": "flake-utils",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
"type": "github"
}
},
- "ghostty": {
- "inputs": {
- "nixpkgs-stable": "nixpkgs-stable",
- "nixpkgs-unstable": "nixpkgs-unstable",
- "zig": "zig"
- },
- "locked": {
- "lastModified": 1729515458,
- "narHash": "sha256-AYLxdLukuWXJREYupBiAXRk9PGX1qA7w/5adKMlNpTo=",
- "ref": "refs/heads/main",
- "rev": "c2cbc214d5f6d45cfa171b8ed6ea7a670a5cbdab",
- "revCount": 7762,
- "type": "git",
- "url": "ssh://git@github.com/mitchellh/ghostty"
- },
- "original": {
- "type": "git",
- "url": "ssh://git@github.com/mitchellh/ghostty"
- }
- },
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -106,11 +89,11 @@
]
},
"locked": {
- "lastModified": 1729459288,
- "narHash": "sha256-gBOVJv+q6Mx8jGvwX7cE6J8+sZmi1uxpRVsO7WxvVuQ=",
+ "lastModified": 1736089250,
+ "narHash": "sha256-/LPWMiiJGPHGd7ZYEgmbE2da4zvBW0acmshUjYC3WG4=",
"owner": "nix-community",
"repo": "home-manager",
- "rev": "1e27f213d77fc842603628bcf2df6681d7d08f7e",
+ "rev": "172b91bfb2b7f5c4a8c6ceac29fd53a01ef07196",
"type": "github"
},
"original": {
@@ -121,11 +104,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1729265718,
- "narHash": "sha256-4HQI+6LsO3kpWTYuVGIzhJs1cetFcwT7quWCk/6rqeo=",
+ "lastModified": 1736010017,
+ "narHash": "sha256-pMttboU4LraZezi3tc7NiHODd4eKziFRb2a4s4WO8Ms=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "ccc0c2126893dd20963580b6478d1a10a4512185",
+ "rev": "a1945f760a8fe019a4d753808de424dcd4e5b3cf",
"type": "github"
},
"original": {
@@ -137,75 +120,48 @@
},
"nixpkgs-stable": {
"locked": {
- "lastModified": 1726062281,
- "narHash": "sha256-PyFVySdGj3enKqm8RQuo4v1KLJLmNLOq2yYOHsI6e2Q=",
- "owner": "nixos",
- "repo": "nixpkgs",
- "rev": "e65aa8301ba4f0ab8cb98f944c14aa9da07394f8",
- "type": "github"
- },
- "original": {
- "owner": "nixos",
- "ref": "release-24.05",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs-stable_2": {
- "locked": {
- "lastModified": 1729307008,
- "narHash": "sha256-QUvb6epgKi9pCu9CttRQW4y5NqJ+snKr1FZpG/x3Wtc=",
+ "lastModified": 1736061677,
+ "narHash": "sha256-DjkQPnkAfd7eB522PwnkGhOMuT9QVCZspDpJJYyOj60=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "a9b86fc2290b69375c5542b622088eb6eca2a7c3",
+ "rev": "cbd8ec4de4469333c82ff40d057350c30e9f7d36",
"type": "github"
},
"original": {
"owner": "nixos",
- "ref": "nixos-24.05",
+ "ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
- "nixpkgs-stable_3": {
+ "nixpkgs_2": {
"locked": {
- "lastModified": 1729357638,
- "narHash": "sha256-66RHecx+zohbZwJVEPF7uuwHeqf8rykZTMCTqIrOew4=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "bb8c2cf7ea0dd2e18a52746b2c3a5b0c73b93c22",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "release-24.05",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs-unstable": {
- "locked": {
- "lastModified": 1719082008,
- "narHash": "sha256-jHJSUH619zBQ6WdC21fFAlDxHErKVDJ5fpN0Hgx4sjs=",
+ "lastModified": 1736012469,
+ "narHash": "sha256-/qlNWm/IEVVH7GfgAIyP6EsVZI6zjAx1cV5zNyrs+rI=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "9693852a2070b398ee123a329e68f0dab5526681",
+ "rev": "8f3e1f807051e32d8c95cd12b9b421623850a34d",
"type": "github"
},
"original": {
"owner": "nixos",
- "ref": "nixpkgs-unstable",
+ "ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nur": {
+ "inputs": {
+ "flake-parts": "flake-parts",
+ "nixpkgs": "nixpkgs_2",
+ "treefmt-nix": "treefmt-nix"
+ },
"locked": {
- "lastModified": 1729525671,
- "narHash": "sha256-/pZSi3LBtztMfOJti72FOj3OBJvsCb1N/d9Jl5L04fI=",
+ "lastModified": 1736153313,
+ "narHash": "sha256-QbFglVYGZ/GRzCLetrTOPli11xHD6w8I2w/QGsyeR90=",
"owner": "nix-community",
"repo": "nur",
- "rev": "305d127d2f03fb412de348455a3175df9e66cd04",
+ "rev": "6dc38ea9c5d7d4c3d1785594198d726849a14a6a",
"type": "github"
},
"original": {
@@ -219,10 +175,9 @@
"darwin": "darwin",
"disko": "disko",
"dotfiles-private": "dotfiles-private",
- "ghostty": "ghostty",
"home-manager": "home-manager",
"nixpkgs": "nixpkgs",
- "nixpkgs-stable": "nixpkgs-stable_2",
+ "nixpkgs-stable": "nixpkgs-stable",
"nur": "nur",
"sops-nix": "sops-nix"
}
@@ -231,15 +186,14 @@
"inputs": {
"nixpkgs": [
"nixpkgs"
- ],
- "nixpkgs-stable": "nixpkgs-stable_3"
+ ]
},
"locked": {
- "lastModified": 1729394972,
- "narHash": "sha256-fADlzOzcSaGsrO+THUZ8SgckMMc7bMQftztKFCLVcFI=",
+ "lastModified": 1736064798,
+ "narHash": "sha256-xJRN0FmX9QJ6+w8eIIIxzBU1AyQcLKJ1M/Gp6lnSD20=",
"owner": "Mic92",
"repo": "sops-nix",
- "rev": "c504fd7ac946d7a1b17944d73b261ca0a0b226a5",
+ "rev": "5dc08f9cc77f03b43aacffdfbc8316807773c930",
"type": "github"
},
"original": {
@@ -248,43 +202,24 @@
"type": "github"
}
},
- "systems": {
- "locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
- "owner": "nix-systems",
- "repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
- "type": "github"
- },
- "original": {
- "owner": "nix-systems",
- "repo": "default",
- "type": "github"
- }
- },
- "zig": {
+ "treefmt-nix": {
"inputs": {
- "flake-compat": [
- "ghostty"
- ],
- "flake-utils": "flake-utils",
"nixpkgs": [
- "ghostty",
- "nixpkgs-stable"
+ "nur",
+ "nixpkgs"
]
},
"locked": {
- "lastModified": 1717848532,
- "narHash": "sha256-d+xIUvSTreHl8pAmU1fnmkfDTGQYCn2Rb/zOwByxS2M=",
- "owner": "mitchellh",
- "repo": "zig-overlay",
- "rev": "02fc5cc555fc14fda40c42d7c3250efa43812b43",
+ "lastModified": 1733222881,
+ "narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=",
+ "owner": "numtide",
+ "repo": "treefmt-nix",
+ "rev": "49717b5af6f80172275d47a418c9719a31a78b53",
"type": "github"
},
"original": {
- "owner": "mitchellh",
- "repo": "zig-overlay",
+ "owner": "numtide",
+ "repo": "treefmt-nix",
"type": "github"
}
}
diff --git a/flake.nix b/flake.nix
index 5b203921..c6ce0bc2 100644
--- a/flake.nix
+++ b/flake.nix
@@ -13,8 +13,8 @@
};
inputs = {
- nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; # Stable(ish) enough. Plus home-manager is _always_ on unstable
- nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.05"; # I don't really use it, but leaving it here.
+ nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; # Stable(ish) enough. Plus home-manager is _always_ on unstable.
+ nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.11"; # I don't really use it, but leaving it here.
darwin.url = "github:lnl7/nix-darwin/master";
darwin.inputs.nixpkgs.follows = "nixpkgs";
@@ -32,7 +32,6 @@
disko.url = "github:nix-community/disko"; # Declaratively describe my disks layout
disko.inputs.nixpkgs.follows = "nixpkgs";
nur.url = "github:nix-community/nur"; # Collection of packages. Use it for Firefox extensions
- ghostty.url = "git+ssh://git@github.com/mitchellh/ghostty"; # Terminal
};
outputs = inputs @ { nixpkgs, ... }:
@@ -47,14 +46,14 @@
default = import ./shell.nix { pkgs = nixpkgs.legacyPackages.${system}; };
});
overlays = import ./overlays { inherit inputs; };
- nixosModules = import ./modules/nixos;
+ nixosModules = import ./nixos/modules;
# Hosts - Each host defines what it needs from the inputs.
- nixosConfigurations.laptop = import ./hosts/laptop (inputs // { inherit mylib; });
- darwinConfigurations.work-macos = import ./hosts/work-macos (inputs // { inherit mylib; });
+ nixosConfigurations.laptop = import ./hosts/laptop { inherit mylib inputs; };
+ darwinConfigurations.work-macos = import ./hosts/work-macos { inherit mylib inputs; };
# Non standard flake outputs
- homeManagerModules = import ./modules/home-manager;
- darwinModules = import ./modules/darwin;
+ homeManagerModules = import ./home-manager/modules;
+ darwinModules = import ./darwin/modules;
};
}
diff --git a/home-manager/default.nix b/home-manager/default.nix
new file mode 100644
index 00000000..caa329ad
--- /dev/null
+++ b/home-manager/default.nix
@@ -0,0 +1,129 @@
+{ pkgs, lib, config, ... }:
+{
+ imports = [
+ ./fonts.nix
+ ./git.nix
+ ./fish.nix # Shell
+ ./helix.nix # Editor
+ ./direnv.nix # Automate dev environment when we enter directories
+ ./fzf.nix # Fuzzy search
+ ./ripgrep.nix # Search
+ ./yazi.nix # File browser
+ ./lang-scala.nix # Programming language
+ ];
+
+ # XDG Compliance to tidy up $HOME.
+ xdg.enable = true;
+ xdg.mimeApps.enable = pkgs.stdenv.isLinux; # Default apps and directories
+ home.preferXdgDirectories = true;
+
+ programs.bat.enable = true; # Better file previewer
+ programs.fd.enable = true; # Better `find`.
+ programs.jq.enable = true; # JSON query.
+ programs.htop.enable = true; # Fancy `top`.
+ custom.programs.project.enable = true; # Easier way to navigate jump through different projects
+
+ programs.tealdeer = {
+ enable = true;
+ settings = {
+ display = {
+ compact = false;
+ use_pager = true;
+ };
+
+ updates.auto_update = false;
+ };
+ };
+
+ programs.zoxide = {
+ enable = true;
+ options = [ "--cmd j" ];
+ };
+
+ home.packages = with pkgs; [
+ # Consistency across different operating systems
+ coreutils
+ findutils
+ gnugrep
+ watch
+ tree
+ parallel
+ gnused
+ dateutils
+ unzip
+ openssl
+ xdg-user-dirs
+
+ # Text Processors
+ yq-go # Query YAML.
+ vim # Basic editor
+
+ # Archive
+ p7zip # 7zip for linux
+ unrar # Still need it
+
+ # Monitoring
+ procs # Fancy `ps`.
+ ];
+
+ # Gpg
+ programs.gpg.enable = pkgs.stdenv.isLinux;
+ services.gpg-agent = {
+ enable = pkgs.stdenv.isLinux;
+ pinentryPackage = pkgs.pinentry-gnome3;
+ };
+
+ home = {
+ sessionVariables = {
+ VISUAL = "$EDITOR"; # Set within the editor config.
+ PAGER = "less -iMR";
+
+ # Colors
+ LS_COLORS ="$(${pkgs.vivid}/bin/vivid generate snazzy)"; # LS_COLORS generator because I refuse to maintain one >.<
+ LANG = "en_US.UTF-8";
+ LC_ALL = "en_US.UTF-8";
+ } // (lib.optionalAttrs pkgs.config.allowUnfree {
+ NIXPKGS_ALLOW_UNFREE = 1;
+ }) // (lib.optionalAttrs pkgs.stdenv.isDarwin {
+ CLICOLOR = 1; # Enable ls colors in MacOS.
+ });
+
+ shellAliases = {
+ # Default colorizatio
+ diff = "diff --color=auto";
+ grep = "grep --color=auto";
+ egrep = "egrep --color=auto";
+ fgrep = "fgrep --color=auto";
+ ls = "ls --color=auto";
+
+ # The usual aliases
+ l = "ls -alh";
+ ll = "ls -l";
+
+ # Quality of life
+ mkdir = "mkdir -pv";
+ ".." = "cd ..";
+ "..." = "cd ../..";
+ ":q" = "exit";
+ tmpdir = "cd (mktemp -d)";
+
+ # Text Processor
+ e = "$EDITOR";
+
+ # Utility
+ whatsmyip = "${lib.getExe pkgs.curl} ifconfig.me";
+ } // (lib.optionalAttrs pkgs.stdenv.isLinux {
+ webp_to_png = ''nix-shell -p libwebp -p parallel --command "parallel dwebp {} -o {.}.png ::: *.webp"'';
+ });
+ };
+
+ programs.man.enable = true; # RTFM
+ manual.manpages.enable = false; # Discard home-manager configuration man pages.
+ manual.json.enable = false; # Discard home-manager configuration JSON docs.
+
+ # Tighten permissions to private keys
+ systemd.user.tmpfiles.rules = lib.optionals pkgs.stdenv.isLinux [
+ "z ${config.home.homeDirectory}/.ssh 0700 ${config.home.username} users"
+ "z ${config.home.homeDirectory}/.gnupg 0700 ${config.home.username} users"
+ ];
+}
diff --git a/home-manager/desktop-environment/default.nix b/home-manager/desktop-environment/default.nix
new file mode 100644
index 00000000..096c34e1
--- /dev/null
+++ b/home-manager/desktop-environment/default.nix
@@ -0,0 +1,64 @@
+{ config, lib, pkgs, ... }:
+{
+ imports = [
+ ./niri.nix # Window Manager
+ ./waybar # Status bar
+ ./mako.nix # Notification Daemon
+ ./fuzzel.nix # Application Launcher
+ ./rofi.nix # Application Launcher
+ ./swayidle.nix # Locks/suspends the computer when idle
+ ./hyprlock.nix # Lock screend
+ ];
+
+ custom.services.swww.enable = true; # Wallpaper daemon
+ home.packages = [
+ # TODO: MOVE TO: https://github.com/savedra1/clipse
+ pkgs.cliphist # Wayland clipboard history
+ (pkgs.writeScriptBin "pbcopy" (lib.getExe' pkgs.wl-clipboard "wl-copy")) # I am too hardwired to pbcopy
+ (pkgs.writeScriptBin "pbpaste" (lib.getExe' pkgs.wl-clipboard "wl-paste")) # I am too hardwired to pbpaste
+ ];
+
+ home.pointerCursor = {
+ gtk.enable = true;
+ package = pkgs.bibata-cursors;
+ name = "Bibata-Modern-Classic";
+ size = 16;
+ };
+
+ gtk = {
+ enable = true;
+ theme = {
+ package = pkgs.adw-gtk3;
+ name = "adw-gtk3-dark";
+ };
+
+ iconTheme = {
+ package = pkgs.morewaita-icon-theme;
+ name = "MoreWaita";
+ };
+
+ font = {
+ name = "Ubuntu Nerd Font";
+ package = pkgs.nerd-fonts.ubuntu;
+ size = 11;
+ };
+
+ gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc"; # Leave my $HOME
+ gtk3.extraConfig = {
+ gtk-application-prefer-dark-theme = 1;
+ gtk-error-bell = 0;
+ };
+
+ gtk4.extraConfig = {
+ gtk-application-prefer-dark-theme = 1;
+ gtk-error-bell = 0;
+ };
+ };
+
+ qt = {
+ enable = true;
+ style.name = "adwaita-dark";
+ style.package = pkgs.adwaita-qt;
+ platformTheme.name = "adwaita-dark";
+ };
+}
diff --git a/home-manager/desktop-environment/dunst.nix b/home-manager/desktop-environment/dunst.nix
new file mode 100644
index 00000000..174f0960
--- /dev/null
+++ b/home-manager/desktop-environment/dunst.nix
@@ -0,0 +1,49 @@
+{ config, lib, pkgs, ... }:
+{
+ services.dunst = {
+ enable = false;
+ iconTheme = {
+ name = "Papirus-Dark";
+ package = pkgs.papirus-icon-theme;
+ };
+ settings = {
+ global = {
+ enable_recursive_icon_lookup = true;
+ rounded = true;
+ width = "400";
+ height = "400";
+ gap_size = 2;
+ progress_bar_corner_radius = 2;
+ idle_threshold = 120;
+ markup = "full";
+ corner_radius = 10;
+ follow = "mouse";
+
+ font = "Source Sans Pro 10";
+ frame_color = "#232323";
+ frame_width = 1;
+ offset = "15x15";
+ mouse_left_click = "do_action, close_current";
+ mouse_middle_click = "close_current";
+ mouse_right_click = "close_all";
+ };
+
+ fullscreen_delay_everything = {
+ fullscreen = "delay";
+ };
+
+ urgency_critical = {
+ background = "#d64e4e";
+ foreground = "#f0e0e0";
+ };
+ urgency_low = {
+ background = "#232323";
+ foreground = "#2596be";
+ };
+ urgency_normal = {
+ background = "#1e1e2a";
+ foreground = "#2596be";
+ };
+ };
+ };
+}
\ No newline at end of file
diff --git a/home-manager/desktop-environment/fuzzel.nix b/home-manager/desktop-environment/fuzzel.nix
new file mode 100644
index 00000000..08e9a9a3
--- /dev/null
+++ b/home-manager/desktop-environment/fuzzel.nix
@@ -0,0 +1,21 @@
+{ config, pkgs, lib, ... }:
+{
+ fonts.fontconfig.enable = true;
+ home.packages = [ pkgs.nerd-fonts.jetbrains-mono ];
+
+ programs.fuzzel = {
+ enable = true;
+ settings = {
+ main.font = "JetBrainsMono Nerd Font";
+ colors = {
+ background = "1e1e2edd";
+ text = "cdd6f4ff";
+ match = "f38ba8ff";
+ selection = "585b70ff";
+ selection-match = "f38ba8ff";
+ selection-text = "cdd6f4ff";
+ border = "b4befeff";
+ };
+ };
+ };
+}
diff --git a/home-manager/desktop-environment/hyprlock.nix b/home-manager/desktop-environment/hyprlock.nix
new file mode 100644
index 00000000..9d5d82b0
--- /dev/null
+++ b/home-manager/desktop-environment/hyprlock.nix
@@ -0,0 +1,56 @@
+{ config, pkgs, lib, self, ... }:
+let
+ wallpapersPkg = self.private.wallpapers.override {
+ selected = [ "lake" ];
+ };
+in
+{
+ programs.hyprlock = {
+ enable = true;
+
+ settings = {
+ general.disable_loading_bar = true;
+ background = [{
+ path = "${wallpapersPkg}/share/wallpapers/lake.jpg";
+ blur_passes = 3;
+ blur_size = 12;
+ }];
+
+ input-field = [{
+ size = "300, 50";
+ valign = "bottom";
+ position = "0%, 10%";
+
+ outline_thickness = 1;
+
+ font_color = "rgb(b6c4ff)";
+ outer_color = "rgba(180, 180, 180, 0.5)";
+ inner_color = "rgba(200, 200, 200, 0.1)";
+ check_color = "rgba(247, 193, 19, 0.5)";
+ fail_color = "rgba(255, 106, 134, 0.5)";
+
+ fade_on_empty = false;
+ placeholder_text = "Enter Password";
+
+ shadow_color = "rgba(0, 0, 0, 0.1)";
+ shadow_size = 7;
+ shadow_passes = 2;
+ }];
+
+ label = [{
+ text = ''cmd[update:60000] echo "$(date +'%H:%M')"'';
+ font_size = 300;
+ font_family = "Ubuntu Nerd Font";
+
+ color = "rgb(b6c4ff)";
+ position = "0%, 2%";
+ valign = "center";
+ halign = "center";
+ shadow_color = "rgba(0, 0, 0, 0.1)";
+ shadow_size = 20;
+ shadow_passes = 2;
+ shadow_boost = 0.3;
+ }];
+ };
+ };
+}
\ No newline at end of file
diff --git a/home-manager/desktop-environment/mako.nix b/home-manager/desktop-environment/mako.nix
new file mode 100644
index 00000000..5cf4fb24
--- /dev/null
+++ b/home-manager/desktop-environment/mako.nix
@@ -0,0 +1,26 @@
+{ pkgs, lib, ... }:
+{
+ services.mako = {
+ enable = true;
+ layer = "overlay";
+ defaultTimeout = 5000;
+
+ # Theming
+ backgroundColor = "#151515";
+ textColor = "#e8e3e3";
+ progressColor = "over #2e2e2e";
+ width = 300;
+ height = 200;
+ margin = "8";
+ padding = "12";
+ borderSize = 1;
+ borderRadius = 4;
+ borderColor= "#424242";
+
+ extraConfig = ''
+ [urgency=critical]
+ border-color=#b66467
+ default-timeout=0
+ '';
+ };
+}
\ No newline at end of file
diff --git a/home-manager/desktop-environment/niri.nix b/home-manager/desktop-environment/niri.nix
new file mode 100644
index 00000000..738bc6f6
--- /dev/null
+++ b/home-manager/desktop-environment/niri.nix
@@ -0,0 +1,250 @@
+{ config, lib, pkgs, self, community, ... }:
+# Logout: https://github.com/wuliuqii/nixos-config/blob/69606b2e0cccb6a135522fc5df188e4da0595e73/home/wm/wlogout.nix
+# TODO: Alt F4 means keep closing active window until there is none. Then, show list of options.
+# TODO: "Mod+Escape".action = spawn "wlogout";
+# # https://github.com/prasanthrangan/hyprdots?tab=readme-ov-file
+# https://github.com/linyinfeng/dotfiles/blob/340f913ea7520a3c0034034d4fe870c05145bbcb/home-manager/profiles/niri/default.nix#L796
+# ${lib.getExe pkgs.grim} -g \"$(${lib.getExe pkgs.slurp} -o -r -c '#ff0000ff')\" -t ppm - | ${lib.getExe pkgs.satty} --filename - --fullscreen --output-filename ~/Pictures/Screenshots/satty-$(date '+%Y%m%d-%H:%M:%S').png
+
+# Battery? https://github.com/linuxmobile/kaku/blob/13eb9e8a19823cb2fa2aed29f7b1f49bea51c4a2/system/services/power.nix
+# Seems to be more or less what I want? https://github.com/kiike/dotfiles/blob/ff788bae02ba6d15c73632d99654269d2b5fba49/hosts/balrog/default.nix
+# Idle effect: https://github.com/nyawox/nixboxes/blob/ecab4559da256b4f1198ca7d39d6e5b1d4442296/home/desktop/niri/swayidle.nix#L24
+# Screencast? https://github.com/maximbaz/dotfiles/blob/98ff8b69370e86879faf57b29d07cfcb6aff4306/modules/linux/xdg.nix#L2
+# https://github.com/nyawox/nixboxes/blob/ecab4559da256b4f1198ca7d39d6e5b1d4442296/home/desktop/niri/general.nix
+
+# Window rules: https://github.com/nyawox/nixboxes/blob/ecab4559da256b4f1198ca7d39d6e5b1d4442296/home/desktop/niri/general.nix#L143
+# Env variables: https://github.com/nyawox/nixboxes/blob/ecab4559da256b4f1198ca7d39d6e5b1d4442296/home/desktop/niri/general.nix#L185
+# Funny login audio: https://github.com/nyawox/nixboxes/blob/ecab4559da256b4f1198ca7d39d6e5b1d4442296/home/desktop/niri/general.nix#L201
+# https://gitlab.com/scientiac/einstein.nixos/-/tree/main/home/niriwm?ref_type=heads
+# https://gitlab.com/scientiac/einstein.nixos/-/blob/main/home/niriwm/niri.nix?ref_type=heads
+# https://gitlab.com/usmcamp0811/dotfiles
+# https://github.com/gopi487krishna/niri-waydots/tree/main/rofi
+
+# https://github.com/LoneWolf4713/seraphic.dotfiles
+# TODO shortcut to lock the computer
+
+let
+ # nix repl
+ # then :lf .
+ # then inputs.nixpkgs.lib.strings.concatMapStringsSep " " (x: ''"${x}"'') inputs.nixpkgs.lib.strings.splitString " " "please run this command"
+ # run-cmd = cmd: lib.strings.concatMapStringsSep " " (x: ''"${x}"'') lib.strings.splitString " " cmd;
+
+ xwaylandDisplayId = "21";
+
+ wallpapersPkg = self.private.wallpapers.override {
+ selected = [ "lake-fishing-sunset" "mountains" "whale-sunset" "watch-tower" ];
+ };
+
+ env = {
+ DISPLAY = ":${xwaylandDisplayId}";
+ NIXOS_OZONE_WL = "1"; # Electron?
+ QT_QPA_PLATFORM = "wayland";
+ QT_WAYLAND_DISABLE_WINDOWDECORATION = "1"; # Signal QT windows to remove their window decorations
+ };
+
+ on-startup = ''
+ spawn-at-startup "${lib.getExe self.pkgs.swww-util}" "random" "${wallpapersPkg}/share/wallpapers"
+ spawn-at-startup "${lib.getExe pkgs.xwayland-satellite}" ":${xwaylandDisplayId}"
+ spawn-at-startup "${lib.getExe pkgs.waybar}"
+ spawn-at-startup "${lib.getExe self.pkgs.niri-output-configuration}" "startup"
+ spawn-at-startup "${pkgs.wl-clipboard}/bin/wl-paste" "--type" "text" "--watch" "${lib.getExe pkgs.cliphist}" "store" "-max-items" "20"
+ spawn-at-startup "${self.pkgs.sway-audio-idle-inhibit}/bin/sway-audio-idle-inhibit" "-w"
+ '';
+
+ input = ''
+ input {
+ keyboard {
+ xkb {
+ layout "us,pt";
+ variant "euro,";
+ options "caps:ctrl_modifier"
+ }
+ }
+
+ touchpad {
+ tap
+ natural-scroll
+ }
+
+ mouse {
+ }
+ }
+ '';
+ outputs = ''
+ output "Samsung Display Corp. 0x4188 Unknown" {
+ mode "2880x1800@120.001"
+ scale 1.75
+ }
+
+ output "Dell Inc. DELL S2721DGF 4P11R83" {
+ off
+ mode "2560x1440@143.912"
+ scale 1.0
+ variable-refresh-rate on-demand=true
+ }
+ '';
+
+ layout = ''
+ layout {
+ gaps 6
+ center-focused-column "on-overflow"
+ preset-column-widths {
+ proportion 0.33333
+ proportion 0.5
+ proportion 0.66667
+ proportion 1.0
+ }
+ default-column-width { proportion 1.00; }
+ focus-ring {
+ width 3
+ active-color "#7fc8ff"
+ inactive-color "#505050"
+ }
+
+ border {
+ off
+ }
+ }
+ '';
+in
+{
+ #services.gnome-keyring.enable = true; # Redundant as done in nixos?
+
+ xdg.configFile."niri/config.kdl".text = ''
+ workspace "browsing"
+ workspace "coding"
+ workspace "gaming"
+
+ window-rule {
+ match at-startup=true app-id="com.mitchellh.ghostty"
+ match at-startup=true app-id="jetbrains-idea-ce"
+ open-on-workspace "coding"
+ }
+
+ window-rule {
+ match at-startup=true app-id="firefox"
+ open-on-workspace "browsing"
+ }
+
+ window-rule {
+ match at-startup=true app-id="steam$"
+ match at-startup=true app-id=r#"^steam_app_[0-9]+$"#
+ open-on-workspace "gaming"
+ }
+
+ hotkey-overlay {
+ skip-at-startup
+ }
+
+ environment {
+ DISPLAY ":21"
+ XDG_CURRENT_DESKTOP "niri"
+ QT_WAYLAND_DISABLE_WINDOWDECORATION "1"
+ QT_QPA_PLATFORM "wayland"
+ NIXOS_OZONE_WL "1"
+ MOZ_ENABLE_WAYLAND "1"
+ }
+
+ ${on-startup}
+ ${input}
+ ${outputs}
+ ${layout}
+
+ prefer-no-csd
+
+ screenshot-path "${config.xdg.userDirs.extraConfig.XDG_SCREENSHOTS_DIR}/%Y-%m-%d %H-%M-%S.png"
+
+ animations {
+ }
+
+ binds {
+ // Basic
+ Mod+Q { close-window; }
+ Mod+Shift+Slash { show-hotkey-overlay; }
+ Mod+F { maximize-column; }
+ Mod+Shift+F { fullscreen-window; }
+ Mod+C { center-column; }
+ Mod+W { spawn "pkill" "-SIGUSR1" "waybar"; }
+
+ Print { screenshot; }
+ Ctrl+Print { screenshot-screen; }
+ Alt+Print { screenshot-window; }
+
+ Mod+Shift+E { quit; }
+
+ Mod+Period { spawn "${lib.getExe pkgs.bemoji}"; }
+ Mod+Shift+Q { spawn "${lib.getExe self.pkgs.session-dmenu}"; }
+ Mod+Shift+Tab { focus-workspace-previous; }
+ Mod+Tab { spawn "${lib.getExe self.pkgs.niri-window-dmenu}"; }
+ Mod+Shift+V { spawn "${lib.getExe self.pkgs.cliphist-dmenu}" "&&" "${lib.getExe self.pkgs.smart-paste}"; }
+
+ // Suggested binds for running programs: terminal, app launcher, screen locker.
+ Mod+Return { spawn "${lib.getExe pkgs.ghostty}"; }
+ Mod+Space { spawn "${lib.getExe pkgs.fuzzel}"; }
+ Super+Alt+L { spawn "swaylock"; }
+
+ // Audio
+ XF86AudioRaiseVolume allow-when-locked=true { spawn "${lib.getExe self.pkgs.osd-volume}" "increase"; }
+ XF86AudioLowerVolume allow-when-locked=true { spawn "${lib.getExe self.pkgs.osd-volume}" "decrease"; }
+ XF86AudioMute allow-when-locked=true { spawn "${lib.getExe self.pkgs.osd-volume}" "toggle-mute"; }
+ XF86AudioMicMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; }
+ XF86AudioNext allow-when-locked=true { spawn "playerctl" "next"; }
+ XF86AudioPause allow-when-locked=true { spawn "playerctl" "play-pause"; }
+ XF86AudioPlay allow-when-locked=true { spawn "playerctl" "play-pause"; }
+ XF86AudioPrev allow-when-locked=true { spawn "playerctl" "previous"; }
+
+ // Brightness
+ XF86MonBrightnessUp allow-when-locked=true { spawn "${lib.getExe self.pkgs.osd-brightness}" "increase"; }
+ XF86MonBrightnessDown allow-when-locked=true { spawn "${lib.getExe self.pkgs.osd-brightness}" "decrease"; }
+
+ Mod+Left { focus-column-left; }
+ Mod+Down { focus-window-down; }
+ Mod+Up { focus-window-up; }
+ Mod+Right { focus-column-right; }
+
+ Mod+Ctrl+Left { move-column-left; }
+ Mod+Ctrl+Down { move-window-down; }
+ Mod+Ctrl+Up { move-window-up; }
+ Mod+Ctrl+Right { move-column-right; }
+
+ Mod+Shift+Down { focus-workspace-down; }
+ Mod+Shift+Up { focus-workspace-up; }
+
+ Mod+1 { focus-workspace 1; }
+ Mod+2 { focus-workspace 2; }
+ Mod+3 { focus-workspace 3; }
+ Mod+4 { focus-workspace 4; }
+ Mod+5 { focus-workspace 5; }
+ Mod+6 { focus-workspace 6; }
+ Mod+7 { focus-workspace 7; }
+ Mod+8 { focus-workspace 8; }
+ Mod+9 { focus-workspace 9; }
+ Mod+Ctrl+1 { move-column-to-workspace 1; }
+ Mod+Ctrl+2 { move-column-to-workspace 2; }
+ Mod+Ctrl+3 { move-column-to-workspace 3; }
+ Mod+Ctrl+4 { move-column-to-workspace 4; }
+ Mod+Ctrl+5 { move-column-to-workspace 5; }
+ Mod+Ctrl+6 { move-column-to-workspace 6; }
+ Mod+Ctrl+7 { move-column-to-workspace 7; }
+ Mod+Ctrl+8 { move-column-to-workspace 8; }
+ Mod+Ctrl+9 { move-column-to-workspace 9; }
+
+ // Mod+Comma { consume-window-into-column; }
+ // Mod+Period { expel-window-from-column; }
+
+ // There are also commands that consume or expel a single window to the side.
+ Mod+BracketLeft { consume-or-expel-window-left; }
+ Mod+BracketRight { consume-or-expel-window-right; }
+
+ Mod+R { switch-preset-column-width; }
+ Mod+Shift+R { switch-preset-window-height; }
+ Mod+Ctrl+R { reset-window-height; }
+
+ Alt+Mod+Space { switch-layout "next"; }
+
+ // Powers off the monitors. To turn them back on, do any input like
+ // moving the mouse or pressing any other key.
+ Mod+Shift+P { power-off-monitors; }
+ }
+ '';
+}
diff --git a/home-manager/desktop-environment/rofi.nix b/home-manager/desktop-environment/rofi.nix
new file mode 100644
index 00000000..1f9d2bb7
--- /dev/null
+++ b/home-manager/desktop-environment/rofi.nix
@@ -0,0 +1,232 @@
+{ pkgs, lib, ... }:
+
+# desktop items: https://github.com/edmundmiller/dotfiles/blob/main/modules/desktop/apps/rofi.nix
+let
+ theme = ''
+ * {
+ font: "Cascadia Code NF 11";
+
+ bg0: #151515f2;
+ bg1: #1f1f1f80;
+ bg2: #393939bf;
+ fg0: #ffffff;
+ fg1: #cecece;
+ fg2: #DEDEDE80;
+
+ background-color: transparent;
+ text-color: @fg0;
+
+ margin: 0;
+ padding: 0;
+ spacing: 0;
+ }
+
+ window {
+ background-color: @bg0;
+ location: center;
+ width: 540px;
+ border-radius: 4px;
+ }
+
+ inputbar {
+ font: "Cascadia Code NF 13";
+ padding: 12px;
+ spacing: 12px;
+ children: [ icon-search, entry];
+ }
+
+ icon-search {
+ expand: false;
+ filename: "search";
+ size: 28px;
+ }
+
+ icon-search,
+ entry,
+ element-icon,
+ element-text {
+ vertical-align: 0.5;
+ }
+
+ entry {
+ font: inherit;
+
+ placeholder: "Search";
+ placeholder-color: @fg2;
+ }
+
+ message {
+ border: 2px 0 0;
+ border-color: @bg1;
+ background-color: @bg1;
+ }
+
+ textbox {
+ padding: 8px 24px;
+ }
+
+ listview {
+ lines: 7;
+ columns: 1;
+ fixed-height: false;
+ border: 1px 0 0;
+ border-color: @bg1;
+ }
+
+ element {
+ padding: 8px 16px;
+ spacing: 16px;
+ background-color: transparent;
+ children: [ element-icon, element-text];
+ }
+
+ element normal active {
+ text-color: @bg2;
+ }
+
+ element alternate active {
+ text-color: @bg2;
+ }
+
+ element selected normal,
+ element selected active {
+ background-color: @bg2;
+ text-color: @fg1;
+ }
+
+ element-icon {
+ size: 2em;
+ }
+
+ element-text {
+ text-color: inherit;
+ }
+ '';
+in
+{
+ # #https://codeberg.org/adamcstephens/dotfiles/src/branch/main/apps/rofi/default.nix
+ programs.rofi = {
+ enable = true;
+ package = pkgs.rofi-wayland;
+# theme = {
+# "*" = {
+# font = "FiraCode Nerd Font Medium 14";
+# bg0 = mkLiteral "#1e1e2e";
+# bg1 = mkLiteral "#181825";
+# bg2 = mkLiteral "#11111b";
+# bg3 = mkLiteral "#b4befe";
+# fg0 = mkLiteral "#cdd6f4";
+# fg1 = mkLiteral "#bac2de";
+# fg2 = mkLiteral "#a6adc8";
+# red = mkLiteral "#f38ba8";
+# green = mkLiteral "#a6e3a1";
+# yellow = mkLiteral "#f9e2af";
+# blue = mkLiteral "#89b4fa";
+# magenta = mkLiteral "#cba6f7";
+# cyan = mkLiteral "#94e2d5";
+#
+# accent = mkLiteral "@red";
+# urgent = mkLiteral "@yellow";
+#
+# background-color = mkLiteral "transparent";
+# text-color = mkLiteral "@fg0";
+#
+# margin = 0;
+# padding = 0;
+# spacing = 0;
+# };
+# "element-icon, element-text, scrollbar" = {
+# cursor = mkLiteral "pointer";
+# };
+#
+# "window" = {
+# location = mkLiteral "center";
+# width = mkLiteral "500px";
+#
+# background-color = mkLiteral "@bg1";
+# border = mkLiteral "3px";
+# border-color = mkLiteral "@bg3";
+# border-radius = mkLiteral "6px";
+# };
+#
+# "inputbar" = {
+# spacing = mkLiteral "8px";
+# padding = mkLiteral "4px 8px";
+# children = mkLiteral "[ prompt, entry ]";
+#
+# background-color = mkLiteral "@bg0";
+# };
+#
+# "icon-search, entry, element-icon, element-text" = {
+# vertical-align = mkLiteral "0.5";
+# };
+#
+# "icon-search" = {
+# expand = mkLiteral "false";
+# filename = "search-symbolic";
+# size = mkLiteral "14px";
+# };
+#
+# "textbox" = {
+# padding = mkLiteral "4px 8px";
+# background-color = mkLiteral "@bg2";
+# };
+#
+# "listview" = {
+# padding = mkLiteral "4px 0px";
+# lines = mkLiteral "12";
+# columns = mkLiteral "1";
+# scrollbar = mkLiteral "false";
+# fixed-height = mkLiteral "false";
+# dynamic = mkLiteral "true";
+# };
+#
+# "element" = {
+# padding = mkLiteral "4px 8px";
+# spacing = mkLiteral "8px";
+# };
+#
+# "element normal urgent" = {
+# text-color = mkLiteral "@urgent";
+# };
+#
+# "element normal active" = {
+# text-color = mkLiteral "@accent";
+# };
+#
+# "element selected" = {
+# text-color = mkLiteral "@bg1";
+# background-color = mkLiteral "@accent";
+# };
+#
+# "element selected urgent" = {
+# background-color = mkLiteral "@urgent";
+# };
+#
+# "element-icon" = {
+# size = mkLiteral "0.8em";
+# };
+#
+# "element-text" = {
+# text-color = mkLiteral "inherit";
+# };
+#
+# "scrollbar" = {
+# handle-width = mkLiteral "0px";
+# handle-color = mkLiteral "@fg2";
+# padding = mkLiteral "0 4px";
+# };
+# };
+# extraConfig = {
+# modes = mkLiteral "[ combi ]";
+# combi-modes = mkLiteral "[ window, drun, run ]";
+# };
+ };
+}
+
+# https://github.com/iynaix/dotfiles/blob/e441ab4ff7a775b57b6c79a2fa6be99e3ab2d58b/home-manager/programs/rofi.nix
+# https://github.com/iynaix/dotfiles/blob/e441ab4ff7a775b57b6c79a2fa6be99e3ab2d58b/home-manager/programs/rofi-wifi-menu.sh
+# https://github.com/iynaix/dotfiles/blob/e441ab4ff7a775b57b6c79a2fa6be99e3ab2d58b/home-manager/programs/rofi-power-menu.sh
+# https://github.com/adi1090x/rofi/tree/master/files
+# https://github.com/edmundmiller/dotfiles/blob/main/modules/desktop/apps/rofi.nix
+# https://github.com/edmundmiller/dotfiles/blob/main/config/rofi/bin/rofi-browsermenu
diff --git a/home-manager/desktop-environment/swayidle.nix b/home-manager/desktop-environment/swayidle.nix
new file mode 100644
index 00000000..8aa6aa35
--- /dev/null
+++ b/home-manager/desktop-environment/swayidle.nix
@@ -0,0 +1,34 @@
+{ pkgs, config, lib, self, ... }:
+
+let
+ pidof = lib.getExe' pkgs.procps "pidof";
+ hyprlock = lib.getExe config.programs.hyprlock.package;
+ niri = lib.getExe pkgs.niri;
+ osd-brightness = lib.getExe self.pkgs.osd-brightness;
+ systemctl = lib.getExe' pkgs.systemd "systemctl";
+in
+{
+ services.swayidle = {
+ enable = true;
+ timeouts = [
+ {
+ timeout = 60 * 5;
+ command = "${osd-brightness} dim >/dev/null 2>&1";
+ resumeCommand = "${osd-brightness} restore >/dev/null 2>&1";
+ }
+ {
+ timeout = 60 * 6;
+ command = "${pidof} hyprlock || ${niri} msg action spawn -- ${hyprlock}";
+ }
+ {
+ timeout = 60 * 10;
+ command = "${systemctl} suspend";
+ }
+ ];
+
+ events = [
+ { event = "before-sleep"; command = "${niri} msg action power-off-monitors"; }
+ { event = "after-resume"; command = "${niri} msg action power-on-monitors"; }
+ ];
+ };
+}
diff --git a/home-manager/desktop-environment/waybar/default.nix b/home-manager/desktop-environment/waybar/default.nix
new file mode 100644
index 00000000..91d9f4bc
--- /dev/null
+++ b/home-manager/desktop-environment/waybar/default.nix
@@ -0,0 +1,243 @@
+{ lib, config, pkgs, self, ... }:
+# https://github.com/bitSheriff/dotfiles/blob/master/configuration/.config/waybar/modules/modules.jsonc
+# https://github.com/nix-community/nur-combined/blob/4d8b064e3cff836ee8c17c48c592874b0209e167/repos/slaier/modules/waybar/mediaplayer.nix
+# TODO: Notification: https://github.com/prasanthrangan/hyprdots/blob/main/Configs/.config/waybar/modules/notifications.jsonc
+let
+ audio = {
+ headset = {
+ name = "alsa_output.usb-SteelSeries_SteelSeries_Arctis_7-00.stereo-game";
+ icon = "";
+ icon-muted = "";
+ };
+
+ external-speaker = {
+ name = "alsa_output.pci-0000_01_00.1.hdmi-stereo";
+ icon = "";
+ icon-muted = "";
+ };
+
+ internal-speaker = {
+ name = "alsa_output.pci-0000_06_00.6.analog-stereo";
+ icon = "";
+ icon-muted = "";
+ };
+ };
+
+ display = {
+ external-only = "";
+ internal-aptop = "";
+ extended = "";
+ };
+
+ modules = {
+ cpu = {
+ format = "{usage}% ";
+ };
+
+ temperature = {
+ thermal-zone = 2;
+ critical-threshold = 80;
+ format = "{icon} {temperatureC}°C";
+ format-icons = ["" "" "" "" ""];
+ };
+
+ # FIXME: Does not work with ZFS
+ disk = {
+ interval = 30;
+ format = " {percentage_used}%";
+ path = "/";
+ tooltip = true;
+ unit = "GB";
+ tooltip-format = "Available {free} of {total}";
+ };
+
+ memory = {
+ interval = 30;
+ format = " {usage}%";
+ max-length = 10;
+ tooltip = true;
+ tooltip-format = " {used:0.1f}GB/{total:0.1f}GB";
+ };
+
+ # FIXME: mkIf laptop
+ battery = {
+ states = {
+ good = 95;
+ warning = 30;
+ critical = 20;
+ };
+ format = "{icon} {capacity}%";
+ format-charging = " {capacity}%";
+ format-plugged = " {capacity}%";
+ format-alt = "{time} {icon}";
+ format-icons = [ "" "" "" "" "" ];
+ format-time = "{H}h {M}min";
+ # on-click = "${lib.getExe pkgs.wlogout} &"; FIXME
+ };
+
+ # FIXME: mkIf laptop
+ backlight = {
+ format = "{icon} {percent}%";
+ format-icons = ["" "" "" "" "" "" "" "" ""];
+ on-scroll-up = "${lib.getExe self.pkgs.osd-brightness} increase";
+ on-scroll-down ="${lib.getExe self.pkgs.osd-brightness} decrease";
+ min-length = 6;
+ # "on-click": "wdisplays"
+ };
+
+ # FIXME: mkIf laptop
+ power-profiles-daemon = {
+ format = "{icon}";
+ tooltip-format = "{profile}";
+ tooltip = true;
+ format-icons = {
+ default = "";
+ performance = "";
+ balanced = "";
+ power-saver = "";
+ };
+ min-length = 6;
+ };
+
+ "custom/os" = {
+ format = "";
+ on-click = "${lib.getExe pkgs.fuzzel}";
+ };
+
+ "niri/language" = {
+ format-en = " US";
+ format-pt = " PT";
+ on-click-release = "${lib.getExe pkgs.niri} msg action switch-layout next";
+ };
+
+ "custom/media" = {
+ format = "{icon} {}";
+ escape = true;
+ return-type = "json";
+ max-length = 40;
+ on-click = "playerctl play-pause";
+ on-click-right = "playerctl stop";
+ smooth-scrolling-threshold = 10;
+ on-scroll-up = "playerctl next";
+ on-scroll-down = "playerctl previous";
+ };
+
+ network = {
+ format-wifi = " {icon}";
+ format-ethernet = " ";
+ format-disconnected = "";
+ format-icons = [ " " " " " " " " " " ];
+ tooltip = true;
+ tooltip-format = ''
+ IP: {ipaddr}/{cidr}
+ Gateway: {gwaddr}'';
+
+ on-click = "${config.xdg.configHome}/rofi/rofi-wifi-menu"; # FIXME
+ on-click-right = "nmtui"; #FIXME
+ };
+
+ clock = {
+ format = "{:%a %d %b %H:%M}";
+ interval = 10;
+ tooltip-format = "{calendar}";
+ calendar = {
+ mode = "year";
+ mode-mon-col = 3;
+ weeks-pos = "right" ;
+ on-scroll = 1;
+ on-click-right = "mode";
+ format = {
+ months = "{}";
+ days = "{}";
+ weeks = "W{}";
+ weekdays = "{}";
+ today = "{}";
+ };
+ };
+ actions = {
+ on-click-right = "mode";
+ on-click-forward = "tz_up";
+ on-click-backward = "tz_down";
+ on-scroll-up = "shift_up";
+ on-scroll-down = "shift_down";
+ };
+ };
+
+ tray = {
+ icon-size = 18;
+ spacing = 10;
+ };
+
+ # See more: https://github.com/prasanthrangan/hyprdots/blob/main/Configs/.config/waybar/modules/pulseaudio.jsonc
+ pulseaudio = {
+ format = "{icon} {volume}%";
+ format-bluetooth = "{icon}";
+ format-bluetooth-muted = " {icon}";
+ format-source = " {volume}%";
+ format-source-muted = " ";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = ["" "" ""];
+
+ "${audio.headset.name}" = audio.headset.icon;
+ "${audio.headset.name}-muted" = audio.headset.icon-muted;
+ "${audio.external-speaker.name}" = audio.external-speaker.icon;
+ "${audio.external-speaker.name}-muted" = audio.external-speaker.icon-muted;
+ "${audio.internal-speaker.name}" = audio.internal-speaker.icon;
+ "${audio.internal-speaker.name}-muted" = audio.internal-speaker.icon-muted;
+ };
+ on-click = "${lib.getExe pkgs.pavucontrol}";
+ #on-right-click = "${lib.getExe self.pkgs.dunst-volume} set alsa_output.usb-SteelSeries_SteelSeries_Arctis_7-00.stereo-game";
+
+ on-scroll-up = "${lib.getExe self.pkgs.osd-volume} increase";
+ on-scroll-down ="${lib.getExe self.pkgs.osd-volume} decrease";
+
+ tooltip = true;
+ tooltip-format = "{desc}";
+ };
+ };
+
+ groups = {
+ "group/stats" = {
+ orientation = "inherit";
+ modules = [ "disk" "memory" "cpu" "temperature" ];
+ };
+ "group/toggles" = {
+ orientation = "inherit";
+ modules = [ "niri/language" "power-profiles-daemon" "pulseaudio" "network" "battery" ];
+ };
+ };
+in
+{
+ programs.waybar = {
+ enable = true;
+ systemd.enable = false; # Run manually as it seems flaky: https://github.com/nix-community/home-manager/issues/3599
+ style = ./style.css; # Not using pkgs.writeText as having the file is handy to debug: waybar -s style.css
+ settings = {
+ default = lib.attrsets.mergeAttrsList [
+ modules
+ groups
+ {
+ reload_style_on_change = true;
+
+ layer = "top";
+ position = "top";
+ margin-left = 5;
+ margin-right = 5;
+ margin-top = 5;
+ margin-bottom = 0;
+ spacing = 5;
+
+ modules-left = [ "custom/os" ];
+ modules-center = [ "custom/media" ];
+ modules-right = [ "group/toggles" "clock" ];
+ }
+ ];
+ };
+ };
+}
diff --git a/home-manager/desktop-environment/waybar/style.css b/home-manager/desktop-environment/waybar/style.css
new file mode 100644
index 00000000..f61369d3
--- /dev/null
+++ b/home-manager/desktop-environment/waybar/style.css
@@ -0,0 +1,43 @@
+@define-color text white;
+
+* {
+ border: none;
+ border-radius: 0;
+ font-family: "Ubuntu Nerd Font";
+ font-size: 15px;
+ min-height: 0;
+}
+
+#waybar {
+ background: transparent;
+ color: @text;
+}
+
+#toggles,
+#clock,
+#custom-os {
+ padding: 0.4rem 0.7rem;
+ border-radius: 6px;
+ background: rgba(30, 30, 46, 0.75);
+}
+
+#power-profiles-daemon,
+#pulseaudio,
+#network,
+#keyboard,
+#battery
+{
+ margin-left: 0.7rem;
+ margin-right: 0.7rem;
+}
+
+#keyboard {
+ margin-left: 0px;
+}
+#battery {
+ margin-right: 0px;
+}
+#power-profiles-daemon {
+ margin-left: -5px;
+ margin-right: -5px;
+}
\ No newline at end of file
diff --git a/home-manager/desktop/beets.nix b/home-manager/desktop/beets.nix
new file mode 100644
index 00000000..c0b13dc8
--- /dev/null
+++ b/home-manager/desktop/beets.nix
@@ -0,0 +1,78 @@
+{ pkgs, lib, config, ... }:
+let
+ inherit (lib) foldl';
+
+ musicLibrary = "${config.xdg.userDirs.music}/library";
+ playlistsDirectory = "${config.xdg.userDirs.music}/playlists";
+
+ # Beets require absolute paths: https://github.com/beetbox/beets/issues/133
+ # If needed:
+ # 1. Find the base path in the db: beet list -f '$path' artist:beatles | head -n 1
+ # 2. Manually update the database:
+ # sqlite3 $XDG_DATA_HOME/beets/library.db "UPDATE items SET path = replace(path, '/home/bphenriques/Music/Library', '/home/bphenriques/music/library');"
+ # sqlite3 $XDG_DATA_HOME/beets/library.db "UPDATE albums SET artpath = replace(artpath, '/home/bphenriques/Music/Library', '/home/bphenriques/music/library');"
+ #
+ # 3. Confirm if everything is alright. The following command should not hint that files should be deleted.
+ # beets update -p
+ database = "${config.xdg.dataHome}/beets/library.db";
+ databaseBackup = "${config.xdg.userDirs.music}/beets.db.backup";
+
+ # Healthcheck: beet bad && beet duplicates
+ # Update files: beet fetchart && beet fingerprint && beet embedart && beet scrub
+ # Docs: https://beets.readthedocs.io/en/stable/plugins/index.html
+ plugins = let
+ providers = [ "chroma" "spotify" "deezer" ];
+ metadata = [ "fetchart" "embedart" "lyrics" "mbsync" ]; # lastgenre
+ health = [ "duplicates" "badfiles" ];
+ utility = [ "edit" "playlist" "scrub" "fish" ]; # https://beets.readthedocs.io/en/stable/plugins/smartplaylist.html
+ in (providers ++ health ++ metadata ++ utility);
+ basePackage = pkgs.beets-unstable.override {
+ # Reference: https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/audio/beets/builtin-plugins.nix
+ pluginOverrides = foldl' (acc: plugin: acc // { "${plugin}".enable = true; }) { } plugins;
+ };
+
+ # Sanity check + backup database file to NAS. Can't store the DB file in the NAS as it leads to lock issues.
+ finalPackage = (pkgs.writeScriptBin "beet" ''
+ #!${pkgs.stdenv.shell}
+ if [ ! -d "${musicLibrary}" ]; then
+ echo "${musicLibrary} does not exist!"
+ exit 1
+ fi
+
+ ${lib.getExe basePackage} "$@"
+ status=$?
+ if [ $status -eq 0 ] && [ -f "${database}" ] && ([ ! -f "${databaseBackup}" ] || [[ "$(md5sum "${databaseBackup}")" = "$(md5sum "${database}")" ]]); then
+ echo "Backing up beets library: ${database}"
+ cp -f "${database}" "${databaseBackup}"
+ fi
+ exit $status
+ '');
+in
+{
+ programs.beets = {
+ enable = pkgs.stdenv.isLinux;
+ package = finalPackage;
+ settings = {
+ library = database;
+ directory = musicLibrary;
+ paths = {
+ default = "$albumartist/$album%aunique{}/$track $title";
+ singleton = "$artist/Non-Album/$title";
+ comp = "Compilations/$album%aunique{}/$track $title";
+ };
+ plugins = builtins.concatStringsSep " " plugins;
+ playlist = {
+ auto = true; # Automatically remove/move items inside the playlists in case they move.
+ relative_to = musicLibrary;
+ playlist_dir = playlistsDirectory;
+ };
+ fetchart = {
+ auto = true;
+ cautious = true;
+ };
+ musicbrainz = {
+ extra_tags = ["date" "year" "originalyear" "originalartist" "originalalbum" "artists"];
+ };
+ };
+ };
+}
diff --git a/home-manager/desktop/default.nix b/home-manager/desktop/default.nix
new file mode 100644
index 00000000..51c4d4ab
--- /dev/null
+++ b/home-manager/desktop/default.nix
@@ -0,0 +1,39 @@
+{ pkgs, lib, config, ... }:
+{
+ imports = [
+ ./firefox # Browser
+ ./zathura.nix # Documents
+ ./mpv.nix # Videos
+ ./imv.nix # Images
+ ./logseq # Notes
+ ./beets.nix # Music library manager
+ ./discord.nix # Social
+ ./ghostty.nix # Terminal applicaton
+ ./mangohud.nix # Game HUD
+ ./retroarch.nix # Emulation
+ ./heroic.nix # Game launcher
+ ];
+
+ home.packages = lib.optionals pkgs.stdenv.isLinux [
+ # Internet
+ pkgs.qbittorrent # Torrent client
+ pkgs.filezilla # Access files remotely
+
+ # Media
+ pkgs.newsflash # RSS Reader
+ pkgs.feishin # Jellyfin player
+ pkgs.cmus # TUI music player
+
+ # Development
+ pkgs.jetbrains.idea-community
+
+ # System
+ pkgs.baobab # Disk space analyzer
+ ];
+
+ # TODO
+ custom.xdgDefaultApps = {
+ archive = lib.mkBefore [ "org.kde.ark.desktop" ];
+ fileBrowser = lib.mkBefore [ "org.gnome.baobab.desktop" ];
+ };
+}
diff --git a/home-manager/desktop/discord.nix b/home-manager/desktop/discord.nix
new file mode 100644
index 00000000..5887d3e2
--- /dev/null
+++ b/home-manager/desktop/discord.nix
@@ -0,0 +1,5 @@
+{ lib, pkgs, ... }:
+lib.mkIf pkgs.stdenv.isLinux {
+ home.packages = [ pkgs.vesktop ]; # Lightweight discord
+ xdg.mimeApps.defaultApplications."x-scheme-handler/discord" = [ "vesktop.desktop" ];
+}
\ No newline at end of file
diff --git a/config/home-manager/internet/firefox/basic.nix b/home-manager/desktop/firefox/basic.nix
similarity index 100%
rename from config/home-manager/internet/firefox/basic.nix
rename to home-manager/desktop/firefox/basic.nix
diff --git a/config/home-manager/internet/firefox/default.nix b/home-manager/desktop/firefox/default.nix
similarity index 100%
rename from config/home-manager/internet/firefox/default.nix
rename to home-manager/desktop/firefox/default.nix
diff --git a/config/home-manager/internet/firefox/telemetry.nix b/home-manager/desktop/firefox/telemetry.nix
similarity index 100%
rename from config/home-manager/internet/firefox/telemetry.nix
rename to home-manager/desktop/firefox/telemetry.nix
diff --git a/config/home-manager/terminal/ghostty.nix b/home-manager/desktop/ghostty.nix
similarity index 77%
rename from config/home-manager/terminal/ghostty.nix
rename to home-manager/desktop/ghostty.nix
index 476504fc..0e56e110 100644
--- a/config/home-manager/terminal/ghostty.nix
+++ b/home-manager/desktop/ghostty.nix
@@ -1,5 +1,6 @@
{ config, pkgs, lib, community, ... }:
+# TODO: https://github.com/nix-community/home-manager/commit/5f6aa268e419d053c3d5025da740e390b12ac936
let
font = {
name = "Hack Nerd Font Mono";
@@ -21,7 +22,7 @@ let
# Red
color1 = "#ff6c6b";
- color9 = "#ff6655";
+ color9 = "#ff6655";#
# Green
color2 = "#98be65";
@@ -49,24 +50,14 @@ let
};
in
{
- # MacOS requires installation by hand for now: https://github.com/ghostty-org/ghostty/releases/tag/tip
home.packages = lib.optionals pkgs.stdenv.isLinux [
- # Fixes issues with GTK, need to sort this out separately
- (pkgs.writeScriptBin "ghostty" ''
- #!${pkgs.stdenv.shell}
- GDK_BACKEND=x11 exec ${community.pkgs.ghostty}/bin/ghostty "$@"
- '')
-
- (pkgs.makeDesktopItem {
- name = "Ghostty";
- desktopName = "Ghostty";
- categories = [ "Utility" "Development" ];
- exec = "GDK_BACKEND=x11 exec ${community.pkgs.ghostty}/bin/ghostty";
- })
+ pkgs.ghostty
];
- xdg.mimeApps.defaultApplications."x-scheme-handler/terminal" = [ "Ghostty.desktop" ];
- xdg.mimeApps.defaultApplications."x-scheme-handler/x-executable" = [ "Ghostty.desktop" ];
+ xdg.mimeApps.defaultApplications = {
+ "x-scheme-handler/terminal" = [ "Ghostty.desktop" ];
+ "x-scheme-handler/x-executable" = [ "Ghostty.desktop" ];
+ };
programs.fish.interactiveShellInit = lib.optionalString pkgs.stdenv.isDarwin ''
fish_add_path --append --move ${config.home.homeDirectory}/Applications/Ghostty.app/Contents/MacOS
@@ -109,7 +100,6 @@ in
palette = 15=${colors.color15}
copy-on-select = clipboard
-
''+ lib.optionalString pkgs.stdenv.isLinux ''
gtk-single-instance = true
window-decoration = true
diff --git a/config/home-manager/gaming/default.nix b/home-manager/desktop/heroic.nix
similarity index 60%
rename from config/home-manager/gaming/default.nix
rename to home-manager/desktop/heroic.nix
index cf1cfb00..a7116ff5 100644
--- a/config/home-manager/gaming/default.nix
+++ b/home-manager/desktop/heroic.nix
@@ -1,7 +1,5 @@
-{ config, lib, pkgs, ... }:
+{ lib, pkgs, ... }:
{
+ home.packages = [ pkgs.heroic ];
xdg.mimeApps.defaultApplications."x-scheme-handler/heroic" = [ "heroic.desktop" ];
-}
-
-
-
+}
\ No newline at end of file
diff --git a/home-manager/desktop/imv.nix b/home-manager/desktop/imv.nix
new file mode 100644
index 00000000..e6fbe645
--- /dev/null
+++ b/home-manager/desktop/imv.nix
@@ -0,0 +1,5 @@
+{ pkgs, lib, config, ... }:
+{
+ programs.imv.enable = pkgs.stdenv.isLinux;
+ custom.xdgDefaultApps.image = lib.mkBefore [ "imv.desktop" ];
+}
diff --git a/config/home-manager/media/notes/logseq/configs.edn b/home-manager/desktop/logseq/configs.edn
similarity index 100%
rename from config/home-manager/media/notes/logseq/configs.edn
rename to home-manager/desktop/logseq/configs.edn
diff --git a/config/home-manager/media/notes/logseq/default.nix b/home-manager/desktop/logseq/default.nix
similarity index 89%
rename from config/home-manager/media/notes/logseq/default.nix
rename to home-manager/desktop/logseq/default.nix
index 0a928abb..ccb4e4e8 100644
--- a/config/home-manager/media/notes/logseq/default.nix
+++ b/home-manager/desktop/logseq/default.nix
@@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }:
let
- basePath = "${config.custom.dotfiles.directory}/home-manager/media/notes/logseq";
+ basePath = "${config.custom.dotfiles.directory}/home-manager/desktop/logseq";
in
{
home.packages = lib.optionals (pkgs.stdenv.isLinux) [ pkgs.logseq ];
diff --git a/config/home-manager/media/notes/logseq/plugins.edn b/home-manager/desktop/logseq/plugins.edn
similarity index 100%
rename from config/home-manager/media/notes/logseq/plugins.edn
rename to home-manager/desktop/logseq/plugins.edn
diff --git a/home-manager/desktop/mangohud.nix b/home-manager/desktop/mangohud.nix
new file mode 100644
index 00000000..e08bad84
--- /dev/null
+++ b/home-manager/desktop/mangohud.nix
@@ -0,0 +1,22 @@
+_: {
+ programs.mangohud = {
+ enable = true;
+ enableSessionWide = true;
+ settings = {
+ no_display = true; # Hide until toggled
+ toggle_hud = "Shift_L+F1";
+ toggle_hud_position = "Shift_L+F2";
+ toggle_logging = "Shift_L+F3";
+
+ cpu_stats = true;
+ cpu_temp = true;
+ gpu_stats = true;
+ gpu_temp = true;
+ ram = true;
+ vram = true;
+ fps = true;
+ frame_timing = false;
+ hud_compact = true;
+ };
+ };
+}
\ No newline at end of file
diff --git a/config/home-manager/media/video.nix b/home-manager/desktop/mpv.nix
similarity index 87%
rename from config/home-manager/media/video.nix
rename to home-manager/desktop/mpv.nix
index 3f23385a..3a3be38d 100644
--- a/config/home-manager/media/video.nix
+++ b/home-manager/desktop/mpv.nix
@@ -1,4 +1,8 @@
-{ pkgs, lib, config, host, ... }:
+{ pkgs, lib, config, ... }:
+# TODO: Check https://github.com/iynaix/dotfiles/blob/f0f8918caed8f4c245fa82fc505ae0de09a32f5c/home-manager/programs/mpv.nix
+# TODO: https://github.com/diniamo/niqs/blob/53288d72902365ee8d3bfdd6aff0ec79eb7c1c36/home/mpv/anime.nix
+# TODO: https://github.com/iynaix/dotfiles/blob/56d2d63b3b5f4c621429d79fb2aef8d44fdc25b9/home-manager/gui/mpv.nix
+# https://github.com/Samillion/ModernZ
let
# Interesting guides:
# - https://kokomins.wordpress.com/2019/10/14/mpv-config-guide/
@@ -95,10 +99,10 @@ in
home.shellAliases = lib.optionalAttrs (pkgs.stdenv.isLinux) {
"mpv360" = "${lib.getExe config.programs.mpv.package} --script-opts=360plugin-enabled=yes";
- } // (lib.optionalAttrs (pkgs.stdenv.isLinux && (host ? webcam)) {
- "webcam" = "${lib.getExe config.programs.mpv.package} --profile=low-latency --untimed -vf=hflip ${host.webcam}";
- });
+ };
- custom.xdgDefaultApps.video = lib.mkBefore [ "mpv.desktop" ];
- custom.xdgDefaultApps.audio = lib.mkBefore [ "mpv.desktop" ];
+ custom.xdgDefaultApps = {
+ video = lib.mkBefore [ "mpv.desktop" ];
+ audio = lib.mkBefore [ "mpv.desktop" ];
+ };
}
diff --git a/home-manager/desktop/retroarch.nix b/home-manager/desktop/retroarch.nix
new file mode 100644
index 00000000..c89bc56e
--- /dev/null
+++ b/home-manager/desktop/retroarch.nix
@@ -0,0 +1,24 @@
+{ lib, pkgs, ... }:
+{
+ # emulationstation # Does not as it needs additional configuration: perhaps FIXME: https://github.com/juliosueiras-nix/nix-emulationstation/blob/master/modules/emulationstation/default.nix?
+ home.packages = [
+ # More cores at: https://github.com/NixOS/nixpkgs/tree/master/pkgs/applications/emulators/libretro/cores
+ # Emulation
+ # Bios in XDG_CONFIG_DIR/retroarch/system
+ (pkgs.retroarch.withCores (cores: with cores; [
+ genesis-plus-gx # Megadrive
+ snes9x # Snes
+ swanstation # PSX
+ mgba # GBA
+ desmume # NDS
+ dosbox-pure # DOS
+ prboom # Doom
+ fbneo # Arcade
+ flycast # Dreamcast
+ gambatte
+ #N64 - Mupen64Plus-Next with Parallel-RDP - Mupen64Plus-Next GLES3 with GlideN64
+ ]))
+ pkgs.mame-tools # Convert to CHD: parallel chdman createcd -i {} -o {.}.chd ::: *.iso
+ pkgs.maxcso # To convert to CSO
+ ];
+}
\ No newline at end of file
diff --git a/config/home-manager/media/documents.nix b/home-manager/desktop/zathura.nix
similarity index 100%
rename from config/home-manager/media/documents.nix
rename to home-manager/desktop/zathura.nix
diff --git a/home-manager/direnv.nix b/home-manager/direnv.nix
new file mode 100644
index 00000000..a67600c5
--- /dev/null
+++ b/home-manager/direnv.nix
@@ -0,0 +1,10 @@
+{ pkgs, lib, config, ... }:
+{
+ # TODO: Interesting for Android dev: https://git.belanyi.fr/ambroisie/nix-config/src/branch/main/modules/home/direnv/lib/android.sh
+ programs.direnv = {
+ enable = true; # Automatically load .envrc or .env.
+ nix-direnv.enable = true; # Faster direnv for nix environments.
+ silent = true; # Disable verbose messages when entering a directory.
+ config.whitelist.prefix = [ config.custom.dotfiles.directory ]; # Surpress prompt in my private dotfiles
+ };
+}
diff --git a/config/home-manager/terminal/fish.nix b/home-manager/fish.nix
similarity index 92%
rename from config/home-manager/terminal/fish.nix
rename to home-manager/fish.nix
index 142f5562..fd27435d 100644
--- a/config/home-manager/terminal/fish.nix
+++ b/home-manager/fish.nix
@@ -42,9 +42,9 @@ in
test -f "$XDG_CONFIG_HOME"/fish/local.fish && source "$XDG_CONFIG_HOME"/fish/local.fish
'';
in concatStringsSep "\n" [
- (optionalString (pkgs.stdenv.system == "aarch64-darwin") nixDarwinIntegration)
+ (optionalString pkgs.stdenv.isDarwin nixDarwinIntegration)
purePrompt
- (optionalString (pkgs.stdenv.system == "aarch64-darwin") darwinHomebrew)
+ (optionalString pkgs.stdenv.isDarwin darwinHomebrew)
extra
];
};
diff --git a/home-manager/fonts.nix b/home-manager/fonts.nix
new file mode 100644
index 00000000..f988bd62
--- /dev/null
+++ b/home-manager/fonts.nix
@@ -0,0 +1,10 @@
+{ pkgs, lib, config, ... }:
+{
+ fonts.fontconfig.enable = true;
+ home.packages = [
+ pkgs.nerd-fonts.hack
+ pkgs.nerd-fonts.jetbrains-mono
+ pkgs.nerd-fonts.fira-mono
+ pkgs.nerd-fonts.fira-code
+ ];
+}
diff --git a/home-manager/fzf.nix b/home-manager/fzf.nix
new file mode 100644
index 00000000..fb5fde35
--- /dev/null
+++ b/home-manager/fzf.nix
@@ -0,0 +1,21 @@
+{ pkgs, lib, config, ... }:
+{
+ custom.programs.fzf-fd.enable = true; # Fuzzy fd
+ custom.programs.fzf-rg.enable = true; # Fuzzy ripgrep
+ programs.fzf = {
+ enable = true;
+ defaultCommand = "${lib.getExe pkgs.fd} --type file --hidden --exclude=.git";
+ enableFishIntegration = true;
+
+ defaultOptions = [
+ "--height='80%'"
+ "--marker='* '"
+ "--pointer='▶'"
+ "--preview-window='right:60%'"
+ "--bind='ctrl-p:toggle-preview'"
+ "--bind='alt-a:select-all'"
+ "--bind='alt-n:deselect-all'"
+ "--bind='ctrl-f:jump'"
+ ];
+ };
+}
diff --git a/config/home-manager/coding/git.nix b/home-manager/git.nix
similarity index 94%
rename from config/home-manager/coding/git.nix
rename to home-manager/git.nix
index edf5c5d1..ffda5348 100644
--- a/config/home-manager/coding/git.nix
+++ b/home-manager/git.nix
@@ -15,8 +15,8 @@ let
in
{
home.packages = with pkgs; [
- lazygit # Cross-platform GUI to interact with Git
- git-absorb # Trying https://github.com/tummychow/git-absorb
+ lazygit # TODO: do I really need this? Cross-platform GUI to interact with Git
+ git-absorb # TODO: try out: https://github.com/tummychow/git-absorb
];
# TODO: Explore jujutsu: https://github.com/0xcharly/nix-config/blob/a8e1427a67494ad5de3d639d94ee619ca69f51c7/users/delay/home.nix#L99
diff --git a/config/home-manager/coding/helix.nix b/home-manager/helix.nix
similarity index 95%
rename from config/home-manager/coding/helix.nix
rename to home-manager/helix.nix
index 1c731bed..17444d64 100644
--- a/config/home-manager/coding/helix.nix
+++ b/home-manager/helix.nix
@@ -11,6 +11,8 @@
nodePackages.bash-language-server # LSP for Bash
nodePackages.yaml-language-server # LSP for YAML
nodePackages.vscode-json-languageserver # LSP for JSON
+ vscode-langservers-extracted # LSP for HTML/CSS/JSON/ESLint
+ typescript-language-server # LSP for Typescript
docker-compose-language-service # LSP for docker-compose
dockerfile-language-server-nodejs # LSP for docker
texlab # LSP for LaTeX
diff --git a/config/home-manager/coding/scala/default.nix b/home-manager/lang-scala.nix
similarity index 54%
rename from config/home-manager/coding/scala/default.nix
rename to home-manager/lang-scala.nix
index 74a37463..4a3fa020 100644
--- a/config/home-manager/coding/scala/default.nix
+++ b/home-manager/lang-scala.nix
@@ -20,7 +20,27 @@
};
# Ammonite is not XDG_CONFIG_HOME compliant: https://github.com/lihaoyi/Ammonite/issues/696
- home.file.".ammonite/predef.sc".source = ./ammonite-predef.sc;
+ home.file.".ammonite/predef.sc".text = ''
+ object load {
+ def fs2Version(version: String): Unit = {
+ repl.load.apply(s"""
+ import $$ivy.`co.fs2::fs2-core:$version`
+ import $$ivy.`co.fs2::fs2-reactive-streams:$version`
+ import $$ivy.`co.fs2::fs2-io:$version`
+
+ import cats.syntax.all._
+ import cats.effect.{IO, Resource}
+ import fs2.io.file.{Files, Path}
+ import fs2.{Stream, text}
+
+ // For unsafeRunSync
+ implicit val runtime = cats.effect.unsafe.IORuntime.global
+ """)
+ }
+
+ def fs2: Unit = fs2Version("3.11.0")
+ }
+ '';
programs.git.ignores = [
".metals"
diff --git a/home-manager/modules/default.nix b/home-manager/modules/default.nix
new file mode 100644
index 00000000..883718ef
--- /dev/null
+++ b/home-manager/modules/default.nix
@@ -0,0 +1,8 @@
+{
+ programs-dotfiles = ./programs/dotfiles.nix;
+ programs-project = ./programs/project.nix;
+ programs-fzf-fd = ./programs/fzf-fd.nix;
+ programs-fzf-rg = ./programs/fzf-rg.nix;
+ programs-swww = ./wayland/swww.nix;
+ xdg-mime-apps = ./xdg-mime-apps.nix;
+}
diff --git a/modules/home-manager/programs/dotfiles.nix b/home-manager/modules/programs/dotfiles.nix
similarity index 100%
rename from modules/home-manager/programs/dotfiles.nix
rename to home-manager/modules/programs/dotfiles.nix
diff --git a/modules/home-manager/programs/fzf-fd.nix b/home-manager/modules/programs/fzf-fd.nix
similarity index 100%
rename from modules/home-manager/programs/fzf-fd.nix
rename to home-manager/modules/programs/fzf-fd.nix
diff --git a/modules/home-manager/programs/fzf-rg.nix b/home-manager/modules/programs/fzf-rg.nix
similarity index 100%
rename from modules/home-manager/programs/fzf-rg.nix
rename to home-manager/modules/programs/fzf-rg.nix
diff --git a/modules/home-manager/programs/project.nix b/home-manager/modules/programs/project.nix
similarity index 100%
rename from modules/home-manager/programs/project.nix
rename to home-manager/modules/programs/project.nix
diff --git a/modules/home-manager/theme.nix b/home-manager/modules/theme.nix
similarity index 100%
rename from modules/home-manager/theme.nix
rename to home-manager/modules/theme.nix
diff --git a/home-manager/modules/wayland/swww.nix b/home-manager/modules/wayland/swww.nix
new file mode 100644
index 00000000..c399f362
--- /dev/null
+++ b/home-manager/modules/wayland/swww.nix
@@ -0,0 +1,31 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.custom.services.swww;
+in
+{
+ options.custom.services.swww = {
+ enable = mkEnableOption ''swww service.'';
+ };
+
+ config = mkIf cfg.enable {
+ systemd.user.services = {
+ swww = {
+ Unit = {
+ Description = "Efficient animated wallpaper daemon for wayland";
+ PartOf = [ "graphical-session.target" ];
+ After = [ "graphical-session.target" ];
+ };
+ Install.WantedBy = [ "graphical-session.target" ];
+ Service = {
+ Type = "simple";
+ ExecStart = ''${pkgs.swww}/bin/swww-daemon'';
+ ExecStop = "${pkgs.swww}/bin/swww kill";
+ Restart = "on-failure";
+ };
+ };
+ };
+ home.packages = [ pkgs.swww ];
+ };
+}
diff --git a/modules/home-manager/xdg-mime-apps.nix b/home-manager/modules/xdg-mime-apps.nix
similarity index 100%
rename from modules/home-manager/xdg-mime-apps.nix
rename to home-manager/modules/xdg-mime-apps.nix
diff --git a/home-manager/ripgrep.nix b/home-manager/ripgrep.nix
new file mode 100644
index 00000000..b4728ddf
--- /dev/null
+++ b/home-manager/ripgrep.nix
@@ -0,0 +1,12 @@
+{ pkgs, lib, config, ... }:
+{
+ programs.ripgrep = {
+ enable = true;
+ arguments = [
+ "--max-columns=150"
+ "--max-columns-preview"
+ "--glob=!.git"
+ "--smart-case"
+ ];
+ };
+}
diff --git a/config/home-manager/terminal/yazi.nix b/home-manager/yazi.nix
similarity index 94%
rename from config/home-manager/terminal/yazi.nix
rename to home-manager/yazi.nix
index 4095867f..96220927 100644
--- a/config/home-manager/terminal/yazi.nix
+++ b/home-manager/yazi.nix
@@ -1,4 +1,4 @@
-{ config, ... }:
+{ config, lib, ... }:
let
downloadDirName = "downloads";
in
@@ -61,4 +61,6 @@ in
require("folder-rules"):setup()
'';
};
+
+ custom.xdgDefaultApps.fileBrowser = lib.mkBefore [ "yazi.desktop" ];
}
diff --git a/hosts/laptop/bphenriques/default.nix b/hosts/laptop/bphenriques/default.nix
index 956173f9..f72e223f 100644
--- a/hosts/laptop/bphenriques/default.nix
+++ b/hosts/laptop/bphenriques/default.nix
@@ -12,4 +12,4 @@
nix.settings.trusted-users = [ "bphenriques" ];
home-manager.users.bphenriques = import ./home.nix;
-}
+}
\ No newline at end of file
diff --git a/hosts/laptop/bphenriques/home.nix b/hosts/laptop/bphenriques/home.nix
index 5a13e094..6e7cc5c8 100644
--- a/hosts/laptop/bphenriques/home.nix
+++ b/hosts/laptop/bphenriques/home.nix
@@ -1,8 +1,9 @@
{ pkgs, config, self, ... }:
{
imports = [
- ../../../config/home-manager
- ../../../config/home-manager/gaming
+ ../../../home-manager
+ ../../../home-manager/desktop-environment
+ ../../../home-manager/desktop
./input-remapper
];
@@ -22,6 +23,8 @@
# https://www.mankier.com/5/tmpfiles.d
systemd.user.tmpfiles.rules = [
# Tidy up most things under $HOME
+ "L ${config.home.homeDirectory}/nas-private - - - - /mnt/nas-bphenriques"
+ "L ${config.home.homeDirectory}/nas-media - - - - /mnt/nas-media"
"L ${config.home.homeDirectory}/games - - - - /mnt/games"
"L ${config.xdg.userDirs.documents} - - - - /mnt/bphenriques"
"L ${config.xdg.userDirs.pictures} - - - - /mnt/nas-bphenriques/photos"
@@ -31,5 +34,20 @@
"d ${config.xdg.userDirs.extraConfig.XDG_SCREENSHOTS_DIR} - - - -"
];
+ gtk.gtk3.bookmarks = [
+ "file://${config.xdg.userDirs.documents}"
+ "file://${config.xdg.userDirs.pictures}"
+ "file://${config.xdg.userDirs.music}"
+ "file://${config.xdg.userDirs.desktop}"
+ "file://${config.xdg.userDirs.download}"
+ "file://${config.xdg.userDirs.extraConfig.XDG_SCREENSHOTS_DIR}"
+
+ # Other
+ "file://${config.home.homeDirectory}/nas-private"
+ "file://${config.home.homeDirectory}/nas-media"
+ "file://${config.home.homeDirectory}/games"
+ "file://${config.home.homeDirectory}/.config Config"
+ ];
+
home.stateVersion = "24.05";
-}
\ No newline at end of file
+}
diff --git a/hosts/laptop/config.nix b/hosts/laptop/config.nix
index 91b55dc3..6b33c50b 100644
--- a/hosts/laptop/config.nix
+++ b/hosts/laptop/config.nix
@@ -1,31 +1,28 @@
{ config, pkgs, lib, self, ... }:
-let
- wallpapers = self.private.wallpapers.override {
- selected = [ "lake-fishing-sunset" "mountains" "whale-sunset" "watch-tower" ];
- };
-in
{
imports = [
- ./hardware # CPU, graphics, peripherals, etc
- ./filesystem # Partitioning, etc
- ../../config/nixos # Default nixos settings
+ ./hardware # CPU, graphics, peripherals, etc
+ ./filesystem # Partitioning, etc
+ ../../nixos # Default nixos settings
+ ../../nixos/desktop-environment # My desktop environment
+ ../../nixos/desktop # The usual desktop applications
# Users
./bphenriques
];
networking.hostName = "bphenriques-laptop";
- networking.interfaces.lo.wakeOnLan.enable = true;
# Boot: See what it is taking most time: `systemd-analyze critical-chain`
boot = {
supportedFilesystems.zfs = true;
- kernelPackages = pkgs.linuxPackages_6_10;
+ kernelPackages = pkgs.linuxPackages_6_12;
+
loader.grub = {
enable = true;
efiSupport = true;
efiInstallAsRemovable = true;
- configurationLimit = 5;
+ configurationLimit = 10;
# I have Windows To Go on a external drive. I turn it off when not in use to reduce wear-and-tear.
# 1. `sudo fdisk -l` to get the device where "EFI System" is.
@@ -52,40 +49,12 @@ in
theme = "angular";
};
- # Desktop environment
- services.xserver.enable = true;
- services.desktopManager.plasma6.enable = true;
- services.displayManager.sddm.wayland.enable = true;
- services.displayManager.defaultSession = "plasma";
- environment.plasma6.excludePackages = with pkgs.kdePackages; [ elisa plasma-browser-integration ];
-
- # Login Screen
- services.displayManager.sddm.enable = true;
- services.displayManager.sddm.theme = "sddm-astronaut-theme";
+ # Login Screen.
environment.systemPackages = [
- # https://github.com/Keyitdev/sddm-astronaut-theme/blob/master/theme.conf
- # It is possible to override the package and set themeConfig. For now, I will iterate like this.
- pkgs.sddm-astronaut
- (pkgs.writeTextDir "share/sddm/themes/sddm-astronaut-theme/theme.conf.user" ''
- [General]
- background=${wallpapers}/share/wallpapers/watch-tower.png
- FullBlur="false"
- PartialBlur="false"
- FormPosition="center"
- '')
-
- (pkgs.writeScriptBin "reboot-to-windows" ''
- #!${pkgs.stdenv.shell}
- sudo grub-reboot "Windows 11" && reboot $@
- '')
- (pkgs.writeScriptBin "reboot-to-bios" ''
- #!${pkgs.stdenv.shell}
- sudo grub-reboot "BIOS Setup" && reboot $@
- '')
+ (pkgs.writeScriptBin "reboot-to-windows" ''sudo grub-reboot "Windows 11" && reboot $@'')
];
# Gaming
- custom.profiles.gaming.enable = true;
custom.proton-run.enable = true;
custom.proton-run.defaultProtonDir = "/mnt/games/GlobalProton";
diff --git a/hosts/laptop/default.nix b/hosts/laptop/default.nix
index ad3c1500..009c9384 100644
--- a/hosts/laptop/default.nix
+++ b/hosts/laptop/default.nix
@@ -1,19 +1,28 @@
-{ self, mylib, nixpkgs, home-manager, sops-nix, disko, nur, ... }:
+{ inputs, mylib, ... }:
let
- inherit (nixpkgs.lib.attrsets) attrValues;
-
- overlays = attrValues self.overlays ++ [ nur.overlay ];
- nixosModules = attrValues self.nixosModules ++ [
- sops-nix.nixosModules.sops
- disko.nixosModules.disko
- home-manager.nixosModules.home-manager
+ inherit (inputs.nixpkgs.lib.attrsets) attrValues;
+ system = "x86_64-linux";
+ # Ideally modules are imported in the file that uses it. However, it leads to a infinite recursion. A rabbit-hole to debug.
+ overlays = attrValues inputs.self.overlays ++ [ inputs.nur.overlay ];
+ nixosModules = attrValues inputs.self.nixosModules ++ [
+ inputs.sops-nix.nixosModules.sops
+ inputs.disko.nixosModules.disko
+ inputs.home-manager.nixosModules.home-manager
];
- hmModules = attrValues self.homeManagerModules;
-in mylib.hosts.mkNixOSHost {
- inherit nixosModules hmModules overlays;
- extraSpecialArgs = {
- host.webcam = "/dev/video0";
+ hmModules = attrValues inputs.self.homeManagerModules;
+ specialArgs = {
+ self = {
+ pkgs = inputs.self.packages.${system};
+ private = inputs.dotfiles-private.packages.${system};
+ };
+ community.pkgs = {
+ firefox-addons = inputs.firefox-addons.packages.${system};
+ };
network-devices = import ../network-devices.nix;
};
+in mylib.hosts.mkNixOSHost {
+ inherit system nixosModules hmModules overlays;
+ nixosSpecialArgs = specialArgs;
+ hmSpecialArgs = specialArgs;
hostModule = ./config.nix;
}
diff --git a/hosts/laptop/filesystem/disko.nix b/hosts/laptop/filesystem/disko.nix
index 35e5bbcb..b0c462b2 100644
--- a/hosts/laptop/filesystem/disko.nix
+++ b/hosts/laptop/filesystem/disko.nix
@@ -1,4 +1,4 @@
-{ lib, ... }:
+{ lib, inputs, ... }:
{
disko.devices = {
disk = {
@@ -56,6 +56,7 @@
rootFsOptions = {
compression = "lz4";
xattr = "sa";
+ acltype = "posixacl";
atime = "off";
};
diff --git a/hosts/laptop/hardware/default.nix b/hosts/laptop/hardware/default.nix
index da0fe190..27a6e1f2 100644
--- a/hosts/laptop/hardware/default.nix
+++ b/hosts/laptop/hardware/default.nix
@@ -18,15 +18,21 @@
services.blueman.enable = true;
# Power
- # AMD has better battery life with PPD over TLP:
- # https://community.frame.work/t/responded-amd-7040-sleep-states/38101/13
+ # AMD has better battery life with PPD over TLP: https://community.frame.work/t/responded-amd-7040-sleep-states/38101/13
services.power-profiles-daemon.enable = true;
services.auto-epp = {
enable = true;
- # Making the default config explicit. See `cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences`
- settings.Settings = {
+ settings.Settings = { # See `cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_available_preferences`
epp_state_for_AC = "balance_performance";
epp_state_for_BAT = "power";
};
};
+ # TODO: Notifications when it is too low
+ services.upower = {
+ enable = true;
+ percentageLow = 30;
+ percentageCritical = 20;
+ percentageAction = 10;
+ criticalPowerAction = "PowerOff";
+ };
}
diff --git a/hosts/laptop/hardware/graphics.nix b/hosts/laptop/hardware/graphics.nix
index 4436057d..b8f834d5 100644
--- a/hosts/laptop/hardware/graphics.nix
+++ b/hosts/laptop/hardware/graphics.nix
@@ -35,5 +35,5 @@
(nvtopPackages.nvidia.override { amd = true; }) # `top` but for GPUs. Very very useful to see which GPU is being used
];
- services.xserver.videoDrivers = [ "nvidia" ];
+ services.xserver.videoDrivers = [ "nvidia" ]; # Load nvidia driver for Xorg and Wayland
}
diff --git a/hosts/laptop/hardware/peripherals.nix b/hosts/laptop/hardware/peripherals.nix
index 11ba38b4..0c5efeb7 100644
--- a/hosts/laptop/hardware/peripherals.nix
+++ b/hosts/laptop/hardware/peripherals.nix
@@ -26,6 +26,11 @@
custom.services.solaar.enable = true;
custom.services.input-remapper.enable = true;
- # Xbox(ish) gamepads
- hardware.xone.enable = true;
+ hardware.xone.enable = true; # Xbox(ish) gamepads
+ hardware.steam-hardware.enable = true; # Steam Hardware. TODO: I likely do not need this.
+
+ # Other
+ environment.systemPackages = [
+ pkgs.cheese # Webcam
+ ];
}
diff --git a/hosts/network-devices.nix b/hosts/network-devices.nix
index c30fe90b..1901b4f9 100644
--- a/hosts/network-devices.nix
+++ b/hosts/network-devices.nix
@@ -2,7 +2,7 @@
{
# Server: Synology
home-nas = {
- hostname = "192.168.68.53";
+ hostname = "192.168.1.87";
ssh.user = "Bruno-Admin";
ssh.port = 6188;
};
diff --git a/hosts/peripherals.nix b/hosts/peripherals.nix
new file mode 100644
index 00000000..37a02e33
--- /dev/null
+++ b/hosts/peripherals.nix
@@ -0,0 +1,19 @@
+{
+ monitors = {
+ # FIXME: This should be insde `laptop`
+ "Samsung Display Corp. 0x4188 Unknown" = {
+ description = "built-in";
+ resolution = "2880x1800";
+ refresh_rate = "120.001";
+ scale = 1.5;
+ };
+ "Dell Inc. DELL S2721DGF 4P11R83" = {
+ name = "Dell Inc. DELL S2721DGF 4P11R83";
+ model = "S2721DGF";
+ description = "Office Monitor";
+ resolution = "2560x1440";
+ refresh_rate = "143.912";
+ scale = 1.0;
+ };
+ };
+}
\ No newline at end of file
diff --git a/hosts/work-macos/brunohenriques.nix b/hosts/work-macos/brunohenriques.nix
index 9ca41480..70fc36b8 100644
--- a/hosts/work-macos/brunohenriques.nix
+++ b/hosts/work-macos/brunohenriques.nix
@@ -11,7 +11,7 @@
kubelogin-oidc
# Infra
- terraform
+ tfswitch
];
custom.programs.project.directory = "${config.home.homeDirectory}/workspace";
diff --git a/hosts/work-macos/config.nix b/hosts/work-macos/config.nix
index 8604589e..0b9f6e5b 100644
--- a/hosts/work-macos/config.nix
+++ b/hosts/work-macos/config.nix
@@ -25,14 +25,15 @@ in
"python3" # Implicit dependency of Aiven client
"kubeseal" # K8s stuff
"go-task"
+ "snyk-cli"
];
casks = [
"bloop" # Scala
- "google-chrome" # Google Meet.
- "slack" # The usual rabbit-hole of channels.
- "1password-cli" # Team's 1password
- "postman" # Because it is more practical than curl
+ "google-chrome"
+ "slack"
+ "1password-cli"
+ "postman"
];
};
diff --git a/hosts/work-macos/default.nix b/hosts/work-macos/default.nix
index d6971137..16cfbc5e 100644
--- a/hosts/work-macos/default.nix
+++ b/hosts/work-macos/default.nix
@@ -1,13 +1,19 @@
-{ self, mylib, nixpkgs, home-manager, ... }:
+{ inputs, mylib, ... }:
let
- inherit (nixpkgs.lib.attrsets) attrValues;
+ inherit (inputs.nixpkgs.lib.attrsets) attrValues;
- darwinModules = attrValues self.darwinModules ++ [ home-manager.darwinModules.home-manager ];
- hmModules = attrValues self.homeManagerModules;
+ darwinModules = attrValues inputs.self.darwinModules ++ [ inputs.home-manager.darwinModules.home-manager ];
+ hmModules = attrValues inputs.self.homeManagerModules;
+ specialArgs = {
+ self = {
+ pkgs = inputs.self.packages.${system};
+ private = inputs.dotfiles-private.packages.${system};
+ };
+ network-devices = import ../network-devices.nix;
+ };
in mylib.hosts.mkMacOSHost {
inherit darwinModules hmModules;
hostModule = ./config.nix;
- extraSpecialArgs = {
- network-devices = import ../network-devices.nix;
- };
+ darwinSpecialArgs = specialArgs;
+ hmSpecialArgs = specialArgs;
}
diff --git a/lib/hosts.nix b/lib/hosts.nix
index 92a8dc36..c4e4e21b 100644
--- a/lib/hosts.nix
+++ b/lib/hosts.nix
@@ -1,9 +1,9 @@
{ lib, inputs, ... }:
let
nixConfig = {
+ optimise.automatic = true;
settings = {
experimental-features = [ "nix-command" "flakes" ]; # Enable nix flakes.
- auto-optimise-store = true; # Optimise the store when building.
use-xdg-base-directories = true; # Hide ~/.nix-profile and ~/.nix-defexpr
warn-dirty = false; # I know...
};
@@ -16,24 +16,11 @@ let
allowUnfree = true; # I was maintaining a list.. because it was _nicer_ and _explicit_ but.. I am lazy.
permittedInsecurePackages = [ "electron-27.3.11" "electron-28.3.3" ];
};
-
- mkExtraArgs = system: extraSpecialArgs: {
- self = {
- pkgs = inputs.self.packages.${system};
- private = inputs.dotfiles-private.packages.${system} // inputs.dotfiles-private.dotfiles-private;
- };
- community.pkgs = {
- ghostty = inputs.ghostty.packages.${system}.default;
- firefox-addons = inputs.firefox-addons.packages.${system};
- };
-
- host = { }; # Intentionally empty, each host sets as required. This just ensures the root config 'host' is available.
- } // extraSpecialArgs;
in
{
- mkNixOSHost = { system ? "x86_64-linux", overlays ? [ ], nixosModules, hmModules, hostModule, extraSpecialArgs ? { } }:
+ mkNixOSHost = { system, overlays ? [ ], nixosModules, hmModules, hostModule, nixosSpecialArgs ? { }, hmSpecialArgs ? { } }:
let
- specialArgs = (mkExtraArgs system extraSpecialArgs);
+ specialArgs = nixosSpecialArgs;
commonConfig = {
nix = nixConfig;
nixpkgs = {
@@ -42,7 +29,7 @@ in
};
home-manager = {
sharedModules = hmModules;
- extraSpecialArgs = specialArgs;
+ extraSpecialArgs = hmSpecialArgs;
};
};
in inputs.nixpkgs.lib.nixosSystem {
@@ -50,9 +37,9 @@ in
modules = nixosModules ++ [ commonConfig hostModule ];
};
- mkMacOSHost = { system ? "aarch64-darwin", overlays ? [ ], darwinModules, hmModules, hostModule, extraSpecialArgs ? { } }:
+ mkMacOSHost = { system ? "aarch64-darwin", overlays ? [ ], darwinModules, hmModules, hostModule, darwinSpecialArgs ? { }, hmSpecialArgs ? { } }:
let
- specialArgs = (mkExtraArgs system extraSpecialArgs);
+ specialArgs = darwinSpecialArgs;
commonConfig = {
nix = nixConfig;
nixpkgs = {
@@ -62,7 +49,7 @@ in
};
home-manager = {
sharedModules = hmModules;
- extraSpecialArgs = specialArgs;
+ extraSpecialArgs = hmSpecialArgs;
};
};
in inputs.darwin.lib.darwinSystem {
diff --git a/modules/home-manager/default.nix b/modules/home-manager/default.nix
deleted file mode 100644
index 51fd803e..00000000
--- a/modules/home-manager/default.nix
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- programs-dotfiles = ./programs/dotfiles.nix;
- programs-project = ./programs/project.nix;
- programs-fzf-fd = ./programs/fzf-fd.nix;
- programs-fzf-rg = ./programs/fzf-rg.nix;
- xdg-mime-apps = ./xdg-mime-apps.nix;
-}
diff --git a/modules/nixos/profiles/emulation.nix b/modules/nixos/profiles/emulation.nix
deleted file mode 100644
index fc42618a..00000000
--- a/modules/nixos/profiles/emulation.nix
+++ /dev/null
@@ -1,39 +0,0 @@
-{ pkgs, config, lib, ... }:
-
-with lib;
-let
- cfg = config.custom.profiles.emulation;
-in
-{
- options.custom.profiles.emulation = with types; {
- enable = mkEnableOption "emulation profile";
- };
-
- config = lib.mkIf cfg.enable {
- environment.systemPackages = with pkgs; [
- # Emulation
- # Bios in XDG_CONFIG_DIR/retroarch/system
- # emulationstation # Does not as it needs additional configuration: perhaps https://github.com/juliosueiras-nix/nix-emulationstation/blob/master/modules/emulationstation/default.nix?
- (retroarch.override { # more: https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/emulators/retroarch/cores.nix
- cores = with libretro; [
- genesis-plus-gx # Megadrive
- snes9x # Snes
- swanstation # PSX
- mgba # GBA
- desmume # NDS
- dosbox-pure # DOS
- prboom # Doom
- fbneo # Most Arcade games
- flycast # Dremcast
- gambatte
- #N64 - Mupen64Plus-Next with Parallel-RDP - Mupen64Plus-Next GLES3 with GlideN64
- # bsnes
- # mesen
- # PPSSPP
- ];
- })
- mame-tools # Convert to CHD: parallel chdman createcd -i {} -o {.}.chd ::: *.iso
- maxcso # To convert to CSO
- ];
- };
-}
diff --git a/modules/nixos/profiles/gaming.nix b/modules/nixos/profiles/gaming.nix
deleted file mode 100644
index ae17c133..00000000
--- a/modules/nixos/profiles/gaming.nix
+++ /dev/null
@@ -1,120 +0,0 @@
-{ pkgs, config, lib, ... }:
-
-with lib;
-let
- cfg = config.custom.profiles.gaming;
- steam-desktop-item = (pkgs.makeDesktopItem {
- name = "steam";
- desktopName = "Steam";
- icon = "steam";
- exec = "${pkgs.steam}/bin/steam";
- terminal = false;
- mimeTypes = [ "x-scheme-handler/steam" ];
- categories = [ "Network" "FileTransfer" "Game" ];
- });
-in
-{
- options.custom.profiles.gaming = with types; {
- enable = mkEnableOption "gaming profile";
- };
-
- config = mkIf cfg.enable {
- # Tweaks
- boot = {
- kernel.sysctl."vm.max_map_count" = "2147483642"; # https://wiki.archlinux.org/title/gaming#Increase_vm.max_map_count
- kernelParams = [ "tsc=reliable" "clocksource=tsc" ]; # https://wiki.archlinux.org/title/gaming#Improve_clock_gettime_throughput
- };
- security.pam.loginLimits = [
- {
- domain = "*";
- type = "hard";
- item = "nofile";
- value = "1048576";
- }
- ];
-
- hardware = {
- graphics.enable = true;
- graphics.enable32Bit = true;
- steam-hardware.enable = true;
- };
-
- programs = {
- steam = {
- enable = true;
- remotePlay.openFirewall = true;
- dedicatedServer.openFirewall = true;
- localNetworkGameTransfers.openFirewall = true;
-
- extraCompatPackages = with pkgs; [
- proton-ge-bin
- ];
- };
-
- # Steam's microcompositor that gives extra scaling features (https://github.com/ValveSoftware/gamescope).
- # - Steam: Right-click game - Properties - Launch options: gamescope -- %command% (example)
- # - Lutris: General Preferences - Enable gamescope
- gamescope.enable = true;
- gamescope.capSysNice = true; # Ensure niceness is lower to increased priority.
-
- # Improve performance (https://github.com/FeralInteractive/gamemode):
- # - Steam: Right-click game - Properties - Launch options: gamemoderun %command%
- # - Lutris: General Preferences - Enable Feral GameMode
- # - Global options - Add Environment Variables: LD_PRELOAD=/nix/store/*-gamemode-*-lib/lib/libgamemodeauto.so
- gamemode.enable = true;
- gamemode.enableRenice = true; # Ensure niceness is lower to increased priority.
- };
-
- services.sunshine = {
- enable = true;
- openFirewall = true;
- capSysAdmin = true;
- applications = {
- env = {
- PATH = "$(PATH):$(HOME)/.local/bin";
- };
- apps = [
- {
- name = "Desktop";
- image-path = "desktop.png";
- }
- {
- name = "Steam Big Picture";
- output = "/tmp/sunlight-steam.txt";
- detached = ["${pkgs.util-linux}/bin/setsid ${pkgs.steam}/bin/steam steam://open/bigpicture"];
- image-path = "steam.png";
- }
- ];
- };
- };
- # Required to simulate input
- services.udev.extraRules = ''
- # Sunshine
- KERNEL=="uinput", SUBSYSTEM=="misc", OPTIONS+="static_node=uinput", TAG+="uaccess"
- '';
-
- environment.systemPackages = with pkgs; [
- steam-desktop-item # Steam desktop item
- heroic # Epic games / GoG
-
- (pkgs.lutris.override {
- extraPkgs = pkgs: [
- pkgs.protobuf # Required for battlenet.
- ] ++ lib.optionals config.services.desktopManager.plasma6.enable [
- pkgs.kdialog # Required for kde
- ];
- })
- ];
- };
-}
-
-# https://github.com/azuwis/nix-config/blob/d29d918097e5da916be5762255fb418c657860bc/nixos/sunshine/home.nix#L17
-# https://github.com/lucasew/nixcfg/blob/90505958b98379ac19d7c952a27bd7bce8714816/nix/nodes/gui-common/sunshine.nix#L9
-# https://github.com/aostanin/nixos-config/blob/c73238deae8538bc6cd0b885f108255e60c60e94/nixos/modules/headless-gaming.nix#L12
-
-# Enable using:
-# services.sunshine.enable = true;
-# Get Service Status
-# systemctl --user status sunshine
-# get logs
-# journalctl --user -u sunshine --since "2 minutes ago"
\ No newline at end of file
diff --git a/nixos/default.nix b/nixos/default.nix
new file mode 100644
index 00000000..a9f515cc
--- /dev/null
+++ b/nixos/default.nix
@@ -0,0 +1,70 @@
+{ pkgs, lib, network-devices, ... }:
+{
+ nix = {
+ settings.auto-optimise-store = true; # Optimise the store when building.
+ gc = {
+ automatic = true;
+ dates = "weekly";
+ options = "--delete-older-than 7d";
+ };
+ };
+
+ home-manager.useGlobalPkgs = true; # Use pkgs set within nixpkgs.
+ home-manager.useUserPackages = true; # Install packages defined in home-manager.
+
+ # Not enabling useTmpfs despite having enough RAM. Might consider it.
+ boot.tmp.cleanOnBoot = true;
+
+ # Network
+ networking = {
+ networkmanager.enable = true;
+ extraHosts = ''
+ ${network-devices.home-nas.hostname} home-nas
+ ${network-devices.pi-zero.hostname} pi-zero
+ ${network-devices.rg353m.hostname} rg353m
+ '';
+ };
+
+ # Localization
+ time.timeZone = "Europe/Lisbon";
+ i18n = {
+ defaultLocale = "en_GB.UTF-8";
+ extraLocaleSettings = {
+ LC_ADDRESS = "pt_PT.UTF-8";
+ LC_IDENTIFICATION = "pt_PT.UTF-8";
+ LC_MEASUREMENT = "pt_PT.UTF-8";
+ LC_MONETARY = "pt_PT.UTF-8";
+ LC_NAME = "pt_PT.UTF-8";
+ LC_NUMERIC = "pt_PT.UTF-8";
+ LC_PAPER = "pt_PT.UTF-8";
+ LC_TELEPHONE = "pt_PT.UTF-8";
+ LC_TIME = "pt_PT.UTF-8";
+ };
+ };
+
+ environment.systemPackages = let
+ filesystems = [ pkgs.exfat pkgs.ntfs3g ]; # Suport exFAT and NTFS formatted drives (pendisks + external disks)
+ hardware = [
+ pkgs.powertop # Check what is consuming too much energy
+ pkgs.usbutils # USB utilities
+ ];
+ in filesystems ++ hardware;
+
+ programs.fish = {
+ enable = true; # System level.
+ vendor.functions.enable = true; # Ensure completions/functions are automatically set.
+ };
+
+ services.fwupd.enable = true; # Updates firmwares: `fwupdmgr`
+
+ # Disabling some defaults
+ programs.command-not-found.enable = false;
+ programs.nano.enable = false;
+
+ # Security
+ services.journald.extraConfig = ''
+ MaxRetentionSec=1month
+ SystemMaxUse=1G
+ '';
+ security.sudo.extraConfig = "Defaults lecture=never";
+}
diff --git a/nixos/desktop-environment/default.nix b/nixos/desktop-environment/default.nix
new file mode 100644
index 00000000..afe2be5c
--- /dev/null
+++ b/nixos/desktop-environment/default.nix
@@ -0,0 +1,39 @@
+{ pkgs, lib, network-devices, ... }:
+{
+ imports = [
+ ./login-manager.nix
+ ./nautilus.nix # File Manager
+ ];
+
+ programs.niri.enable = true;
+ security.pam.services.swaylock = {};
+ services.gnome.gnome-keyring.enable = true;
+ xdg.portal = {
+ enable = true;
+ extraPortals = [
+ pkgs.xdg-desktop-portal-gnome # Required for screencasting
+ ];
+ };
+
+ # Other
+ # TODO: https://github.com/Aylur/dotfiles/blob/main/nixos/system.nix#L44
+ environment.systemPackages = with pkgs; [
+ # Core - Dependencies
+ qt5.qtwayland
+ qt6.qtwayland
+ libnotify
+
+ wl-clipboard # Wayland clipboard
+
+ xwayland-satellite # X11. See: https://github.com/YaLTeR/niri/wiki/Xwayland
+ konsole # Backup terminal in case something goes wrong
+ ark # KDE package: Manage compressed files
+
+ # Personalization
+ morewaita-icon-theme
+ adwaita-icon-theme
+ qogir-icon-theme
+ gnome-calendar
+ gnome-system-monitor
+ ];
+}
diff --git a/nixos/desktop-environment/login-manager.nix b/nixos/desktop-environment/login-manager.nix
new file mode 100644
index 00000000..c4996562
--- /dev/null
+++ b/nixos/desktop-environment/login-manager.nix
@@ -0,0 +1,20 @@
+{ pkgs, config, lib, ... }:
+{
+ services.greetd = let
+ theme = "--theme border=magenta;text=cyan;prompt=green;time=red;action=blue;button=yellow;container=black;input=red";
+ options = ''--user-menu --asterisks --time --greeting "Hi!" --remember --remember-session'';
+ session = {
+ command = ''${lib.getExe pkgs.greetd.tuigreet} ${theme} ${options} --cmd niri-session''; # FIXME: Hardcoded?
+ user = config.users.users.bphenriques.name; # FIXME: Hardcoded?
+ };
+ in {
+ enable = true;
+ settings = {
+ terminal.vt = 1;
+ default_session = session;
+ initial_session = session;
+ };
+ };
+
+ security.pam.services.greetd.enableGnomeKeyring = true; # unlock GPG keyring on login
+}
diff --git a/nixos/desktop-environment/nautilus.nix b/nixos/desktop-environment/nautilus.nix
new file mode 100644
index 00000000..0f9b841b
--- /dev/null
+++ b/nixos/desktop-environment/nautilus.nix
@@ -0,0 +1,7 @@
+{ pkgs, lib, network-devices, ... }:
+{
+ # TODO: https://github.com/ners/trilby/blob/7dd41d0704ebf75f8f705da066184f5ed6168441/modules/home/dconf.nix#L44
+ environment.systemPackages = with pkgs; [ pkgs.nautilus ];
+ services.gnome.sushi.enable = true; # Nautilus: previews
+ services.gvfs.enable = true; # Nautilus: Mount, trash, and other functionalities
+}
diff --git a/nixos/desktop/default.nix b/nixos/desktop/default.nix
new file mode 100644
index 00000000..e619b57a
--- /dev/null
+++ b/nixos/desktop/default.nix
@@ -0,0 +1,29 @@
+{ pkgs, ... }:
+{
+ imports = [
+ ./steam.nix
+ # ./sunshine.nix # TODO: does not work
+ ];
+
+ # Graphics
+ hardware = {
+ graphics.enable = true;
+ graphics.enable32Bit = true;
+ };
+
+ # Audio
+ services.pipewire = {
+ enable = true; # Enable pipewire
+ alsa.enable = true; # Improve compatibility
+ alsa.support32Bit = true; # Improve compatibility
+ pulse.enable = true; # Pulse audio emulation to improve compatibility
+ wireplumber.enable = true; # Audio routing policy
+ };
+ security.rtkit.enable = true; # Recommended for pipewire
+ services.pulseaudio.enable = false; # Disable PulseAudio as pipewire is preferable
+
+ services = {
+ # TODO: https://github.com/ners/trilby/blob/7dd41d0704ebf75f8f705da066184f5ed6168441/modules/home/dconf.nix#L44
+ flatpak.enable = true; # Easier to run some programs. Setup afterwards: flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
+ };
+}
diff --git a/nixos/desktop/steam.nix b/nixos/desktop/steam.nix
new file mode 100644
index 00000000..8472952a
--- /dev/null
+++ b/nixos/desktop/steam.nix
@@ -0,0 +1,62 @@
+{ pkgs, config, lib, ... }:
+
+# TODO: https://github.com/Misterio77/nix-config/blob/main/home/gabriel/features/games/steam.nix
+with lib;
+let
+ steam-desktop-item = (pkgs.makeDesktopItem {
+ name = "steam";
+ desktopName = "Steam";
+ icon = "steam";
+ exec = "${pkgs.steam}/bin/steam";
+ terminal = false;
+ mimeTypes = [ "x-scheme-handler/steam" ];
+ categories = [ "Network" "FileTransfer" "Game" ];
+ });
+in
+{
+ # Tweaks
+ boot = {
+ kernel.sysctl."vm.max_map_count" = "2147483642"; # https://wiki.archlinux.org/title/gaming#Increase_vm.max_map_count
+ kernelParams = [ "tsc=reliable" "clocksource=tsc" ]; # https://wiki.archlinux.org/title/gaming#Improve_clock_gettime_throughput
+ };
+ security.pam.loginLimits = [
+ {
+ domain = "*";
+ type = "hard";
+ item = "nofile";
+ value = "1048576";
+ }
+ ];
+
+ programs = {
+ steam = {
+ enable = true;
+ remotePlay.openFirewall = true;
+ dedicatedServer.openFirewall = true;
+ localNetworkGameTransfers.openFirewall = true;
+
+ extraCompatPackages = with pkgs; [
+ proton-ge-bin
+ ];
+ };
+
+ # Steam's microcompositor that gives extra scaling features (https://github.com/ValveSoftware/gamescope).
+ # - Steam: Right-click game - Properties - Launch options: gamescope -- %command% (example)
+ # - Lutris: General Preferences - Enable gamescope
+ gamescope.enable = true;
+ gamescope.capSysNice = true; # Ensure niceness is lower to increased priority.
+
+ # Improve performance (https://github.com/FeralInteractive/gamemode):
+ # - Steam: Right-click game - Properties - Launch options: gamemoderun %command%
+ # - Lutris: General Preferences - Enable Feral GameMode
+ # - Global options - Add Environment Variables: LD_PRELOAD=/nix/store/*-gamemode-*-lib/lib/libgamemodeauto.so
+ gamemode.enable = true;
+ gamemode.enableRenice = true; # Ensure niceness is lower to increased priority.
+ };
+
+ environment.systemPackages = with pkgs; [
+ steam-desktop-item # Steam desktop item
+ ];
+}
+
+
diff --git a/nixos/desktop/sunshine.nix b/nixos/desktop/sunshine.nix
new file mode 100644
index 00000000..9d45eb67
--- /dev/null
+++ b/nixos/desktop/sunshine.nix
@@ -0,0 +1,40 @@
+{ pkgs, lib, config, ... }:
+{
+ services.sunshine = {
+ enable = true;
+ openFirewall = true;
+ capSysAdmin = true;
+ applications = {
+ env = {
+ PATH = "$(PATH):$(HOME)/.local/bin";
+ };
+ apps = [
+ {
+ name = "Desktop";
+ image-path = "desktop.png";
+ }
+ {
+ name = "Steam Big Picture";
+ output = "/tmp/sunlight-steam.txt";
+ detached = ["${pkgs.util-linux}/bin/setsid ${pkgs.steam}/bin/steam steam://open/bigpicture"];
+ image-path = "steam.png";
+ }
+ ];
+ };
+ };
+ # Required to simulate input in sunshine
+ services.udev.extraRules = lib.optionalString config.services.sunshine.enable ''
+ KERNEL=="uinput", SUBSYSTEM=="misc", OPTIONS+="static_node=uinput", TAG+="uaccess"
+ '';
+}
+
+# https://github.com/azuwis/nix-config/blob/d29d918097e5da916be5762255fb418c657860bc/nixos/sunshine/home.nix#L17
+# https://github.com/lucasew/nixcfg/blob/90505958b98379ac19d7c952a27bd7bce8714816/nix/nodes/gui-common/sunshine.nix#L9
+# https://github.com/aostanin/nixos-config/blob/c73238deae8538bc6cd0b885f108255e60c60e94/nixos/modules/headless-gaming.nix#L12
+
+# Enable using:
+# services.sunshine.enable = true;
+# Get Service Status
+# systemctl --user status sunshine
+# get logs
+# journalctl --user -u sunshine --since "2 minutes ago"
\ No newline at end of file
diff --git a/modules/nixos/default.nix b/nixos/modules/default.nix
similarity index 67%
rename from modules/nixos/default.nix
rename to nixos/modules/default.nix
index 7a8f7407..c15e06d6 100644
--- a/modules/nixos/default.nix
+++ b/nixos/modules/default.nix
@@ -1,7 +1,6 @@
{
+ hardware-ddcci = ./hardware/ddcci.nix;
proton-run = ./programs/proton-run.nix;
- profile-gaming = ./profiles/gaming.nix;
- profile-emulation = ./profiles/emulation.nix;
services-input-remapper-profiles = ./services/input-remapper.nix;
services-solaar = ./services/solaar.nix;
boot-theme = ./system/boot-theme.nix;
diff --git a/nixos/modules/hardware/ddcci.nix b/nixos/modules/hardware/ddcci.nix
new file mode 100644
index 00000000..d75267ec
--- /dev/null
+++ b/nixos/modules/hardware/ddcci.nix
@@ -0,0 +1,48 @@
+{ pkgs, config, lib, self, ... }:
+with lib;
+
+# https://github.com/ejmastnak/ejmastnak.com/blob/40e0d20bceedc75bc2111201976bb30bc421577f/content/tutorials/arch/monitor-hotplug.md
+# https://github.com/sweenu/nixfiles/blob/77a35153c18ccfa9975c8c712fc6640806a4a102/profiles/laptop.nix#L27
+# https://github.com/sweenu/nixfiles/blob/77a35153c18ccfa9975c8c712fc6640806a4a102/profiles/laptop.nix#L27
+# https://github.com/floscr/dotfiles/blob/main/new/modules/services/hotplug.nix#L30
+# https://discourse.nixos.org/t/brightness-control-of-external-monitors-with-ddcci-backlight/8639/17
+# https://discourse.nixos.org/t/ddcci-kernel-driver/22186/7
+let
+ cfg = config.custom.hardware.ddcci;
+in {
+ options.custom.hardware.ddcci = with types; {
+ enable = mkEnableOption "Manage external monitors through `/sys/class/backlight/`. User needs to belong to 'i2c' group";
+ };
+
+ # TODO: udev when battery is nearly done
+
+ config = lib.mkIf cfg.enable {
+ hardware.i2c.enable = true;
+ boot.extraModulePackages = [ config.boot.kernelPackages.ddcci-driver ];
+ boot.kernelModules = [ "ddcci" ];
+ #services.udev.extraRules = ''
+ # KERNEL=="card0", SUBSYSTEM=="drm", ACTION=="change", RUN+="${lib.getExe self.pkgs.ddcci-external-screen-hotplug}"
+ #'';
+
+ # TODO: Limitation, does not work when we plug/unplug devices. Works for me.
+ systemd.services."init-ddcci-connected-monitors" = {
+ wantedBy = [ "graphical.service" ];
+ after = [ "graphical.service" ];
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = false;
+ ExecStart = ''${lib.getExe self.pkgs.ddcci-util} init"'';
+ };
+ };
+ # Quick enough that does not justify modelling as a service
+ #systemd.services.graphical.postStart = ''
+ # ${pkgs.kmod}/bin/modprobe -r ddcci && ${pkgs.kmod}/bin/modprobe ddcci
+ #'';
+
+ # Temporary
+ environment.systemPackages = with pkgs; [
+ brightnessctl
+ ddcutil
+ ];
+ };
+}
diff --git a/modules/nixos/programs/proton-run.nix b/nixos/modules/programs/proton-run.nix
similarity index 90%
rename from modules/nixos/programs/proton-run.nix
rename to nixos/modules/programs/proton-run.nix
index 9a4c6afd..f57205b3 100644
--- a/modules/nixos/programs/proton-run.nix
+++ b/nixos/modules/programs/proton-run.nix
@@ -1,4 +1,4 @@
-{ pkgs, config, lib, ... }:
+{ pkgs, config, lib, self, ... }:
with lib;
let
cfg = config.custom.proton-run;
@@ -9,7 +9,7 @@ let
if [ "$#" -gt 0 ]; then
STEAM_COMPAT_DATA_PATH="${cfg.defaultProtonDir}" \
STEAM_COMPAT_CLIENT_INSTALL_PATH="${cfg.defaultProtonDir}" \
- ${pkgs.steam-run}/bin/steam-run ${pkgs.nur.repos.ataraxiasjel.proton-ge}/bin/proton run "$@"
+ ${pkgs.steam-run}/bin/steam-run ${self.pkgs.proton-ge-custom}/bin/proton run "$@"
fi
'';
};
diff --git a/modules/nixos/services/input-remapper.nix b/nixos/modules/services/input-remapper.nix
similarity index 100%
rename from modules/nixos/services/input-remapper.nix
rename to nixos/modules/services/input-remapper.nix
diff --git a/modules/nixos/services/solaar.nix b/nixos/modules/services/solaar.nix
similarity index 100%
rename from modules/nixos/services/solaar.nix
rename to nixos/modules/services/solaar.nix
diff --git a/modules/nixos/system/boot-theme.nix b/nixos/modules/system/boot-theme.nix
similarity index 92%
rename from modules/nixos/system/boot-theme.nix
rename to nixos/modules/system/boot-theme.nix
index 363604b6..5fd3598c 100644
--- a/modules/nixos/system/boot-theme.nix
+++ b/nixos/modules/system/boot-theme.nix
@@ -45,7 +45,8 @@ in
loader.timeout = 0;
loader.grub = lib.mkIf config.boot.loader.grub.enable {
timeoutStyle = "hidden";
- font = "${pkgs.nerdfonts}/share/fonts/truetype/NerdFonts/HackNerdFontMono-Regular.ttf";
+ # FIXME
+ # font = "${pkgs.nerdfonts}/share/fonts/truetype/NerdFonts/HackNerdFontMono-Regular.ttf";
fontSize = 36;
backgroundColor = "#000000";
splashImage = null;
diff --git a/packages/cliphist-dmenu/cliphist-dmenu.sh b/packages/cliphist-dmenu/cliphist-dmenu.sh
new file mode 100644
index 00000000..fdef89db
--- /dev/null
+++ b/packages/cliphist-dmenu/cliphist-dmenu.sh
@@ -0,0 +1,14 @@
+#shellcheck shell=bash
+
+PREVIEW_WIDTH_CHARS=150
+exists_cmd() { command -v "$1" >/dev/null; }
+open_dmenu() {
+ if exists_cmd fuzzel; then
+ fuzzel --dmenu --prompt 'Paste ' --width "${PREVIEW_WIDTH_CHARS}"
+ else
+ echo "No compatible dmenu runner found" >&2;
+ exit 1
+ fi
+}
+
+cliphist -preview-width "${PREVIEW_WIDTH_CHARS}" list | open_dmenu | cliphist decode | wl-copy
diff --git a/packages/cliphist-dmenu/default.nix b/packages/cliphist-dmenu/default.nix
new file mode 100644
index 00000000..82c016f7
--- /dev/null
+++ b/packages/cliphist-dmenu/default.nix
@@ -0,0 +1,6 @@
+{ lib, pkgs, ... }:
+pkgs.writeShellApplication {
+ name = "niri-window-dmenu";
+ runtimeInputs = with pkgs; [ cliphist wl-clipboard ];
+ text = lib.fileContents ./cliphist-dmenu.sh;
+}
\ No newline at end of file
diff --git a/packages/ddcci-util/ddcci-util.sh b/packages/ddcci-util/ddcci-util.sh
new file mode 100644
index 00000000..c1829315
--- /dev/null
+++ b/packages/ddcci-util/ddcci-util.sh
@@ -0,0 +1,29 @@
+#shellcheck shell=bash
+# udev rule that hotplugs display drivers.
+#
+# As documented by the ddcci-driver, we need to reload it everytime a device is (dis)connected.
+# Then, we manually add/remove the device so that it gets exposed under `/sys/class/backlight/`
+#
+# Installation: tied to udev using systemd (https://wiki.archlinux.org/title/Udev#Spawning_long-running_processes)
+
+fatal() { printf '%s\n' "$1" 1>&2; exit 1; }
+backlight_compatible() { ddcutil getvcp 10 --bus="$1"; }
+add_ddcci_device() { echo "Registering i2c device '$1'" && echo ddcci 0x37 | tee "/sys/bus/i2c/devices/$1/new_device"; }
+list_external_i2c_devices() { ddcutil detect | grep -A1 'Display [0-9]' | grep -oP '/dev/.*$' | sed 's|/dev/i2c-||g'; }
+register_backlight_devices() {
+ for i2c_bus in $(list_external_i2c_devices); do
+ if backlight_compatible "${i2c_bus}"; then
+ add_ddcci_device "/i2c-${i2c_bus}"
+ else
+ echo "$i2c_bus does not support backlight according to ddcutil"
+ fi
+ done
+}
+
+case "${1:-}" in
+ init) modprobe -r ddcci && modprobe ddcci && register_backlight_devices ;;
+ list) list_external_i2c_devices ;;
+ register-backlight-devices) register_backlight_devices ;;
+esac
+
+# TODO: maybe I _should_ make this smart and give another name to the backlight device so that it matches the desktop manager output (e.g., model).
\ No newline at end of file
diff --git a/packages/ddcci-util/default.nix b/packages/ddcci-util/default.nix
new file mode 100644
index 00000000..f4967fdc
--- /dev/null
+++ b/packages/ddcci-util/default.nix
@@ -0,0 +1,6 @@
+{ lib, pkgs, ... }:
+pkgs.writeShellApplication {
+ name = "ddcci-util";
+ runtimeInputs = with pkgs; [ kmod ddcutil gnugrep ];
+ text = lib.fileContents ./ddcci-util.sh;
+}
\ No newline at end of file
diff --git a/packages/default.nix b/packages/default.nix
index bc311c73..ca430e0f 100644
--- a/packages/default.nix
+++ b/packages/default.nix
@@ -1,11 +1,40 @@
{ nixpkgs, mylib }:
-mylib.builders.forAllSystems (system:
- let pkgs = nixpkgs.legacyPackages.${system};
- in rec {
- dotfiles = pkgs.callPackage ./dotfiles { };
- preview = pkgs.callPackage ./preview { };
- fzf-rg = pkgs.callPackage ./fzf-rg { };
- fzf-fd = pkgs.callPackage ./fzf-fd { inherit preview; };
- project = pkgs.callPackage ./project { inherit preview; };
- }
+
+let
+ inherit (mylib.builders) forAllSystems forLinuxSystems;
+
+ crossPlatform = forAllSystems (system:
+ let pkgs = nixpkgs.legacyPackages.${system};
+ in rec {
+ dotfiles = pkgs.callPackage ./dotfiles { };
+ preview = pkgs.callPackage ./preview { };
+ fzf-rg = pkgs.callPackage ./fzf-rg { };
+ fzf-fd = pkgs.callPackage ./fzf-fd { inherit preview; };
+ project = pkgs.callPackage ./project { inherit preview; };
+ }
+ );
+
+ linux = forLinuxSystems (system:
+ let pkgs = nixpkgs.legacyPackages.${system};
+ in {
+ osd-volume = pkgs.callPackage ./osd-volume { };
+ osd-brightness = pkgs.callPackage ./osd-brightness { };
+ niri-output-configuration = pkgs.callPackage ./niri-output-configuration { };
+ niri-window-dmenu = pkgs.callPackage ./niri-window-dmenu { };
+ swww-util = pkgs.callPackage ./swww-util { };
+ cliphist-dmenu = pkgs.callPackage ./cliphist-dmenu { };
+ smart-paste = pkgs.callPackage ./smart-paste { };
+ session-dmenu = pkgs.callPackage ./session-dmenu { };
+ ddcci-util = pkgs.callPackage ./ddcci-util { };
+
+ # Move to community namespace
+ proton-ge-custom = pkgs.callPackage ./proton-ge-custom { };
+ sway-audio-idle-inhibit = pkgs.callPackage ./sway-audio-idle-inhibit { };
+ }
+ );
+in forAllSystems (system:
+ nixpkgs.lib.attrsets.mergeAttrsList [
+ crossPlatform.${system}
+ (linux.${system} or { })
+ ]
)
diff --git a/packages/dotfiles/default.nix b/packages/dotfiles/default.nix
index ed543f47..3fd1bcd9 100644
--- a/packages/dotfiles/default.nix
+++ b/packages/dotfiles/default.nix
@@ -5,4 +5,4 @@ let
buildCommand = "${old.buildCommand}\n patchShebangs $out";
});
in
-patchShebangs (pkgs.writeScriptBin "dotfiles" (lib.fileContents ./src/dotfiles.sh))
+patchShebangs (pkgs.writeScriptBin "dotfiles" (lib.fileContents ./dotfiles.sh))
diff --git a/packages/dotfiles/src/dotfiles.sh b/packages/dotfiles/dotfiles.sh
similarity index 100%
rename from packages/dotfiles/src/dotfiles.sh
rename to packages/dotfiles/dotfiles.sh
diff --git a/packages/fzf-fd/default.nix b/packages/fzf-fd/default.nix
index 147a031f..02e10d88 100644
--- a/packages/fzf-fd/default.nix
+++ b/packages/fzf-fd/default.nix
@@ -2,5 +2,5 @@
pkgs.writeShellApplication {
name = "fzf-fd";
runtimeInputs = with pkgs; [ fzf fd preview ];
- text = lib.fileContents ./src/fzf-fd.sh;
+ text = lib.fileContents ./fzf-fd.sh;
}
diff --git a/packages/fzf-fd/src/fzf-fd.sh b/packages/fzf-fd/fzf-fd.sh
similarity index 100%
rename from packages/fzf-fd/src/fzf-fd.sh
rename to packages/fzf-fd/fzf-fd.sh
diff --git a/packages/fzf-rg/default.nix b/packages/fzf-rg/default.nix
index 3a4d9f8f..46f5e8dc 100644
--- a/packages/fzf-rg/default.nix
+++ b/packages/fzf-rg/default.nix
@@ -2,5 +2,5 @@
pkgs.writeShellApplication {
name = "fzf-rg";
runtimeInputs = with pkgs; [ ripgrep fzf ];
- text = lib.fileContents ./src/fzf-rg.sh;
+ text = lib.fileContents ./fzf-rg.sh;
}
diff --git a/packages/fzf-rg/src/fzf-rg.sh b/packages/fzf-rg/fzf-rg.sh
similarity index 100%
rename from packages/fzf-rg/src/fzf-rg.sh
rename to packages/fzf-rg/fzf-rg.sh
diff --git a/packages/media-player/default.nix b/packages/media-player/default.nix
new file mode 100644
index 00000000..2c9a856e
--- /dev/null
+++ b/packages/media-player/default.nix
@@ -0,0 +1,43 @@
+{ lib
+, stdenv
+, wrapGAppsHook
+, gobject-introspection
+, glib
+, playerctl
+, python3
+}:
+
+stdenv.mkDerivation {
+ pname = "waybar-mediaplayer";
+ version = "0.1.0";
+
+ src = lib.sourceFilesBySuffices ./. [ ".py" ];
+
+ nativeBuildInputs = [
+ wrapGAppsHook
+ gobject-introspection
+ ];
+
+ propagatedBuildInputs = [
+ glib
+ playerctl
+ python3.pkgs.pygobject3
+ ];
+
+ strictDeps = false;
+
+ installPhase = ''
+ mkdir -p $out/bin
+ cp $src/mediaplayer.py $out/bin/waybar-mediaplayer.py
+ wrapProgram $out/bin/waybar-mediaplayer.py \
+ --prefix PYTHONPATH : "$PYTHONPATH:$out/${python3.sitePackages}"
+ '';
+
+ meta = with lib; {
+ description = "Generic MediaPlayer for waybar";
+ license = licenses.mit;
+ platforms = platforms.unix;
+ mainProgram = "waybar-mediaplayer.py";
+ homepage = "https://github.com/Alexays/Waybar/blob/master/resources/custom_modules/mediaplayer.py";
+ };
+}
\ No newline at end of file
diff --git a/packages/niri-output-configuration/default.nix b/packages/niri-output-configuration/default.nix
new file mode 100644
index 00000000..87e14c5a
--- /dev/null
+++ b/packages/niri-output-configuration/default.nix
@@ -0,0 +1,6 @@
+{ lib, pkgs, ... }:
+pkgs.writeShellApplication {
+ name = "niri-output-configuration";
+ runtimeInputs = with pkgs; [ niri libnotify ];
+ text = lib.fileContents ./src/niri-output-configuration.sh;
+}
\ No newline at end of file
diff --git a/packages/niri-output-configuration/src/niri-output-configuration.sh b/packages/niri-output-configuration/src/niri-output-configuration.sh
new file mode 100755
index 00000000..34180bab
--- /dev/null
+++ b/packages/niri-output-configuration/src/niri-output-configuration.sh
@@ -0,0 +1,52 @@
+#shellcheck shell=bash
+
+# TODO: Explore with icons: echo -en 'Bananas\0icon\x1f/nix/store/sch5j89n8dzipmsazl302qa87606f9br-papirus-icon-theme-20240501/share/icons/Papirus/symbolic/devices/video-display-symbolic.svg' | fuzzel --dmenu^
+
+# Functions that depend on the window manager
+dmenu() { fuzzel --dmenu --placeholder "Output Configuration" --lines 3; }
+notify() { notify-send "Output Configuration" "$1"; }
+exists_display() { niri msg --json outputs | jq --exit-status --arg DISPLAY "$1" '.[$DISPLAY]' > /dev/null; }
+
+enable_output() { exists_display "$1" && niri msg output "$1" on; } # assert first as niri sets the state once connected
+disable_output() { exists_display "$1" && niri msg output "$1" off; } # assert first as niri sets the state once connected
+enable_single_output() {
+ export -f disable_output exists_display
+ niri msg --json outputs \
+ | jq -r --exit-status --arg DISPLAY "$1" 'keys | .[] | select(. != $DISPLAY)' \
+ | xargs -I{} sh -c 'disable_output {}'
+ enable_output "$1"
+}
+
+# Profile functions
+profile_default_set() { profile_external_set || profile_internal_set; }
+
+profile_internal_name() { echo "Internal display"; }
+profile_internal_valid() { exists_display eDP-1; }
+profile_internal_set() { profile_internal_valid && enable_single_output eDP-1 && profile_internal_name; }
+
+profile_external_name() { echo "External display"; }
+profile_external_valid() { exists_display HDMI-A-1; }
+profile_external_set() { profile_external_valid && enable_single_output HDMI-A-1 && profile_external_name; }
+
+profile_extend_name() { echo "Extend displays"; }
+profile_extend_valid() { exists_display eDP-1 && exists_display HDMI-A-1; }
+profile_extend_set() { profile_extend_valid && enable_output eDP-1 && enable_output HDMI-A-1 && profile_extend_name; }
+
+# shellcheck disable=SC2005
+profile_list() {
+ profile_internal_valid && echo "$(profile_internal_name)"
+ profile_external_valid && echo "$(profile_external_name)"
+ profile_extend_valid && echo "$(profile_extend_name)"
+}
+
+case "${1:-}" in
+ dmenu)
+ case "$(profile_list | dmenu)" in
+ "$(profile_internal_name)") notify "$(profile_internal_set)" ;;
+ "$(profile_external_name)") notify "$(profile_external_set)" ;;
+ "$(profile_extend_name)") notify "$(profile_extend_set)" ;;
+ esac
+ ;;
+ startup) profile_default_set ;;
+ safemode) notify "$(profile_internal_set)" ;;
+esac
\ No newline at end of file
diff --git a/packages/niri-window-dmenu/default.nix b/packages/niri-window-dmenu/default.nix
new file mode 100644
index 00000000..3f290f66
--- /dev/null
+++ b/packages/niri-window-dmenu/default.nix
@@ -0,0 +1,6 @@
+{ lib, pkgs, ... }:
+pkgs.writeShellApplication {
+ name = "niri-window-dmenu";
+ runtimeInputs = with pkgs; [ niri fuzzel jq ];
+ text = lib.fileContents ./niri-window-dmenu.sh;
+}
\ No newline at end of file
diff --git a/packages/niri-window-dmenu/niri-window-dmenu.sh b/packages/niri-window-dmenu/niri-window-dmenu.sh
new file mode 100644
index 00000000..1e324692
--- /dev/null
+++ b/packages/niri-window-dmenu/niri-window-dmenu.sh
@@ -0,0 +1,10 @@
+#shellcheck shell=bash
+windows="$(niri msg --json windows)"
+selection="$(echo "${windows}" \
+ | jq -r '.[] | "\(.app_id) - \(.title)\u0000icon\u001f\(.app_id)"' \
+ | fuzzel --counter --dmenu --index --width 65 --lines "$(echo "$windows" | jq length)"
+)"
+
+if [ "$selection" != -1 ]; then
+ niri msg action focus-window --id "$(echo "${windows}" | jq -c --arg INDEX "$selection" '.[$INDEX | tonumber].id')"
+fi
\ No newline at end of file
diff --git a/packages/osd-brightness/default.nix b/packages/osd-brightness/default.nix
new file mode 100644
index 00000000..e00ba330
--- /dev/null
+++ b/packages/osd-brightness/default.nix
@@ -0,0 +1,17 @@
+{ lib, pkgs, ... }:
+pkgs.writeShellApplication {
+ name = "osd-brightness";
+ runtimeInputs = with pkgs; [ libnotify brightnessctl gnugrep gawk findutils ];
+ text = let
+ iconBasePath = "${pkgs.pkgs.papirus-icon-theme}/share/icons/Papirus-Dark/symbolic/status";
+ in
+ # FIXME: This is not really configurable. Do something else about this.
+ ''
+ OSD_BRIGHTNESS_OFF_ICON="${iconBasePath}/display-brightness-off-symbolic.svg"
+ OSD_BRIGHTNESS_LOW_ICON="${iconBasePath}/display-brightness-low-symbolic.svg"
+ OSD_BRIGHTNESS_MEDIUM_ICON="${iconBasePath}/display-brightness-medium-symbolic.svg"
+ OSD_BRIGHTNESS_HIGH_ICON="${iconBasePath}/display-brightness-high-symbolic.svg"
+
+ ${lib.fileContents ./osd-brightness.sh}
+ '';
+}
\ No newline at end of file
diff --git a/packages/osd-brightness/osd-brightness.sh b/packages/osd-brightness/osd-brightness.sh
new file mode 100755
index 00000000..3fe56642
--- /dev/null
+++ b/packages/osd-brightness/osd-brightness.sh
@@ -0,0 +1,80 @@
+#shellcheck shell=bash
+
+# Issues:
+# - Applying to a class as whole does not work: brightnessctl --machine-readable --class=backlight set 10
+
+OSD_BRIGHTNESS_OFF_ICON="${OSD_BRIGHTNESS_OFF_ICON:-}"
+OSD_BRIGHTNESS_LOW_ICON="${OSD_BRIGHTNESS_LOW_ICON:-}"
+OSD_BRIGHTNESS_MEDIUM_ICON="${OSD_BRIGHTNESS_MEDIUM_ICON:-}"
+OSD_BRIGHTNESS_HIGH_ICON="${OSD_BRIGHTNESS_HIGH_ICON:-}"
+
+MIN_BRIGHTNESS=10 # 0 turns off OLED monitor (internals/external)
+
+# TODO: RGB keyboard if applicable
+
+# ignore 'kbd_backlight'
+default_device() { brightnessctl --machine-readable | awk -F, '{ print $1; }'; }
+list_backlight_devices() { brightnessctl --machine-readable -l | grep ',backlight,' | awk -F, '{ print $1; }'; }
+get_percentage() { brightnessctl --device="${2:-"$(default_device)"}" --machine-readable | awk -F, '{print $4}' | tr -d %; }
+set_brightness() { brightnessctl --device="${2:-"$(default_device)"}" set "$1" ; }
+
+dim() {
+ case ${1:-} in
+ "") list_backlight_devices | xargs -I{} brightnessctl --save --device={} set "$MIN_BRIGHTNESS" ;;
+ *) brightnessctl --save --device="$1" set "$MIN_BRIGHTNESS" ;;
+ esac
+}
+
+restore() {
+ case ${1:-} in
+ "") list_backlight_devices | xargs -I{} brightnessctl --restore --device={} ;;
+ *) brightnessctl --restore --device="$1" ;;
+ esac
+}
+
+notify() {
+ percentage="$1"
+ icon=
+ if [ "$percentage" -eq 0 ]; then
+ icon="$OSD_BRIGHTNESS_OFF_ICON"
+ progress=0
+ elif [ "$percentage" -lt 30 ]; then
+ icon="$OSD_BRIGHTNESS_LOW_ICON"
+ progress="$percentage"
+ elif [ "$percentage" -lt 70 ]; then
+ icon="$OSD_BRIGHTNESS_MEDIUM_ICON"
+ progress="$percentage"
+ else
+ icon="$OSD_BRIGHTNESS_HIGH_ICON"
+ progress="$percentage"
+ fi
+
+ notify-send \
+ --expire-time 1500 \
+ --icon "$icon" \
+ --category "brightness-osd" \
+ --hint string:x-canonical-private-synchronous:brightness \
+ --hint string:x-dunst-stack-tag:brightness \
+ --hint int:value:"$progress" \
+ "Brightness: $progress%"
+}
+
+case "${1:-}" in
+ increase)
+ shift 1
+ delta="+${1:-5}%"
+ device="${2:-"$(default_device)"}"
+ set_brightness "$delta" "$device"
+ notify "$(get_percentage "$device")"
+ ;;
+ decrease)
+ shift 1
+ delta="${1:-5}-%"
+ device="${2:-"$(default_device)"}"
+ set_brightness "$delta" "$device"q
+ notify "$(get_percentage "$device")"
+ ;;
+ dim) shift 1 && dim "${@:-}" ;;
+ restore) shift 1 && restore "${@:-}" ;;
+ list) shift 1 && list_backlight_devices ;;
+esac
\ No newline at end of file
diff --git a/packages/osd-volume/default.nix b/packages/osd-volume/default.nix
new file mode 100644
index 00000000..9f052e39
--- /dev/null
+++ b/packages/osd-volume/default.nix
@@ -0,0 +1,16 @@
+{ lib, pkgs, ... }:
+pkgs.writeShellApplication {
+ name = "osd-volume";
+ runtimeInputs = with pkgs; [ libnotify ponymix ];
+ text = let
+ iconBasePath = "${pkgs.papirus-icon-theme}/share/icons/Papirus-Dark/symbolic/status";
+ in
+ ''
+ OSD_VOLUME_MUTED_ICON="${iconBasePath}/audio-volume-muted-symbolic.svg"
+ OSD_VOLUME_LOW_ICON="${iconBasePath}/audio-volume-low-symbolic.svg"
+ OSD_VOLUME_MEDIUM_ICON="${iconBasePath}/audio-volume-medium-symbolic.svg"
+ OSD_VOLUME_HIGH_ICON="${iconBasePath}/audio-volume-high-symbolic.svg"
+
+ ${lib.fileContents ./osd-volume.sh}
+ '';
+}
\ No newline at end of file
diff --git a/packages/osd-volume/osd-volume.sh b/packages/osd-volume/osd-volume.sh
new file mode 100755
index 00000000..27d0109b
--- /dev/null
+++ b/packages/osd-volume/osd-volume.sh
@@ -0,0 +1,56 @@
+#shellcheck shell=sh
+
+# TODO review: https://askubuntu.com/questions/1267949/how-do-i-automatically-switch-pulseaudio-input-to-headset-upon-connection
+
+OSD_VOLUME_MUTED_ICON="${OSD_VOLUME_MUTED_ICON:-}"
+OSD_VOLUME_LOW_ICON="${OSD_VOLUME_LOW_ICON:-}"
+OSD_VOLUME_MEDIUM_ICON="${OSD_VOLUME_MEDIUM_ICON:-}"
+OSD_VOLUME_HIGH_ICON="${OSD_VOLUME_HIGH_ICON:-}"
+
+get_percentage() { ponymix get-volume; }
+is_muted() { ponymix is-muted; }
+increase() { ponymix increase "$1"; }
+decrease() { ponymix decrease "$1"; }
+mute() { ponymix mute; }
+unmute() { ponymix unmute; }
+toggle_mute() { ponymix toggle; }
+list() { ponymix list; }
+set_default() { ponymix set-default -d "$1"; }
+get_default_sink_name() { ponymix default | grep sink | awk '{print $3; }'; }
+
+notify() {
+ percentage="$(get_percentage)"
+ icon=
+ if is_muted || [ "$percentage" -eq 0 ]; then
+ icon="$OSD_VOLUME_MUTED_ICON"
+ progress=0
+ elif [ "$percentage" -lt 30 ]; then
+ icon="$OSD_VOLUME_LOW_ICON"
+ progress="$percentage"
+ elif [ "$percentage" -lt 70 ]; then
+ icon="$OSD_VOLUME_MEDIUM_ICON"
+ progress="$percentage"
+ else
+ icon="$OSD_VOLUME_HIGH_ICON"
+ progress="$percentage"
+ fi
+
+ notify-send \
+ --expire-time 1500 \
+ --icon "$icon" \
+ --category "volume-osd" \
+ --hint string:x-canonical-private-synchronous:volume \
+ --hint string:x-dunst-stack-tag:volume \
+ --hint int:value:"$progress" \
+ "Volume: $progress%"
+}
+
+case "${1:-}" in
+ mute) mute && notify ;;
+ unmute) unmute && notify ;;
+ toggle-mute) toggle_mute && notify ;;
+ increase) shift 1 && increase "${1:-10}" && notify ;;
+ decrease) shift 1 && decrease "${1:-10}" && notify ;;
+ list) shift 1 && list "$1" ;;
+ set) shift 1 && set_default "$1" ;;
+esac
\ No newline at end of file
diff --git a/packages/proton-ge-custom/default.nix b/packages/proton-ge-custom/default.nix
new file mode 100644
index 00000000..b16491e2
--- /dev/null
+++ b/packages/proton-ge-custom/default.nix
@@ -0,0 +1,35 @@
+{
+ stdenv,
+ lib,
+ fetchurl,
+ nix-update-script,
+}:
+stdenv.mkDerivation rec {
+ pname = "proton-ge-custom";
+ version = "GE-Proton9-22";
+
+ src = fetchurl {
+ url = "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/${version}/${version}.tar.gz";
+ hash = "sha256-BAp+dIfA62T2SBIEQEWsVab2f2oXRKKRLgm5mTGtdo8=";
+ };
+
+ buildCommand = ''
+ runHook preBuild
+
+ mkdir -p $out/bin
+ tar -C $out/bin --strip=1 -x -f $src
+
+ runHook postBuild
+ '';
+
+ passthru.updateScript = nix-update-script { };
+
+ meta = with lib; {
+ description = "Compatibility tool for Steam Play based on Wine and additional components";
+ homepage = "https://github.com/GloriousEggroll/proton-ge-custom";
+ license = licenses.bsd3;
+ platforms = [ "x86_64-linux" ];
+ maintainers = with maintainers; [ bphenriques ];
+ preferLocalBuild = true;
+ };
+}
\ No newline at end of file
diff --git a/packages/rofi-wifi-menu/default.nix b/packages/rofi-wifi-menu/default.nix
new file mode 100644
index 00000000..68e22ac0
--- /dev/null
+++ b/packages/rofi-wifi-menu/default.nix
@@ -0,0 +1,42 @@
+{
+ lib,
+ fetchFromGitHub,
+ stdenvNoCC,
+ makeWrapper,
+ libnotify,
+ networkmanager,
+}:
+stdenvNoCC.mkDerivation {
+ pname = "rofi-wifi-menu";
+ version = "unstable-2023-11-23";
+
+ src = fetchFromGitHub {
+ owner = "ericmurphyxyz";
+ repo = "rofi-wifi-menu";
+ rev = "d6debde6e302f68d8235ced690d12719124ff18e";
+ hash = "sha256-H+vBRdGcSDMKGLHhPB7imV148O8GRTMj1tZ+PLQUVG4=";
+ };
+
+ nativeBuildInputs = [ makeWrapper ];
+
+ postInstall = ''
+ install -D ./rofi-wifi-menu.sh $out/bin/rofi-wifi-menu
+
+ wrapProgram $out/bin/rofi-wifi-menu \
+ --prefix PATH : ${
+ lib.makeBinPath [
+ libnotify
+ networkmanager
+ ]
+ }
+ '';
+
+ meta = {
+ description = "A bash script using nmcli and rofi to make a wifi menu for your favorite window manager";
+ homepage = "https://github.com/ericmurphyxyz/rofi-wifi-menu";
+ license = lib.licenses.unfree; # nix-init did not find a license
+ maintainers = with lib.maintainers; [ iynaix ];
+ mainProgram = "rofi-wifi-menu";
+ platforms = lib.platforms.all;
+ };
+}
\ No newline at end of file
diff --git a/packages/session-dmenu/default.nix b/packages/session-dmenu/default.nix
new file mode 100644
index 00000000..ac3a49ef
--- /dev/null
+++ b/packages/session-dmenu/default.nix
@@ -0,0 +1,6 @@
+{ lib, pkgs, ... }:
+pkgs.writeShellApplication {
+ name = "session-dmenu";
+ runtimeInputs = with pkgs; [ fuzzel ];
+ text = lib.fileContents ./session-dmenu.sh;
+}
\ No newline at end of file
diff --git a/packages/session-dmenu/session-dmenu.sh b/packages/session-dmenu/session-dmenu.sh
new file mode 100644
index 00000000..c244fa7a
--- /dev/null
+++ b/packages/session-dmenu/session-dmenu.sh
@@ -0,0 +1,26 @@
+#shellcheck shell=bash
+exists_cmd() { command -v "$1" >/dev/null; }
+open_dmenu() {
+ if exists_cmd fuzzel; then
+ fuzzel --dmenu
+ else
+ echo "No compatible dmenu runner found" >&2;
+ exit 1
+ fi
+}
+
+options() {
+ echo "Lock"
+ echo "Logout"
+ echo "Reboot"
+ echo "Shutdown"
+ echo "Suspend"
+}
+
+case "$(options | open_dmenu)" in
+ "Lock") blurlock ;;
+ "Logout") loginctl terminate-user "$(whoami)" ;;
+ "Reboot") systemctl reboot ;;
+ "Shutdown") systemctl poweroff ;;
+ "Suspend") systemctl suspend ;;
+esac
\ No newline at end of file
diff --git a/packages/smart-paste/default.nix b/packages/smart-paste/default.nix
new file mode 100644
index 00000000..92d90639
--- /dev/null
+++ b/packages/smart-paste/default.nix
@@ -0,0 +1,11 @@
+{ lib, pkgs, ... }:
+
+with lib;
+pkgs.writeShellApplication {
+ name = "smart-paste";
+ runtimeInputs = with pkgs; [
+ wtype
+ niri
+ ];
+ text = fileContents ./smart-paste.sh;
+}
diff --git a/packages/smart-paste/smart-paste.sh b/packages/smart-paste/smart-paste.sh
new file mode 100644
index 00000000..d22d2e7c
--- /dev/null
+++ b/packages/smart-paste/smart-paste.sh
@@ -0,0 +1,7 @@
+#shellcheck shell=bash
+
+# TODO: too tied to niri. We can check if the binary exists.
+case "$(niri msg --json focused-window | jq -r '.app_id')" in
+ "com.mitchellh.ghostty") wtype -M shift -M ctrl v ;;
+ *) wtype -M ctrl v ;;
+esac
\ No newline at end of file
diff --git a/packages/sway-audio-idle-inhibit/default.nix b/packages/sway-audio-idle-inhibit/default.nix
new file mode 100644
index 00000000..f0b83d8e
--- /dev/null
+++ b/packages/sway-audio-idle-inhibit/default.nix
@@ -0,0 +1,33 @@
+{
+ lib,
+ stdenv,
+ fetchFromGitHub,
+ meson,
+ pkg-config,
+ cmake,
+ ninja,
+ wayland,
+ wayland-scanner,
+ wayland-protocols,
+ pulseaudio,
+}:
+stdenv.mkDerivation rec {
+ pname = "swayaudioidleinhibit";
+ version = "0.1.2";
+
+ src = fetchFromGitHub {
+ owner = "ErikReider";
+ repo = pname;
+ rev = "v${version}";
+ hash = "sha256-6bdIkNosp/mzH5SiyK6Mox/z8kuFk5RLMmcFZ2VIi0g=";
+ };
+
+ nativeBuildInputs = [meson pkg-config cmake ninja wayland-scanner];
+ buildInputs = [wayland-protocols wayland pulseaudio];
+
+ meta = with lib; {
+ description = "Prevents swayidle from sleeping while any application is outputting or receiving audio";
+ homepage = "https://github.com/ErikReider/SwayAudioIdleInhibit";
+ license = licenses.gpl3Only;
+ };
+}
\ No newline at end of file
diff --git a/packages/swww-util/default.nix b/packages/swww-util/default.nix
new file mode 100644
index 00000000..b990676a
--- /dev/null
+++ b/packages/swww-util/default.nix
@@ -0,0 +1,6 @@
+{ lib, pkgs, ... }:
+pkgs.writeShellApplication {
+ name = "swww-util";
+ runtimeInputs = with pkgs; [ swww ];
+ text = lib.fileContents ./swww-util.sh;
+}
\ No newline at end of file
diff --git a/packages/swww-util/swww-util.sh b/packages/swww-util/swww-util.sh
new file mode 100644
index 00000000..22921ac6
--- /dev/null
+++ b/packages/swww-util/swww-util.sh
@@ -0,0 +1,8 @@
+#shellcheck shell=bash
+set_wallpaper() { test -f "$1" && swww img --transition-type none "$1"; }
+random_file() { find "$1" -type f | sort -R | head -1 ; }
+
+case "${1:-}" in
+ random) shift 1 && set_wallpaper "$(random_file "$1")" ;;
+ one) shift 1 && set_wallpaper "$1" ;;
+esac