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