From 46135a1bc4f6aff740c3ae48fbda5e68c14d8a22 Mon Sep 17 00:00:00 2001 From: Senior Matt Date: Sun, 22 Mar 2026 21:30:03 +0500 Subject: [PATCH] first commit --- flake.lock | 234 +++++++ flake.nix | 24 + modules/flake-parts.nix | 4 + modules/home.nix | 19 + modules/hosts/laptop/configuration.nix | 121 ++++ .../hosts/laptop/hardware-configuration.nix | 45 ++ modules/nixos/programs/fastfetch.nix | 67 ++ modules/nixos/programs/gamedev.nix | 16 + modules/nixos/programs/gaming.nix | 7 + modules/nixos/programs/git.nix | 20 + modules/nixos/programs/kitty.nix | 21 + modules/nixos/programs/matugen/matugen.nix | 69 ++ .../programs/matugen/templates/Matugen.colors | 150 ++++ .../programs/matugen/templates/gtk-colors.css | 23 + .../matugen/templates/qtct-colors.conf | 5 + modules/nixos/programs/neovim.nix | 144 ++++ modules/nixos/programs/tmux.nix | 54 ++ modules/nixos/programs/waybar.nix | 185 +++++ modules/nixos/programs/wofi.nix | 12 + modules/nixos/programs/zen-browser.nix | 82 +++ modules/nixos/sessions/config.kdl | 649 ++++++++++++++++++ modules/nixos/sessions/niri.nix | 86 +++ 22 files changed, 2037 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 modules/flake-parts.nix create mode 100644 modules/home.nix create mode 100644 modules/hosts/laptop/configuration.nix create mode 100644 modules/hosts/laptop/hardware-configuration.nix create mode 100644 modules/nixos/programs/fastfetch.nix create mode 100644 modules/nixos/programs/gamedev.nix create mode 100644 modules/nixos/programs/gaming.nix create mode 100644 modules/nixos/programs/git.nix create mode 100644 modules/nixos/programs/kitty.nix create mode 100644 modules/nixos/programs/matugen/matugen.nix create mode 100644 modules/nixos/programs/matugen/templates/Matugen.colors create mode 100644 modules/nixos/programs/matugen/templates/gtk-colors.css create mode 100644 modules/nixos/programs/matugen/templates/qtct-colors.conf create mode 100644 modules/nixos/programs/neovim.nix create mode 100644 modules/nixos/programs/tmux.nix create mode 100644 modules/nixos/programs/waybar.nix create mode 100644 modules/nixos/programs/wofi.nix create mode 100644 modules/nixos/programs/zen-browser.nix create mode 100644 modules/nixos/sessions/config.kdl create mode 100644 modules/nixos/sessions/niri.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..82c1d53 --- /dev/null +++ b/flake.lock @@ -0,0 +1,234 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1751685974, + "narHash": "sha256-NKw96t+BgHIYzHUjkTK95FqYRVKB8DHpVhefWSz/kTw=", + "ref": "refs/heads/main", + "rev": "549f2762aebeff29a2e5ece7a7dc0f955281a1d1", + "revCount": 92, + "type": "git", + "url": "https://git.lix.systems/lix-project/flake-compat.git" + }, + "original": { + "type": "git", + "url": "https://git.lix.systems/lix-project/flake-compat.git" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1772408722, + "narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": [ + "nvf", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1769996383, + "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1773898372, + "narHash": "sha256-PqeDgmyI/Df3/Mv0B81FP/ZC4KuO88YRQF5ZfeFyA4k=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "ecf019baf47df009937b5f8c4604cee10f410a76", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "import-tree": { + "locked": { + "lastModified": 1773693634, + "narHash": "sha256-BtZ2dtkBdSUnFPPFc+n0kcMbgaTxzFNPv2iaO326Ffg=", + "owner": "vic", + "repo": "import-tree", + "rev": "c41e7d58045f9057880b0d85e1152d6a4430dbf1", + "type": "github" + }, + "original": { + "owner": "vic", + "repo": "import-tree", + "type": "github" + } + }, + "mnw": { + "locked": { + "lastModified": 1770419553, + "narHash": "sha256-b1XqsH7AtVf2dXmq2iyRr2NC1yG7skY7Z6N2MpWHlK4=", + "owner": "Gerg-L", + "repo": "mnw", + "rev": "2aaffa8030d0b262176146adbb6b0e6374ce2957", + "type": "github" + }, + "original": { + "owner": "Gerg-L", + "repo": "mnw", + "type": "github" + } + }, + "ndg": { + "inputs": { + "nixpkgs": [ + "nvf", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1768214250, + "narHash": "sha256-hnBZDQWUxJV3KbtvyGW5BKLO/fAwydrxm5WHCWMQTbw=", + "owner": "feel-co", + "repo": "ndg", + "rev": "a6bd3c1ce2668d096e4fdaaa03ad7f03ba1fbca8", + "type": "github" + }, + "original": { + "owner": "feel-co", + "ref": "refs/tags/v2.6.0", + "repo": "ndg", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1773821835, + "narHash": "sha256-TJ3lSQtW0E2JrznGVm8hOQGVpXjJyXY2guAxku2O9A4=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "b40629efe5d6ec48dd1efba650c797ddbd39ace0", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1772328832, + "narHash": "sha256-e+/T/pmEkLP6BHhYjx6GmwP5ivonQQn0bJdH9YrRB+Q=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "c185c7a5e5dd8f9add5b2f8ebeff00888b070742", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nvf": { + "inputs": { + "flake-compat": "flake-compat", + "flake-parts": "flake-parts_2", + "mnw": "mnw", + "ndg": "ndg", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems" + }, + "locked": { + "lastModified": 1773927734, + "narHash": "sha256-hjf4JtCVGXO3/1SznMKKC+qFsIxQcVhZvPpoNuBYdFY=", + "owner": "NotAShelf", + "repo": "nvf", + "rev": "618cbe6aac5e72f1f9dc0d0dde145ee2d452df71", + "type": "github" + }, + "original": { + "owner": "NotAShelf", + "repo": "nvf", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "home-manager": "home-manager", + "import-tree": "import-tree", + "nixpkgs": "nixpkgs", + "nvf": "nvf", + "zen-browser": "zen-browser" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "zen-browser": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1773722260, + "narHash": "sha256-U8MsSiqqYZHR3oKE+cCZ2AJt3b4LcXs+oQuNLipaO78=", + "owner": "youwen5", + "repo": "zen-browser-flake", + "rev": "0e6e43342fb3e9a3439fafa777d8cdf98e4ffc49", + "type": "github" + }, + "original": { + "owner": "youwen5", + "repo": "zen-browser-flake", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..f4c8f09 --- /dev/null +++ b/flake.nix @@ -0,0 +1,24 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; + import-tree.url = "github:vic/import-tree"; + + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + nvf = { + url = "github:NotAShelf/nvf"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + zen-browser = { + url = "github:youwen5/zen-browser-flake"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules); +} diff --git a/modules/flake-parts.nix b/modules/flake-parts.nix new file mode 100644 index 0000000..681a328 --- /dev/null +++ b/modules/flake-parts.nix @@ -0,0 +1,4 @@ +{ inputs, ...}: { + imports = [ inputs.flake-parts.flakeModules.modules ]; + systems = [ "x86_64-linux" ]; +} diff --git a/modules/home.nix b/modules/home.nix new file mode 100644 index 0000000..e53bf66 --- /dev/null +++ b/modules/home.nix @@ -0,0 +1,19 @@ +{ inputs, self, ... }: +{ + flake.nixosModules.home-manager = { + imports = [ + inputs.home-manager.nixosModules.home-manager + ]; + + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + extraSpecialArgs = { inherit inputs self; }; + + users.matthew = { + home.stateVersion = "25.11"; + programs.home-manager.enable = true; + }; + }; + }; +} diff --git a/modules/hosts/laptop/configuration.nix b/modules/hosts/laptop/configuration.nix new file mode 100644 index 0000000..6e2c3a4 --- /dev/null +++ b/modules/hosts/laptop/configuration.nix @@ -0,0 +1,121 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page, on +# https://search.nixos.org/options and in the NixOS manual (`nixos-help`). + +{ inputs, self, ... }: +{ + flake.nixosConfigurations.nixos = inputs.nixpkgs.lib.nixosSystem { + modules = [ self.nixosModules.laptop ]; + }; + + flake.nixosModules.laptop = { pkgs, ... }: { + + # Import NixOS modules. + imports = [ + self.nixosModules.fastfetch + self.nixosModules.gamedev + self.nixosModules.gaming + self.nixosModules.home-manager + self.nixosModules.kitty + self.nixosModules.niri + self.nixosModules.zen-browser + ]; + + # Use the systemd-boot EFI boot loader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Enable flakes. + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + + # Enable store optimization on every rebuild. + nix.settings.auto-optimise-store = true; + + # Enable automatic garbace collection. + nix.gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 7d"; + }; + + networking.hostName = "nixos"; # Define your hostname. + + # Configure network connections interactively with nmcli or nmtui. + networking.networkmanager.enable = true; + + # Set your time zone. + time.timeZone = "Asia/Almaty"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + + # Enable CUPS to print documents. + services.printing.enable = true; + + # Enable bluetooth. + hardware.bluetooth.enable = true; + + # Enable sound. + services.pipewire = { + enable = true; + pulse.enable = true; + }; + + # Enable TLP. + services.tlp = { + enable = true; + settings = { + # Improve performance on battery. + CPU_ENERGY_PERF_POLICY_ON_BAT = "balance_performance"; + PLATFORM_PROFILE_ON_BAT = "performance"; + }; + }; + + # Define a user account. Don't forget to set a password with ‘passwd’. + users.users.matthew = { + isNormalUser = true; + extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. + packages = with pkgs; [ + tree + ]; + }; + + nixpkgs.config.allowUnfree = true; + + # List packages installed in system profile. + # You can use https://search.nixos.org/ to find more packages (and options). + environment.systemPackages = with pkgs; [ + gnome-clocks + kdePackages.okular + krita + obsidian + telegram-desktop + vesktop + ]; + + # List font packages installed in system profile. + fonts.packages = with pkgs; [ + nerd-fonts.jetbrains-mono + ]; + + fileSystems = { + "/".options = [ "compress=zstd" ]; + "/home".options = [ "compress=zstd" ]; + "/nix".options = [ "compress=zstd" "noatime" ]; + }; + + # Mount /dev/nvme0n1p5 data partition. + fileSystems."/mnt/data" = { + device = "/dev/disk/by-uuid/a7614c0a-f5ee-4eab-a431-853affce8a34"; + fsType = "btrfs"; + options = [ + "users" + "nofail" + "exec" + ]; + }; + + system.stateVersion = "25.11"; # Did you read the comment? + }; +} + diff --git a/modules/hosts/laptop/hardware-configuration.nix b/modules/hosts/laptop/hardware-configuration.nix new file mode 100644 index 0000000..aae04bd --- /dev/null +++ b/modules/hosts/laptop/hardware-configuration.nix @@ -0,0 +1,45 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. + +{ + flake.nixosModules.laptop = { config, lib, pkgs, modulesPath, ... }: { + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usbhid" "usb_storage" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/aabb49a2-7563-4851-9e07-5656cd3fe765"; + fsType = "btrfs"; + options = [ "subvol=root" ]; + }; + + fileSystems."/home" = + { device = "/dev/disk/by-uuid/aabb49a2-7563-4851-9e07-5656cd3fe765"; + fsType = "btrfs"; + options = [ "subvol=home" ]; + }; + + fileSystems."/nix" = + { device = "/dev/disk/by-uuid/aabb49a2-7563-4851-9e07-5656cd3fe765"; + fsType = "btrfs"; + options = [ "subvol=nix" ]; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/D1B6-016C"; + fsType = "vfat"; + options = [ "fmask=0022" "dmask=0022" ]; + }; + + swapDevices = [ ]; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + }; +} diff --git a/modules/nixos/programs/fastfetch.nix b/modules/nixos/programs/fastfetch.nix new file mode 100644 index 0000000..9f5f4e4 --- /dev/null +++ b/modules/nixos/programs/fastfetch.nix @@ -0,0 +1,67 @@ +{ + flake.nixosModules.fastfetch = { + home-manager.users.matthew.imports = [ + { + programs.fastfetch = { + enable = true; + settings = { + "$schema" = "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json"; + display = { + size = { + maxPrefix = "MB"; + ndigits = 0; + spaceBeforeUnit = "never"; + }; + freq = { + ndigits = 3; + spaceBeforeUnit = "never"; + }; + }; + modules = [ + "title" + "separator" + "os" + { + type = "kernel"; + format = "{release}"; + } + "uptime" + { + type = "packages"; + combined = true; + } + "shell" + { + type = "display"; + compactTpe = "original"; + key = "Resolution"; + } + "de" + "wm" + "wmtheme" + "theme" + "icons" + "terminal" + { + type = "terminalfont"; + format = "{/name}{-}{/}{name}{?size} {size}{?}"; + } + "cpu" + { + type = "gpu"; + key = "GPU"; + format = "{name}"; + } + { + type = "memory"; + format = "{used} / {total}"; + } + "break" + "colors" + ]; + }; + }; + } + ]; + }; +} diff --git a/modules/nixos/programs/gamedev.nix b/modules/nixos/programs/gamedev.nix new file mode 100644 index 0000000..87cc7b6 --- /dev/null +++ b/modules/nixos/programs/gamedev.nix @@ -0,0 +1,16 @@ +{ self, ... }: +{ + flake.nixosModules.gamedev = { pkgs, ... }: { + imports = [ + self.nixosModules.neovim + self.nixosModules.tmux + self.nixosModules.git + ]; + + environment.systemPackages = with pkgs; [ + # aseprite + dotnet-sdk + godot-mono + ]; + }; +} diff --git a/modules/nixos/programs/gaming.nix b/modules/nixos/programs/gaming.nix new file mode 100644 index 0000000..874413b --- /dev/null +++ b/modules/nixos/programs/gaming.nix @@ -0,0 +1,7 @@ +{ + flake.nixosModules.gaming = { pkgs, ... }: + { + programs.steam.enable = true; + programs.gamescope.enable = true; + }; +} diff --git a/modules/nixos/programs/git.nix b/modules/nixos/programs/git.nix new file mode 100644 index 0000000..6ed4346 --- /dev/null +++ b/modules/nixos/programs/git.nix @@ -0,0 +1,20 @@ +{ + flake.nixosModules.git = { + home-manager.users.matthew.imports = [ + { + programs.git = { + enable = true; + settings = { + user = { + name = "Senior Matt"; + email = "matthew.prakhov@gmail.com"; + }; + core = { + editor = "nvim"; + }; + }; + }; + } + ]; + }; +} diff --git a/modules/nixos/programs/kitty.nix b/modules/nixos/programs/kitty.nix new file mode 100644 index 0000000..1a000cb --- /dev/null +++ b/modules/nixos/programs/kitty.nix @@ -0,0 +1,21 @@ +{ + flake.nixosModules.kitty = { + home-manager.users.matthew.imports = [ + { + programs.kitty = { + enable = true; + font = { + name = "JetBrainsMonoNerdFont"; + size = 13; + }; + settings = { + confirm_os_window_close = 0; + }; + extraConfig = '' + include ~/.cache/wal/colors-kitty.conf + ''; + }; + } + ]; + }; +} diff --git a/modules/nixos/programs/matugen/matugen.nix b/modules/nixos/programs/matugen/matugen.nix new file mode 100644 index 0000000..0f43ce2 --- /dev/null +++ b/modules/nixos/programs/matugen/matugen.nix @@ -0,0 +1,69 @@ +{ + flake.nixosModules.matugen = { pkgs, lib, ... }: + { + home-manager.users.matthew.imports = [ + { + home.packages = with pkgs; [ + matugen + kdePackages.breeze + kdePackages.qt6ct + libsForQt5.qt5ct + ]; + + xdg.configFile = { + "matugen/config.toml".text = /* toml */ '' + [config] + [templates.gtk3] + input_path = '${builtins.toString ./templates/gtk-colors.css}' + output_path = '~/.config/gtk-3.0/colors.css' + + [templates.gtk4] + input_path = '${builtins.toString ./templates/gtk-colors.css}' + output_path = '~/.config/gtk-4.0/colors.css' + + [templates.color-scheme] + input_path = '${builtins.toString ./templates/Matugen.colors}' + output_path = '~/.local/share/color-schemes/Matugen.colors' + + [templates.qt5ct] + input_path = '${builtins.toString ./templates/qtct-colors.conf}' + output_path = '~/.config/qt5ct/colors/matugen.conf' + + [templates.qt6ct] + input_path = '${builtins.toString ./templates/qtct-colors.conf}' + output_path = '~/.config/qt6ct/colors/matugen.conf' + ''; + "kdeglobals".text = '' + [UiSettings] + ColorScheme=Matugen + ''; + }; + + qt = { + enable = true; + platformTheme.name = lib.mkForce "qt6ct"; + + qt5ctSettings = { + Appearance = { + color_scheme_path = "/home/matthew/.config/qt5ct/colors/matugen.conf"; + custom_palette = true; + }; + }; + + qt6ctSettings = { + Appearance = { + color_scheme_path = "/home/matthew/.config/qt5ct/colors/matugen.conf"; + custom_palette = true; + }; + }; + }; + + gtk = { + enable = true; + gtk4.extraCss = "@import 'colors.css';"; + gtk3.extraCss = "@import 'colors.css';"; + }; + } + ]; + }; +} diff --git a/modules/nixos/programs/matugen/templates/Matugen.colors b/modules/nixos/programs/matugen/templates/Matugen.colors new file mode 100644 index 0000000..d5bddc0 --- /dev/null +++ b/modules/nixos/programs/matugen/templates/Matugen.colors @@ -0,0 +1,150 @@ +[ColorEffects:Disabled] +Color={{colors.surface_dim.default.hex}} +ColorAmount=0 +ColorEffect=0 +ContrastAmount=0.65 +ContrastEffect=1 +IntensityAmount=0.1 +IntensityEffect=2 + +[ColorEffects:Inactive] +ChangeSelectionColor=true +Color={{colors.surface_variant.default.hex}} +ColorAmount=0.025 +ColorEffect=2 +ContrastAmount=0.1 +ContrastEffect=2 +Enable=false +IntensityAmount=0 +IntensityEffect=0 + +[Colors:Button] +BackgroundAlternate={{colors.surface_container_low.default.hex}} +BackgroundNormal={{colors.surface_container_high.default.hex}} +DecorationFocus={{colors.primary.default.hex}} +DecorationHover={{colors.primary.default.hex}} +ForegroundActive={{colors.primary.default.hex}} +ForegroundInactive={{colors.on_surface_variant.default.hex}} +ForegroundLink={{colors.secondary.default.hex}} +ForegroundNegative={{colors.error.default.hex}} +ForegroundNeutral={{colors.tertiary.default.hex}} +ForegroundNormal={{colors.on_surface.default.hex}} +ForegroundPositive={{colors.tertiary_fixed.default.hex}} +ForegroundVisited={{colors.on_secondary_container.default.hex}} + +[Colors:Complementary] +BackgroundAlternate={{colors.surface_container_low.default.hex}} +BackgroundNormal={{colors.surface.default.hex}} +DecorationFocus={{colors.primary.default.hex}} +DecorationHover={{colors.primary.default.hex}} +ForegroundActive={{colors.primary.default.hex}} +ForegroundInactive={{colors.on_surface_variant.default.hex}} +ForegroundLink={{colors.secondary.default.hex}} +ForegroundNegative={{colors.error.default.hex}} +ForegroundNeutral={{colors.tertiary.default.hex}} +ForegroundNormal={{colors.on_primary_container.default.hex}} +ForegroundPositive={{colors.tertiary_fixed.default.hex}} +ForegroundVisited={{colors.on_secondary_container.default.hex}} + +[Colors:Header] +BackgroundAlternate={{colors.surface.default.hex}} +BackgroundNormal={{colors.surface_container.default.hex}} +DecorationFocus={{colors.primary.default.hex}} +DecorationHover={{colors.primary.default.hex}} +ForegroundActive={{colors.primary.default.hex}} +ForegroundInactive={{colors.on_surface_variant.default.hex}} +ForegroundLink={{colors.secondary.default.hex}} +ForegroundNegative={{colors.error.default.hex}} +ForegroundNeutral={{colors.tertiary.default.hex}} +ForegroundNormal={{colors.on_surface.default.hex}} +ForegroundPositive={{colors.tertiary_fixed.default.hex}} +ForegroundVisited={{colors.on_secondary_container.default.hex}} + +[Colors:Header][Inactive] +BackgroundAlternate={{colors.surface_container.default.hex}} +BackgroundNormal={{colors.surface.default.hex}} +DecorationFocus={{colors.primary.default.hex}} +DecorationHover={{colors.primary.default.hex}} +ForegroundActive={{colors.primary.default.hex}} +ForegroundInactive={{colors.on_surface_variant.default.hex}} +ForegroundLink={{colors.secondary.default.hex}} +ForegroundNegative={{colors.error.default.hex}} +ForegroundNeutral={{colors.tertiary.default.hex}} +ForegroundNormal={{colors.on_surface.default.hex}} +ForegroundPositive={{colors.tertiary_fixed.default.hex}} +ForegroundVisited={{colors.on_secondary_container.default.hex}} + +[Colors:Selection] +BackgroundAlternate={{colors.surface_container_low.default.hex}} +BackgroundNormal={{colors.primary.default.hex}} +DecorationFocus={{colors.primary.default.hex}} +DecorationHover={{colors.primary.default.hex}} +ForegroundActive={{colors.on_primary.default.hex}} +ForegroundInactive={{colors.on_surface_variant.default.hex}} +ForegroundLink={{colors.secondary_fixed.default.hex}} +ForegroundNegative={{colors.error_container.default.hex}} +ForegroundNeutral={{colors.tertiary_fixed_dim.default.hex}} +ForegroundNormal={{colors.secondary_fixed.default.hex}} +ForegroundPositive={{colors.tertiary_container.default.hex}} +ForegroundVisited={{colors.on_secondary_container.default.hex}} + +[Colors:Tooltip] +BackgroundAlternate={{colors.surface.default.hex}} +BackgroundNormal={{colors.surface_container.default.hex}} +DecorationFocus={{colors.primary.default.hex}} +DecorationHover={{colors.primary.default.hex}} +ForegroundActive={{colors.primary.default.hex}} +ForegroundInactive={{colors.on_surface_variant.default.hex}} +ForegroundLink={{colors.secondary.default.hex}} +ForegroundNegative={{colors.error.default.hex}} +ForegroundNeutral={{colors.tertiary.default.hex}} +ForegroundNormal={{colors.on_background.default.hex}} +ForegroundPositive={{colors.tertiary_fixed.default.hex}} +ForegroundVisited={{colors.on_secondary_container.default.hex}} + +[Colors:View] +BackgroundAlternate={{colors.surface_container.default.hex}} +BackgroundNormal={{colors.background.default.hex}} +DecorationFocus={{colors.primary_container.default.hex}} +DecorationHover={{colors.on_primary.default.hex}} +ForegroundActive={{colors.primary.default.hex}} +ForegroundInactive={{colors.on_surface_variant.default.hex}} +ForegroundLink={{colors.secondary.default.hex}} +ForegroundNegative={{colors.error.default.hex}} +ForegroundNeutral={{colors.tertiary.default.hex}} +ForegroundNormal={{colors.on_background.default.hex}} +ForegroundPositive={{colors.tertiary_fixed.default.hex}} +ForegroundVisited={{colors.on_secondary_container.default.hex}} + +[Colors:Window] +BackgroundAlternate={{colors.primary_container.default.hex}} +BackgroundNormal={{colors.surface_container.default.hex}} +DecorationFocus={{colors.primary.default.hex}} +DecorationHover={{colors.primary.default.hex}} +ForegroundActive={{colors.primary.default.hex}} +ForegroundInactive={{colors.on_surface_variant.default.hex}} +ForegroundLink={{colors.secondary.default.hex}} +ForegroundNegative={{colors.error.default.hex}} +ForegroundNeutral={{colors.tertiary.default.hex}} +ForegroundNormal={{colors.on_background.default.hex}} +ForegroundPositive={{colors.tertiary_fixed.default.hex}} +ForegroundVisited={{colors.on_secondary_container.default.hex}} + +[General] +ColorScheme=Matugen +Name=Matugen + +[Appearance] +color_scheme=Matugen + +[KDE] +contrast=4 + +[WM] +activeBackground={{colors.primary_container.default.hex}} +activeBlend={{colors.on_primary_container.default.hex}} +activeForeground={{colors.on_primary_container.default.hex}} +inactiveBackground={{colors.surface.default.hex}} +inactiveBlend={{colors.on_surface_variant.default.hex}} +inactiveForeground={{colors.on_surface_variant.default.hex}} + diff --git a/modules/nixos/programs/matugen/templates/gtk-colors.css b/modules/nixos/programs/matugen/templates/gtk-colors.css new file mode 100644 index 0000000..64abe77 --- /dev/null +++ b/modules/nixos/programs/matugen/templates/gtk-colors.css @@ -0,0 +1,23 @@ +/* +* GTK Colors +* Generated with Matugen +*/ + +@define-color accent_color {{colors.primary_fixed_dim.default.hex}}; +@define-color accent_fg_color {{colors.on_primary_fixed.default.hex}}; +@define-color accent_bg_color {{colors.primary_fixed_dim.default.hex}}; +@define-color window_bg_color {{colors.surface_dim.default.hex}}; +@define-color window_fg_color {{colors.on_surface.default.hex}}; +@define-color headerbar_bg_color {{colors.surface_dim.default.hex}}; +@define-color headerbar_fg_color {{colors.on_surface.default.hex}}; +@define-color popover_bg_color {{colors.surface_dim.default.hex}}; +@define-color popover_fg_color {{colors.on_surface.default.hex}}; +@define-color view_bg_color {{colors.surface.default.hex}}; +@define-color view_fg_color {{colors.on_surface.default.hex}}; +@define-color card_bg_color {{colors.surface.default.hex}}; +@define-color card_fg_color {{colors.on_surface.default.hex}}; +@define-color sidebar_bg_color @window_bg_color; +@define-color sidebar_fg_color @window_fg_color; +@define-color sidebar_border_color @window_bg_color; +@define-color sidebar_backdrop_color @window_bg_color; + diff --git a/modules/nixos/programs/matugen/templates/qtct-colors.conf b/modules/nixos/programs/matugen/templates/qtct-colors.conf new file mode 100644 index 0000000..5d35cb4 --- /dev/null +++ b/modules/nixos/programs/matugen/templates/qtct-colors.conf @@ -0,0 +1,5 @@ +[ColorScheme] +active_colors={{colors.on_background.default.hex}}, {{colors.surface.default.hex}}, #ffffff, #cacaca, #9f9f9f, #b8b8b8, {{colors.on_background.default.hex}}, #ffffff, {{colors.on_surface.default.hex}}, {{colors.background.default.hex}}, {{colors.background.default.hex}}, {{colors.shadow.default.hex}}, {{colors.primary_container.default.hex}}, {{colors.on_primary_container.default.hex}}, {{colors.secondary.default.hex}}, {{colors.primary.default.hex}}, {{colors.surface.default.hex}}, {{colors.scrim.default.hex}}, {{colors.surface.default.hex}}, {{colors.on_surface.default.hex}}, {{colors.secondary.default.hex}} +disabled_colors={{colors.on_background.default.hex}}, {{colors.surface.default.hex}}, #ffffff, #cacaca, #9f9f9f, #b8b8b8, {{colors.on_background.default.hex}}, #ffffff, {{colors.on_surface.default.hex}}, {{colors.background.default.hex}}, {{colors.background.default.hex}}, {{colors.shadow.default.hex}}, {{colors.primary_container.default.hex}}, {{colors.on_primary_container.default.hex}}, {{colors.secondary.default.hex}}, {{colors.primary.default.hex}}, {{colors.surface.default.hex}}, {{colors.scrim.default.hex}}, {{colors.surface.default.hex}}, {{colors.on_surface.default.hex}}, {{colors.secondary.default.hex}} +inactive_colors={{colors.on_background.default.hex}}, {{colors.surface.default.hex}}, #ffffff, #cacaca, #9f9f9f, #b8b8b8, {{colors.on_background.default.hex}}, #ffffff, {{colors.on_surface.default.hex}}, {{colors.background.default.hex}}, {{colors.background.default.hex}}, {{colors.shadow.default.hex}}, {{colors.primary_container.default.hex}}, {{colors.on_primary_container.default.hex}}, {{colors.secondary.default.hex}}, {{colors.primary.default.hex}}, {{colors.surface.default.hex}}, {{colors.scrim.default.hex}}, {{colors.surface.default.hex}}, {{colors.on_surface.default.hex}}, {{colors.secondary.default.hex}} + diff --git a/modules/nixos/programs/neovim.nix b/modules/nixos/programs/neovim.nix new file mode 100644 index 0000000..0062714 --- /dev/null +++ b/modules/nixos/programs/neovim.nix @@ -0,0 +1,144 @@ +{ inputs, ... }: +{ + flake.nixosModules.neovim = { + home-manager.users.matthew.imports = [ + { + imports = [ inputs.nvf.homeManagerModules.default ]; + + home.sessionVariables = { + MANPAGER = "nvim +Man!"; + }; + + programs.neovim = { + enable = true; + defaultEditor = true; + }; + + programs.nvf = { + enable = true; + settings = { + vim = { + luaConfigPost = '' + vim.opt.shiftwidth = 2 + -- vim.opt.colorcolumn = "80" + ''; + treesitter.indent.enable = false; + + lsp = { + enable = true; + lspconfig.enable = true; + mappings.format = ""; + }; + + languages = { + enableFormat = true; + enableTreesitter = true; + + nix.enable = true; + markdown.enable = true; + bash.enable = true; + lua.enable = true; + css.enable = true; + + csharp = { + enable = true; + lsp = { + enable = true; + servers = [ "roslyn_ls" ]; + }; + treesitter.enable = true; + }; + }; + + visuals = { + nvim-cursorline.enable = true; + }; + + theme = { + enable = true; + name = "gruvbox"; + style = "dark"; + }; + + statusline = { + lualine.enable = true; + }; + + autopairs = { + nvim-autopairs.enable = true; + }; + + autocomplete = { + nvim-cmp.enable = true; + }; + + filetree = { + neo-tree.enable = true; + }; + + tabline = { + nvimBufferline = { + enable = true; + mappings = { + closeCurrent = "x"; + cycleNext = ""; + cyclePrevious = ""; + moveNext = "l"; + movePrevious = "h"; + }; + }; + }; + + telescope.enable = true; + + git = { + enable = true; + }; + + utility = { + ccc.enable = true; + }; + + notes = { + todo-comments.enable = true; + }; + + ui = { + fastaction.enable = true; # Not so sure about it. + }; + + keymaps = [ + { + mode = [ "n" "v" "i" ]; + key = ""; + action = "Neotree toggle left"; + } + + { + mode = "n"; + key = ""; + action = "h"; + } + { + mode = "n"; + key = ""; + action = "j"; + } + { + mode = "n"; + key = ""; + action = "k"; + } + { + mode = "n"; + key = ""; + action = "l"; + } + ]; + }; + }; + }; + } + ]; + }; +} diff --git a/modules/nixos/programs/tmux.nix b/modules/nixos/programs/tmux.nix new file mode 100644 index 0000000..5f2c595 --- /dev/null +++ b/modules/nixos/programs/tmux.nix @@ -0,0 +1,54 @@ +{ + flake.nixosModules.tmux = { pkgs, ... }: { + home-manager.users.matthew.imports = [ + { + programs.tmux = { + enable = true; + mouse = true; + baseIndex = 1; + plugins = with pkgs; [ + { + plugin = tmuxPlugins.resurrect; + extraConfig = "set -g @resurrect-strategy-nvim 'session'"; + } + ]; + extraConfig = '' + unbind -a -T root + bind -n M-r source-file ~/.config/tmux/tmux.conf \; display "Config reloaded" + + bind -n M-s choose-session + + bind -n M-1 select-window -t 1 + bind -n M-2 select-window -t 2 + bind -n M-3 select-window -t 3 + bind -n M-4 select-window -t 4 + bind -n M-5 select-window -t 5 + bind -n M-6 select-window -t 6 + bind -n M-7 select-window -t 7 + bind -n M-8 select-window -t 8 + bind -n M-9 select-window -t 9 + + bind -n M-h select-pane -L + bind -n M-l select-pane -R + bind -n M-k select-pane -U + bind -n M-j select-pane -D + + bind -n M-H resize-pane -L 5 + bind -n M-L resize-pane -R 5 + bind -n M-K resize-pane -U 3 + bind -n M-J resize-pane -D 3 + + bind -n M-u split-window -v + bind -n M-i split-window -h + + bind -n M-t new-window + bind -n M-c kill-pane + bind -n M-q kill-window + bind -n M-w kill-session + bind -n M-d detach + ''; + }; + } + ]; + }; +} diff --git a/modules/nixos/programs/waybar.nix b/modules/nixos/programs/waybar.nix new file mode 100644 index 0000000..857914c --- /dev/null +++ b/modules/nixos/programs/waybar.nix @@ -0,0 +1,185 @@ +{ self, ... }: +{ + flake.nixosModules.waybar = { pkgs, ... }: + { + environment.systemPackages = with pkgs; [ + bluetui + wiremix + ]; + + fonts.packages = with pkgs; [ + font-awesome + ]; + + home-manager.users.matthew.imports = [ + { + programs.waybar = { + enable = true; + settings = { + bar = { + height = 24; + spacing = 4; + modules-left = [ "niri/workspaces" ]; + modules-center = [ "niri/window" ]; + modules-right = [ "niri/language" "tray" "wireplumber" "network" "bluetooth" "power-profiles-daemon" "backlight" "battery" "battery#bat2" "clock" "custom/power" ]; + "niri/workspaces" = { + "disable-scroll" = true; + "all-outputs" = true; + "warp-on-scroll" = false; + "format" = "{icon}"; + }; + "tray" = { + "spacing" = 10; + }; + "clock" = { + "tooltip-format" = "{:%Y %B}\n{calendar}"; + "format-alt" = "{:%Y-%m-%d}"; + }; + "backlight" = { + "format" = "{percent}% {icon}"; + "format-icons" = ["" "" "" "" "" "" "" "" ""]; + }; + "battery" = { + "bat" = "BAT0"; + "states" = { + "good" = 95; + "warning" = 30; + "critical" = 15; + }; + "format" = "{icon} {capacity}%"; + "format-full" = "{icon} {capacity}%"; + "format-charging" = " {capacity}%"; + "format-plugged" = " {capacity}%"; + "format-alt" = "{icon} {time}"; + "format-icons" = ["" "" "" "" ""]; + }; + "battery#bat2" = { + "bat" = "BAT1"; + "states" = { + "good" = 95; + "warning" = 30; + "critical" = 15; + }; + "format" = "{icon} {capacity}%"; + "format-full" = "{icon} {capacity}%"; + "format-charging" = " {capacity}%"; + "format-plugged" = " {capacity}%"; + "format-alt" = "{icon} {time}"; + "format-icons" = ["" "" "" "" ""]; + }; + "power-profiles-daemon" = { + "format" = "{icon}"; + "tooltip-format" = "Power profile: {profile}\nDriver: {driver}"; + "tooltip" = true; + "format-icons" = { + "default" = ""; + "performance" = ""; + "balanced" = ""; + "power-saver" = ""; + }; + }; + "bluetooth" = { + "format" = ""; + "format-off" = "󰂲"; + "on-click" = "kitty --hold sh -c 'bluetui'"; + }; + "network" = { + "format-wifi" = " {essid}"; + "format-disconnected" = "󰖪"; + "on-click" = "kitty --hold sh -c 'nmtui'"; + }; + "wireplumber" = { + "format" = "{icon} {volume}%"; + "format-muted" = " "; + "format-icons" = { + "default" = ["" "" ""]; + }; + "on-click" = "kitty --hold sh -c 'wiremix'"; + }; + "custom/power" = { + "format" = "⏻ "; + "on-click" = "systemctl suspend"; + # "shutdown" = "shutdown"; + # "reboot" = "reboot"; + # "suspend" = "systemctl suspend"; + # "hibernate" = "systemctl hibernate" + }; + }; + }; + + style = /*css*/ '' + @import "/home/matthew/.cache/wal/colors-waybar.css"; + + * { + /* `otf-font-awesome` is required to be installed for icons */ + font-family: FontAwesome, JetBrainsMonoNerdFont; + font-size: 13pt; + } + + window#waybar { + background-color: @background; + color: @cursor; + transition-property: background-color; + transition-duration: .5s; + } + + button { + /* Use box-shadow instead of border so the text isn't offset */ + box-shadow: inset 0 -3px transparent; + /* Avoid rounded borders under each button name */ + border: none; + border-radius: 0; + } + + #workspaces button { + padding: 0 5px; + background-color: transparent; + } + + #workspaces button:hover { + background: rgba(0, 0, 0, 0.2); + } + + #workspaces button.focused, #workspaces button.active { + background-color: @color2; + /* box-shadow: inset 0 -3px @color3; */ + } + + #workspaces button.urgent { + background-color: @color4; + } + + #language, + #tray, + #bluetooth, + #wireplumber, + #network, + #backlight, + #power-profiles-daemon, + #battery, + #clock, + #power { + padding: 0 10px; + color: @cursor; + } + + #window, + #workspaces { + margin: 0 4px; + } + + /* If workspaces is the leftmost module, omit left margin */ + .modules-left > widget:first-child > #workspaces { + margin-left: 0; + } + + /* If workspaces is the rightmost module, omit right margin */ + .modules-right > widget:last-child > #workspaces { + margin-right: 0; + } + ''; + }; + } + ]; + }; +} diff --git a/modules/nixos/programs/wofi.nix b/modules/nixos/programs/wofi.nix new file mode 100644 index 0000000..581232f --- /dev/null +++ b/modules/nixos/programs/wofi.nix @@ -0,0 +1,12 @@ +{ + flake.nixosModules.wofi = { pkgs, ... }: + { + home-manager.users.matthew.imports = [ + { + programs.wofi = { + enable = true; + }; + } + ]; + }; +} diff --git a/modules/nixos/programs/zen-browser.nix b/modules/nixos/programs/zen-browser.nix new file mode 100644 index 0000000..630e4d6 --- /dev/null +++ b/modules/nixos/programs/zen-browser.nix @@ -0,0 +1,82 @@ +{ inputs, ... }: +{ + flake.nixosModules.zen-browser = { pkgs, lib, ... }: + { + environment.systemPackages = + let + extension = shortId: guid: { + name = guid; + value = { + install_url = "https://addons.mozilla.org/en-US/firefox/downloads/latest/${shortId}/latest.xpi"; + installation_mode = "normal_installed"; + }; + }; + + prefs = { + # Check these out at about:config + # ... + }; + + extensions = [ + # To add additional extensions, find it on addons.mozilla.org, find + # the short ID in the url (like https://addons.mozilla.org/en-US/firefox/addon/!SHORT_ID!/) + # Then go to https://addons.mozilla.org/api/v5/addons/addon/!SHORT_ID!/ to get the guid + (extension "ublock-origin" "uBlock0@raymondhill.net") + # ... + ]; + in + [ + (pkgs.wrapFirefox + inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.zen-browser-unwrapped + { + extraPrefs = lib.concatLines ( + lib.mapAttrsToList ( + name: value: ''lockPref(${lib.strings.toJSON name}, ${lib.strings.toJSON value});'' + ) prefs + ); + + extraPolicies = { + DisableTelemetry = true; + ExtensionSettings = builtins.listToAttrs extensions; + + SearchEngines = { + Default = "ddg"; + Add = [ + { + Name = "nixpkgs packages"; + URLTemplate = "https://search.nixos.org/packages?query={searchTerms}"; + IconURL = "https://wiki.nixos.org/favicon.ico"; + Alias = "np"; + } + { + Name = "NixOS options"; + URLTemplate = "https://search.nixos.org/options?query={searchTerms}"; + IconURL = "https://wiki.nixos.org/favicon.ico"; + Alias = "no"; + } + { + Name = "NixOS Wiki"; + URLTemplate = "https://wiki.nixos.org/w/index.php?search={searchTerms}"; + IconURL = "https://wiki.nixos.org/favicon.ico"; + Alias = "nw"; + } + { + Name = "noogle"; + URLTemplate = "https://noogle.dev/q?term={searchTerms}"; + IconURL = "https://noogle.dev/favicon.ico"; + Alias = "ng"; + } + { + Name = "home-manager options"; + URLTemplate = "https://home-manager-options.extranix.com/?query={searchTerms}&release=master"; + IconURL = "https://wiki.nixos.org/favicon.ico"; + Alias = "ho"; + } + ]; + }; + }; + } + ) + ]; + }; +} diff --git a/modules/nixos/sessions/config.kdl b/modules/nixos/sessions/config.kdl new file mode 100644 index 0000000..69764c8 --- /dev/null +++ b/modules/nixos/sessions/config.kdl @@ -0,0 +1,649 @@ +// This config is in the KDL format: https://kdl.dev +// "/-" comments out the following node. +// Check the wiki for a full description of the configuration: +// https://yalter.github.io/niri/Configuration:-Introduction + +// Input device configuration. +// Find the full list of options on the wiki: +// https://yalter.github.io/niri/Configuration:-Input +input { + keyboard { + xkb { + // You can set rules, model, layout, variant and options. + // For more information, see xkeyboard-config(7). + + // For example: + layout "us,ru" + // options "grp:win_space_toggle,compose:ralt,ctrl:nocaps" + options "grp:caps_toggle" + + // If this section is empty, niri will fetch xkb settings + // from org.freedesktop.locale1. You can control these using + // localectl set-x11-keymap. + } + + repeat-delay 250 + repeat-rate 25 + + // Enable numlock on startup, omitting this setting disables it. + numlock + } + + // Next sections include libinput settings. + // Omitting settings disables them, or leaves them at their default values. + // All commented-out settings here are examples, not defaults. + touchpad { + // off + tap + // dwt + // dwtp + // drag false + // drag-lock + natural-scroll + // accel-speed 0.2 + // accel-profile "flat" + // scroll-method "two-finger" + // disabled-on-external-mouse + } + + mouse { + // off + // natural-scroll + // accel-speed 0.2 + accel-profile "flat" + // scroll-method "no-scroll" + } + + trackpoint { + // off + // natural-scroll + // accel-speed 0.2 + accel-profile "flat" + // scroll-method "on-button-down" + // scroll-button 273 + // scroll-button-lock + // middle-emulation + } + + // Uncomment this to make the mouse warp to the center of newly focused windows. + warp-mouse-to-focus + + // Focus windows and outputs automatically when moving the mouse into them. + // Setting max-scroll-amount="0%" makes it work only on windows already fully on screen. + focus-follows-mouse max-scroll-amount="95%" +} + +// You can configure outputs by their name, which you can find +// by running `niri msg outputs` while inside a niri instance. +// The built-in laptop monitor is usually called "eDP-1". +// Find more information on the wiki: +// https://yalter.github.io/niri/Configuration:-Outputs +// Remember to uncomment the node by removing "/-"! +output "eDP-1" { + // Uncomment this line to disable this output. + // off + + // Resolution and, optionally, refresh rate of the output. + // The format is "x" or "x@". + // If the refresh rate is omitted, niri will pick the highest refresh rate + // for the resolution. + // If the mode is omitted altogether or is invalid, niri will pick one automatically. + // Run `niri msg outputs` while inside a niri instance to list all outputs and their modes. + mode "1920x1080@60" + + // You can use integer or fractional scale, for example use 1.5 for 150% scale. + scale 1 + + // Transform allows to rotate the output counter-clockwise, valid values are: + // normal, 90, 180, 270, flipped, flipped-90, flipped-180 and flipped-270. + transform "normal" + + // Position of the output in the global coordinate space. + // This affects directional monitor actions like "focus-monitor-left", and cursor movement. + // The cursor can only move between directly adjacent outputs. + // Output scale and rotation has to be taken into account for positioning: + // outputs are sized in logical, or scaled, pixels. + // For example, a 3840×2160 output with scale 2.0 will have a logical size of 1920×1080, + // so to put another output directly adjacent to it on the right, set its x to 1920. + // If the position is unset or results in an overlap, the output is instead placed + // automatically. + // position x=1280 y=0 +} + +// Settings that influence how windows are positioned and sized. +// Find more information on the wiki: +// https://yalter.github.io/niri/Configuration:-Layout +layout { + // Set gaps around windows in logical pixels. + gaps 8 + + always-center-single-column + + // When to center a column when changing focus, options are: + // - "never", default behavior, focusing an off-screen column will keep at the left + // or right edge of the screen. + // - "always", the focused column will always be centered. + // - "on-overflow", focusing a column will center it if it doesn't fit + // together with the previously focused column. + center-focused-column "never" + + // You can customize the widths that "switch-preset-column-width" (Mod+R) toggles between. + preset-column-widths { + // Proportion sets the width as a fraction of the output width, taking gaps into account. + // For example, you can perfectly fit four windows sized "proportion 0.25" on an output. + // The default preset widths are 1/3, 1/2 and 2/3 of the output. + proportion 0.33333 + proportion 0.5 + proportion 0.66667 + + // Fixed sets the width in logical pixels exactly. + // fixed 1920 + } + + // You can also customize the heights that "switch-preset-window-height" (Mod+Shift+R) toggles between. + // preset-window-heights { } + + // You can change the default width of the new windows. + default-column-width { proportion 0.5; } + // If you leave the brackets empty, the windows themselves will decide their initial width. + // default-column-width {} + + // By default focus ring and border are rendered as a solid background rectangle + // behind windows. That is, they will show up through semitransparent windows. + // This is because windows using client-side decorations can have an arbitrary shape. + // + // If you don't like that, you should uncomment `prefer-no-csd` below. + // Niri will draw focus ring and border *around* windows that agree to omit their + // client-side decorations. + // + // Alternatively, you can override it with a window rule called + // `draw-border-with-background`. + + // You can change how the focus ring looks. + focus-ring { + // Uncomment this line to disable the focus ring. + // off + + // How many logical pixels the ring extends out from the windows. + width 3 + + // Colors can be set in a variety of ways: + // - CSS named colors: "red" + // - RGB hex: "#rgb", "#rgba", "#rrggbb", "#rrggbbaa" + // - CSS-like notation: "rgb(255, 127, 0)", rgba(), hsl() and a few others. + + // Color of the ring on the active monitor. + // active-color "#7fc8ff" + active-color "#77863D" + + // Color of the ring on inactive monitors. + // + // The focus ring only draws around the active window, so the only place + // where you can see its inactive-color is on other monitors. + inactive-color "#505050" + + // You can also use gradients. They take precedence over solid colors. + // Gradients are rendered the same as CSS linear-gradient(angle, from, to). + // The angle is the same as in linear-gradient, and is optional, + // defaulting to 180 (top-to-bottom gradient). + // You can use any CSS linear-gradient tool on the web to set these up. + // Changing the color space is also supported, check the wiki for more info. + // + // active-gradient from="#80c8ff" to="#c7ff7f" angle=45 + + // You can also color the gradient relative to the entire view + // of the workspace, rather than relative to just the window itself. + // To do that, set relative-to="workspace-view". + // + // inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" + } + + // You can also add a border. It's similar to the focus ring, but always visible. + border { + // The settings are the same as for the focus ring. + // If you enable the border, you probably want to disable the focus ring. + off + + width 2 + active-color "#ffc87f" + inactive-color "#505050" + + // Color of the border around windows that request your attention. + urgent-color "#9b0000" + + // Gradients can use a few different interpolation color spaces. + // For example, this is a pastel rainbow gradient via in="oklch longer hue". + // + // active-gradient from="#e5989b" to="#ffb4a2" angle=45 relative-to="workspace-view" in="oklch longer hue" + + // inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" + } + + // You can enable drop shadows for windows. + shadow { + // Uncomment the next line to enable shadows. + // on + + // By default, the shadow draws only around its window, and not behind it. + // Uncomment this setting to make the shadow draw behind its window. + // + // Note that niri has no way of knowing about the CSD window corner + // radius. It has to assume that windows have square corners, leading to + // shadow artifacts inside the CSD rounded corners. This setting fixes + // those artifacts. + // + // However, instead you may want to set prefer-no-csd and/or + // geometry-corner-radius. Then, niri will know the corner radius and + // draw the shadow correctly, without having to draw it behind the + // window. These will also remove client-side shadows if the window + // draws any. + // + // draw-behind-window true + + // You can change how shadows look. The values below are in logical + // pixels and match the CSS box-shadow properties. + + // Softness controls the shadow blur radius. + softness 30 + + // Spread expands the shadow. + spread 5 + + // Offset moves the shadow relative to the window. + offset x=0 y=5 + + // You can also change the shadow color and opacity. + color "#0007" + } + + // Struts shrink the area occupied by windows, similarly to layer-shell panels. + // You can think of them as a kind of outer gaps. They are set in logical pixels. + // Left and right struts will cause the next window to the side to always be visible. + // Top and bottom struts will simply add outer gaps in addition to the area occupied by + // layer-shell panels and regular gaps. + struts { + // left 64 + // right 64 + // top 64 + // bottom 64 + } +} + +// Add lines like this to spawn processes at startup. +// Note that running niri as a session supports xdg-desktop-autostart, +// which may be more convenient to use. +// See the binds section below for more spawn examples. + +// This line starts waybar, a commonly used bar for Wayland compositors. +spawn-at-startup "waybar" // Bar. +spawn-at-startup "dunst" // Notification daemon. +spawn-sh-at-startup "swaybg -i /mnt/data/pictures/Bierstadt_Mount_Baker_Washington.jpg" // Wallpaper utility. +spawn-sh-at-startup "wlsunset -l 43.2 -L 76.9 -t 5000" // Night light utility. +spawn-sh-at-startup "wal -i /mnt/data/pictures/Bierstadt_Mount_Baker_Washington.jpg --cols16" +spawn-sh-at-startup "matugen image /mnt/data/pictures/Bierstadt_Mount_Baker_Washington.jpg" + +// To run a shell command (with variables, pipes, etc.), use spawn-sh-at-startup: +// spawn-sh-at-startup "qs -c ~/source/qs/MyAwesomeShell" + +hotkey-overlay { + // Uncomment this line to disable the "Important Hotkeys" pop-up at startup. + skip-at-startup +} + +// Uncomment this line to ask the clients to omit their client-side decorations if possible. +// If the client will specifically ask for CSD, the request will be honored. +// Additionally, clients will be informed that they are tiled, removing some client-side rounded corners. +// This option will also fix border/focus ring drawing behind some semitransparent windows. +// After enabling or disabling this, you need to restart the apps for this to take effect. +prefer-no-csd + +// You can change the path where screenshots are saved. +// A ~ at the front will be expanded to the home directory. +// The path is formatted with strftime(3) to give you the screenshot date and time. +screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" + +// You can also set this to null to disable saving screenshots to disk. +// screenshot-path null + +// Animation settings. +// The wiki explains how to configure individual animations: +// https://yalter.github.io/niri/Configuration:-Animations +animations { + // Uncomment to turn off all animations. + // off + + // Slow down all animations by this factor. Values below 1 speed them up instead. + // slowdown 3.0 +} + +// environment { +// QT_QPA_PLATFORMTHEME "gtk3" +// } + +// cursor { +// xcursor-theme "Bibata-Modern-Classic" +// xcursor-size 24 +// } + +// Window rules let you adjust behavior for individual windows. +// Find more information on the wiki: +// https://yalter.github.io/niri/Configuration:-Window-Rules + +// Work around WezTerm's initial configure bug +// by setting an empty default-column-width. +window-rule { + // This regular expression is intentionally made as specific as possible, + // since this is the default config, and we want no false positives. + // You can get away with just app-id="wezterm" if you want. + match app-id=r#"^org\.wezfurlong\.wezterm$"# + default-column-width {} +} + +// Open the Firefox picture-in-picture player as floating by default. +window-rule { + // This app-id regular expression will work for both: + // - host Firefox (app-id is "firefox") + // - Flatpak Firefox (app-id is "org.mozilla.firefox") + match app-id=r#"firefox$"# title="^Picture-in-Picture$" + open-floating true +} + +// Example: block out two password managers from screen capture. +// (This example rule is commented out with a "/-" in front.) +/-window-rule { + match app-id=r#"^org\.keepassxc\.KeePassXC$"# + match app-id=r#"^org\.gnome\.World\.Secrets$"# + + block-out-from "screen-capture" + + // Use this instead if you want them visible on third-party screenshot tools. + // block-out-from "screencast" +} + +// Example: enable rounded corners for all windows. +// (This example rule is commented out with a "/-" in front.) +/-window-rule { + geometry-corner-radius 12 + clip-to-geometry true +} + +binds { + // Keys consist of modifiers separated by + signs, followed by an XKB key name + // in the end. To find an XKB name for a particular key, you may use a program + // like wev. + // + // "Mod" is a special modifier equal to Super when running on a TTY, and to Alt + // when running as a winit window. + // + // Most actions that you can bind here can also be invoked programmatically with + // `niri msg action do-something`. + + // Mod-Shift-/, which is usually the same as Mod-?, + // shows a list of important hotkeys. + Mod+Shift+Slash { show-hotkey-overlay; } + + // Suggested binds for running programs: terminal, app launcher, screen locker. + Mod+Shift+G hotkey-overlay-title=null { spawn "godot-mono"; } + Mod+Shift+O hotkey-overlay-title=null { spawn "obsidian"; } + Mod+Shift+F hotkey-overlay-title=null { spawn-sh "zen"; } + Mod+Shift+T hotkey-overlay-title=null { spawn-sh "Telegram"; } + Mod+Shift+C hotkey-overlay-title=null { spawn "kitty"; } + Mod+E hotkey-overlay-title=null { spawn "nautilus"; } + Mod+P hotkey-overlay-title="Run an Application: wofi" { spawn-sh "wofi --show drun"; } + + // Use spawn-sh to run a shell command. Do this if you need pipes, multiple commands, etc. + // Note: the entire command goes as a single argument. It's passed verbatim to `sh -c`. + // For example, this is a standard bind to toggle the screen reader (orca). + Super+Alt+S allow-when-locked=true hotkey-overlay-title=null { spawn-sh "pkill orca || exec orca"; } + + // Example volume keys mappings for PipeWire & WirePlumber. + // The allow-when-locked=true property makes them work even when the session is locked. + // Using spawn-sh allows to pass multiple arguments together with the command. + // "-l 1.0" limits the volume to 100%. + XF86AudioRaiseVolume allow-when-locked=true { spawn-sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.05+ -l 1.0"; } + XF86AudioLowerVolume allow-when-locked=true { spawn-sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.05-"; } + XF86AudioMute allow-when-locked=true { spawn-sh "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; } + XF86AudioMicMute allow-when-locked=true { spawn-sh "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"; } + + // Example media keys mapping using playerctl. + // This will work with any MPRIS-enabled media player. + XF86AudioPlay allow-when-locked=true { spawn-sh "playerctl play-pause"; } + XF86AudioStop allow-when-locked=true { spawn-sh "playerctl stop"; } + XF86AudioPrev allow-when-locked=true { spawn-sh "playerctl previous"; } + XF86AudioNext allow-when-locked=true { spawn-sh "playerctl next"; } + + // Example brightness key mappings for brightnessctl. + // You can use regular spawn with multiple arguments too (to avoid going through "sh"), + // but you need to manually put each argument in separate "" quotes. + XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "+5%"; } + XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "5%-"; } + + // Open/close the Overview: a zoomed-out view of workspaces and windows. + // You can also move the mouse into the top-left hot corner, + // or do a four-finger swipe up on a touchpad. + Mod+O repeat=false { toggle-overview; } + + Mod+C repeat=false { close-window; } + + Mod+Left { focus-column-left; } + Mod+Down { focus-window-down; } + Mod+Up { focus-window-up; } + Mod+Right { focus-column-right; } + Mod+H { focus-column-left; } + Mod+J { focus-window-down; } + Mod+K { focus-window-up; } + Mod+L { focus-column-right; } + + Mod+Shift+Left { move-column-left; } + Mod+Shift+Down { move-window-down; } + Mod+Shift+Up { move-window-up; } + Mod+Shift+Right { move-column-right; } + Mod+Shift+H { move-column-left; } + Mod+Shift+J { move-window-down; } + Mod+Shift+K { move-window-up; } + Mod+Shift+L { move-column-right; } + + // Alternative commands that move across workspaces when reaching + // the first or last window in a column. + // Mod+J { focus-window-or-workspace-down; } + // Mod+K { focus-window-or-workspace-up; } + // Mod+Ctrl+J { move-window-down-or-to-workspace-down; } + // Mod+Ctrl+K { move-window-up-or-to-workspace-up; } + + Mod+Home { focus-column-first; } + Mod+End { focus-column-last; } + Mod+Ctrl+Home { move-column-to-first; } + Mod+Ctrl+End { move-column-to-last; } + + Mod+Ctrl+Left { focus-monitor-left; } + Mod+Ctrl+Down { focus-monitor-down; } + Mod+Ctrl+Up { focus-monitor-up; } + Mod+Ctrl+Right { focus-monitor-right; } + Mod+Ctrl+H { focus-monitor-left; } + Mod+Ctrl+J { focus-monitor-down; } + Mod+Ctrl+K { focus-monitor-up; } + Mod+Ctrl+L { focus-monitor-right; } + + Mod+Shift+Ctrl+Left { move-column-to-monitor-left; } + Mod+Shift+Ctrl+Down { move-column-to-monitor-down; } + Mod+Shift+Ctrl+Up { move-column-to-monitor-up; } + Mod+Shift+Ctrl+Right { move-column-to-monitor-right; } + Mod+Shift+Ctrl+H { move-column-to-monitor-left; } + Mod+Shift+Ctrl+J { move-column-to-monitor-down; } + Mod+Shift+Ctrl+K { move-column-to-monitor-up; } + Mod+Shift+Ctrl+L { move-column-to-monitor-right; } + + // Alternatively, there are commands to move just a single window: + // Mod+Shift+Ctrl+Left { move-window-to-monitor-left; } + // ... + + // And you can also move a whole workspace to another monitor: + // Mod+Shift+Ctrl+Left { move-workspace-to-monitor-left; } + // ... + + Mod+Page_Down { focus-workspace-down; } + Mod+Page_Up { focus-workspace-up; } + Mod+U { focus-workspace-down; } + Mod+I { focus-workspace-up; } + Mod+Ctrl+Page_Down { move-column-to-workspace-down; } + Mod+Ctrl+Page_Up { move-column-to-workspace-up; } + Mod+Ctrl+U { move-column-to-workspace-down; } + Mod+Ctrl+I { move-column-to-workspace-up; } + + // Alternatively, there are commands to move just a single window: + // Mod+Ctrl+Page_Down { move-window-to-workspace-down; } + // ... + + Mod+Shift+Page_Down { move-workspace-down; } + Mod+Shift+Page_Up { move-workspace-up; } + Mod+Shift+U { move-workspace-down; } + Mod+Shift+I { move-workspace-up; } + + // You can bind mouse wheel scroll ticks using the following syntax. + // These binds will change direction based on the natural-scroll setting. + // + // To avoid scrolling through workspaces really fast, you can use + // the cooldown-ms property. The bind will be rate-limited to this value. + // You can set a cooldown on any bind, but it's most useful for the wheel. + Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; } + Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; } + Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; } + Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; } + + Mod+WheelScrollRight { focus-column-right; } + Mod+WheelScrollLeft { focus-column-left; } + Mod+Ctrl+WheelScrollRight { move-column-right; } + Mod+Ctrl+WheelScrollLeft { move-column-left; } + + // Usually scrolling up and down with Shift in applications results in + // horizontal scrolling; these binds replicate that. + Mod+Shift+WheelScrollDown { focus-column-right; } + Mod+Shift+WheelScrollUp { focus-column-left; } + Mod+Ctrl+Shift+WheelScrollDown { move-column-right; } + Mod+Ctrl+Shift+WheelScrollUp { move-column-left; } + + // Similarly, you can bind touchpad scroll "ticks". + // Touchpad scrolling is continuous, so for these binds it is split into + // discrete intervals. + // These binds are also affected by touchpad's natural-scroll, so these + // example binds are "inverted", since we have natural-scroll enabled for + // touchpads by default. + // Mod+TouchpadScrollDown { spawn-sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.02+"; } + // Mod+TouchpadScrollUp { spawn-sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.02-"; } + + // You can refer to workspaces by index. However, keep in mind that + // niri is a dynamic workspace system, so these commands are kind of + // "best effort". Trying to refer to a workspace index bigger than + // the current workspace count will instead refer to the bottommost + // (empty) workspace. + // + // For example, with 2 workspaces + 1 empty, indices 3, 4, 5 and so on + // will all refer to the 3rd workspace. + 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+Shift+1 { move-column-to-workspace 1; } + Mod+Shift+2 { move-column-to-workspace 2; } + Mod+Shift+3 { move-column-to-workspace 3; } + Mod+Shift+4 { move-column-to-workspace 4; } + Mod+Shift+5 { move-column-to-workspace 5; } + Mod+Shift+6 { move-column-to-workspace 6; } + Mod+Shift+7 { move-column-to-workspace 7; } + Mod+Shift+8 { move-column-to-workspace 8; } + Mod+Shift+9 { move-column-to-workspace 9; } + + // Alternatively, there are commands to move just a single window: + // Mod+Ctrl+1 { move-window-to-workspace 1; } + + // Switches focus between the current and the previous workspace. + // Mod+Tab { focus-workspace-previous; } + + // The following binds move the focused window in and out of a column. + // If the window is alone, they will consume it into the nearby column to the side. + // If the window is already in a column, they will expel it out. + + Mod+Comma { consume-or-expel-window-left; } + Mod+Period { consume-or-expel-window-right; } + + // Consume one window from the right to the bottom of the focused column. + Mod+Shift+Comma { consume-window-into-column; } + // Expel the bottom window from the focused column to the right. + Mod+Shift+Period { expel-window-from-column; } + + Mod+R { switch-preset-column-width; } + // Cycling through the presets in reverse order is also possible. + // Mod+R { switch-preset-column-width-back; } + Mod+Shift+R { switch-preset-window-height; } + Mod+Ctrl+R { reset-window-height; } + Mod+M { maximize-column; } + Mod+F { fullscreen-window; } + + // Expand the focused column to space not taken up by other fully visible columns. + // Makes the column "fill the rest of the space". + Mod+Ctrl+F { expand-column-to-available-width; } + + Mod+Alt+C { center-column; } + + // Center all fully visible columns on screen. + Mod+Ctrl+C { center-visible-columns; } + + // Finer width adjustments. + // This command can also: + // * set width in pixels: "1000" + // * adjust width in pixels: "-5" or "+5" + // * set width as a percentage of screen width: "25%" + // * adjust width as a percentage of screen width: "-10%" or "+10%" + // Pixel sizes use logical, or scaled, pixels. I.e. on an output with scale 2.0, + // set-column-width "100" will make the column occupy 200 physical screen pixels. + Mod+Minus { set-column-width "-10%"; } + Mod+Equal { set-column-width "+10%"; } + + // Finer height adjustments when in column with other windows. + Mod+Shift+Minus { set-window-height "-10%"; } + Mod+Shift+Equal { set-window-height "+10%"; } + + // Move the focused window between the floating and the tiling layout. + Mod+V { toggle-window-floating; } + Mod+Shift+V { switch-focus-between-floating-and-tiling; } + + // Toggle tabbed column display mode. + // Windows in this column will appear as vertical tabs, + // rather than stacked on top of each other. + Mod+W { toggle-column-tabbed-display; } + + // Actions to switch layouts. + // Note: if you uncomment these, make sure you do NOT have + // a matching layout switch hotkey configured in xkb options above. + // Having both at once on the same hotkey will break the switching, + // since it will switch twice upon pressing the hotkey (once by xkb, once by niri). + // Mod+Space { switch-layout "next"; } + // Mod+Shift+Space { switch-layout "prev"; } + + Print { screenshot; } + Ctrl+Print { screenshot-screen; } + Alt+Print { screenshot-window; } + + // Applications such as remote-desktop clients and software KVM switches may + // request that niri stops processing the keyboard shortcuts defined here + // so they may, for example, forward the key presses as-is to a remote machine. + // It's a good idea to bind an escape hatch to toggle the inhibitor, + // so a buggy application can't hold your session hostage. + // + // The allow-inhibiting=false property can be applied to other binds as well, + // which ensures niri always processes them, even when an inhibitor is active. + Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } + + // The quit action will show a confirmation dialog to avoid accidental exits. + Mod+Shift+E { quit; } + Ctrl+Alt+Delete { quit; } + + // 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/modules/nixos/sessions/niri.nix b/modules/nixos/sessions/niri.nix new file mode 100644 index 0000000..302bdf5 --- /dev/null +++ b/modules/nixos/sessions/niri.nix @@ -0,0 +1,86 @@ +{ self, lib, ... }: +{ + flake.nixosModules.niri = { pkgs, ... }: + { + imports = [ + self.nixosModules.wofi + self.nixosModules.waybar + self.nixosModules.matugen + ]; + + programs.niri.enable = true; + services.displayManager.gdm.enable = true; + + services.udisks2.enable = true; # Removable media. + services.gvfs.enable = true; # Nautilus mount and trash support. + + environment.systemPackages = with pkgs; [ + brightnessctl + dunst + eog + gnome-themes-extra + kdePackages.breeze + kdePackages.dolphin + kdePackages.kcalc + mpv + nautilus + pywal + swaybg + waybar + wlsunset + xwayland-satellite + ]; + + home-manager.users.matthew.imports = [ + { + services.polkit-gnome.enable = true; # Enable Gnome polkit. + + # Symlink config file. + xdg.configFile."niri/config.kdl".source = ./config.kdl; + + # Set default applications. + xdg.mimeApps = { + enable = true; + defaultApplications = let + imageViewer = "org.gnome.eog.desktop"; + documentViewer = "org.kde.okular.desktop"; + videoViewer = "mpv.desktop"; + in { + "image/png" = imageViewer; + "image/jpg" = imageViewer; + "image/jpeg" = imageViewer; + "document/pdf" = documentViewer; + "video/mp4" = videoViewer; + "video/webm" = videoViewer; + }; + }; + + # Set cursor theme. + home.file.".icons/default".source = "${pkgs.bibata-cursors}/share/icons/Bibata-Modern-Classic"; + + # Set dark theme for GTK programs. + dconf.settings."org/gnome/desktop/interface".color-scheme = "prefer-dark"; + + # Set GTK theme. + gtk = { + enable = true; + theme = { + name = "adw-gtk3-dark"; + package = pkgs.adw-gtk3; + }; + cursorTheme = { + name = "Bibata-Modern-Classic"; + package = pkgs.bibata-cursors; + size = 24; + }; + }; + + # Make QT follow GTK theme. + qt = { + enable = true; + platformTheme.name = "gtk3"; + }; + } + ]; + }; +}