diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..a5e26fd --- /dev/null +++ b/Readme.md @@ -0,0 +1,53 @@ +# Voronind NixOS configuration. + +## Screenshot. + +![Screenshot](https://i.imgur.com/aGmmVJa.png) + +[Wallpaper link](https://git.voronind.com/voronind/nixos/src/branch/main/part/Wallpaper.nix#L2) + +## What is NixOS? + +NixOS allows you to manage your systems declaratively. Which means that nothing happens outside the centralized config. System handles all the mutations when your config changes - even without reboot! + +The core of the system is a thing called Nixpkgs. Nix is not your regular package manager. Smart people simplified all the complicated installation and configuration to a single generalized way of writing configuration. + +This repository uses flakes for configuration. I really recomend you to start with flakes and skip channels entirely. Flakes give you one killer feature called version locking. This means that unless you update your .lock file, you'll have all the same binary versions across all the hosts. This makes thing very consistent across all your hosts. And it allows for easy rollback just by dropping .lock file update commit. + +NixOS also scales well. You can have a single configuration file just for your host locally. Or, like me, you can have an online repository for any amount of hosts. All my hosts pull changes every hour from this repo. They are *not* all running the same configuration, which is a very common misconception. Here I have a bunch of "modules" like Bash, Gnome, Sway, Gaming etc. For example, I want to do heavy gaming on my desktop, so I enable Gnome+Gaming. But my laptop has *smol (kitten sized)* RAM and I go with just Sway and no Gaming :sad:. + +For power users it has a heck load of goodies! For example, if you have a home server or just a powerful machine, you can use it as a cache and/or a build server. In my setup it works like this: when any of my hosts updates, builds any development shell or temporarily loads any package - it caches everything on my home lab. This means that after each flake lock update (package versions) I download everything over the Internet only once - other local hosts pull from my homelab over the fast local connection. Also if I need to build a heavy development environment i.e. for Android project - it will be built once, cached the result on homelab and then other hosts will pull the prebuild environment. You can also create Live ISO installations from your config, run in impermanence mode and so much more! + +Outside of NixOS you also get things like Dev Shells. They allow you to create reproducible environments per project. This means you can run `nix develop` on any host with Nix package manager (not limited to NixOS) and have *exact* environment. By only typing two words. This creates a consistent environment, which practically destroys *"it works on my machine!"* arguments. This said, you may actually start in softcore mode: by utilizing Nix package manager and Home Manager. They do not require NixOS and can help you get aquainted with Nix ecosystem. But if it's just so happens that you distrohop now - spin it up! Learning the Nix language may be daunting, but in the long run it will save you so much time - in shipping updates, + +The project started way back in 2003 and is rock solid by now. +And no, this is by far *not* the same thing as Ansible and Docker. + +## NixOS learning roadmap. + +0. [Nix Pills](https://nixos.org/guides/nix-pills/). This is a bit controversial one. Try it, but if it's hard to read for you - just skip it for now. + +??? Where to look for stuff. +??? Nix language. +??? Nix package manager. +??? Nixpkgs. +??? Home manager. + +??? (Optional) Remote builders. +??? (Optional) Live ISO. +??? (Optional) Dev Shells. +??? (Optional) Impermanence. + +## Discovering my configuration. + +Even tho I've tried to document everything I can in a dum-dum way, I still highly recommend you to learn the very basics of Nix language. If you can give a basic answer to these questions, you may continue: + +1. What a set is? +2. How to define a function? +3. *???* + +Start from the [Flake](flake.nix) file and follow the comments. If you have any questions, get in touch using [Telegram](https://t.me/voronind_com) or [Email](mailto:hi@voronind.com). + +## Configuration highlights. + +* [Keyd](module/common/Keyd.nix) allows you to have QMK-like keyboard remaps. Killer-feature is the ability to have remaps per-application. I have pretty common remaps like CapsLock to Ctrl/Esc combo, Right Shift to Backspace, Backspace to Delete and overlays for System/Windows/Media/Application controls as well as Macros. diff --git a/flake.nix b/flake.nix index dd99fa6..688c6aa 100644 --- a/flake.nix +++ b/flake.nix @@ -1,21 +1,40 @@ +# This is a configuration entry-point called "Flake". +# Here you define your inputs (dependencies) and outputs (hosts). { + # Those are external dependencies. inputs = { - # System. + # Core system. + # Homepage: https://github.com/NixOS/nixpkgs + # Manual: https://nixos.org/manual/nixos/stable + # Search: https://search.nixos.org/packages and https://search.nixos.org/options nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - stylix.url = "github:danth/stylix"; + + # This thing manages user's /home directroies. Because NixOS only manages system itself. + # Homepage: https://github.com/nix-community/home-manager + # Manual: https://nix-community.github.io/home-manager + # Search: https://home-manager-options.extranix.com home-manager = { url = "github:nix-community/home-manager"; + + # This means that home-manager and our Flake both depend on the same nixpkgs version. inputs.nixpkgs.follows = "nixpkgs"; }; - # Android. + # This allows automatic styling based on active Wallpaper. + # Homepage: https://github.com/danth/stylix + # Manual: https://danth.github.io/stylix + stylix.url = "github:danth/stylix"; + + # Nix on Android (inside Termux). It has no NixOS modules, but still allows the use of Nixpkgs arm packages with Home-Manager configurations. + # Homepage: https://github.com/nix-community/nix-on-droid + # Manual: https://github.com/nix-community/nix-on-droid/blob/master/README.md nix-on-droid = { url = "github:t184256/nix-on-droid/release-23.05"; inputs.nixpkgs.follows = "nixpkgs"; inputs.home-manager.follows = "home-manager"; }; - # Nvim plugins. + # Those are Nvim plugins. I do not use package managers like Packer or Lazy, instead I use Nix to download them and later configure in [Neovim module](module/common/Nvim.nix). nvimAlign = { url = "github:echasnovski/mini.align"; flake = false; @@ -98,6 +117,10 @@ }; }; + # Those are outputs (hosts, configurations) that can be produced by this whole config. + # Here you see a set of inputs we defined above, like nixpkgs, home-manager and so on. + # `...` at the end of a set means "ignore other arguments provided to this function". + # @inputs means aliasing all the inputs to the `inputs` name, so we can pass them all at once later. outputs = { self, nixpkgs, nix-on-droid, home-manager, stylix, ... } @inputs: { # Constant values. const = { @@ -107,51 +130,78 @@ url = "https://git.voronind.com/voronind/nixos.git"; }; - # Common modules used across all hosts. + # Common modules used across all the hosts. nixosModules.common = let + # This function allows me to get the list of all the files from the directories I need. + # It differs from the util.ls function because it also filters out all the directories. lsFiles = path: map (f: "${path}/${f}") ( builtins.filter (i: builtins.readFileType "${path}/${i}" == "regular") ( builtins.attrNames (builtins.readDir path) ) ); in { + # Here I import everything from those directories. imports = (lsFiles ./module/common) ++ (lsFiles ./overlay) ++ [ ./user/Root.nix ]; }; - # Function to create a host. + # Function to create a host. It does basic setup, like adding common modules. mkHost = { system, hostname, modules } @args: nixpkgs.lib.nixosSystem { + # `Inherit` is just an alias for `system = system;`, which means that + # keep the `system` argument as a property in a resulting set. inherit system; + # List of modules to use by defualt for all the hosts. modules = [ - ./host/${hostname}/Configuration.nix - { networking.hostName = hostname; } - { system.stateVersion = self.const.stateVersion; } - inputs.self.nixosModules.common - home-manager.nixosModules.home-manager - stylix.nixosModules.stylix - ] ++ modules; + # There I put host-specific configurations. + ./host/${hostname} + # Make a device hostname match the one from this config. + { networking.hostName = hostname; } + + # Specify current release version. + { system.stateVersion = self.const.stateVersion; } + + # Add common modules. + inputs.self.nixosModules.common + + # Add Home Manager module. + home-manager.nixosModules.home-manager + + # Add Stylix module. + stylix.nixosModules.stylix + ] + # Also add host-specific modules from mkHost args. + ++ modules; + + # SpecialArgs allows you to pass objects down to other NixOS modules. specialArgs = let pkgs = nixpkgs.legacyPackages.${system}.pkgs; config = self.nixosConfigurations.${hostname}.config; in { - const = self.const; - flake = self; - inputs = inputs; - key = import ./part/Key.nix {}; - secret = import ./part/Secret.nix {}; - setting = import ./part/Setting.nix {}; - style = import ./part/Style.nix { config = config; }; - util = import ./part/Util.nix { pkgs = pkgs; }; - wallpaper = import ./part/Wallpaper.nix { pkgs = pkgs; }; + const = self.const; # Constant values. + flake = self; # This Flake itself. + inputs = inputs; # Our dependencies. + key = import ./part/Key.nix {}; # Keyboard keys config. + secret = import ./part/Secret.nix {}; # Secrets (public keys). + setting = import ./part/Setting.nix {}; # My own global settings. + style = import ./part/Style.nix { config = config; }; # Style abstraction. + util = import ./part/Util.nix { pkgs = pkgs; }; # Util functions. + wallpaper = import ./part/Wallpaper.nix { pkgs = pkgs; }; # Wallpaper. }; }; - # List of all hosts bellow. + # Bellow is the list of all the hosts I currently use. + # They call the `mkHost` function that I defined above + # with their specific parameters. + # You might be interested in `live` and `nixOnDroidConfiguration` + # for Live ISO and Android configurations respectively. nixosConfigurations.basic = self.mkHost { - hostname = "basic"; - system = "x86_64-linux"; + hostname = "basic"; # Hostname to use. + system = "x86_64-linux"; # System architecture. + + # Host-specific modules. modules = [ + # Force LTS kernel. ({ pkgs, ... }: { boot.kernelPackages = nixpkgs.lib.mkForce pkgs.linuxPackages; }) ]; }; @@ -161,11 +211,14 @@ system = "x86_64-linux"; modules = [ ./module/AmdGpu.nix + ./module/CapsToggle.nix ./module/Gnome.nix ./module/IntelCpu.nix ./module/PowersaveIntel.nix ./module/Print.nix ./module/RemoteBuild.nix + ./module/StrongSwan.nix + ./module/Tablet.nix ./user/Dasha.nix ]; }; @@ -177,7 +230,7 @@ ./module/AmdCompute.nix ./module/AmdCpu.nix ./module/AmdGpu.nix - # ./module/Ollama.nix + # ./module/Ollama.nix # ISSUE: Currently broken. ./module/PowersaveAmd.nix ./module/Print.nix ./module/RemoteBuild.nix @@ -215,26 +268,42 @@ modules = [ ./module/AmdCpu.nix ./module/AmdGpu.nix + ./module/CapsToggle.nix ./module/Gnome.nix ./module/PowersaveAmd.nix ./module/Print.nix ./module/RemoteBuild.nix + ./module/StrongSwan.nix + ./module/Tablet.nix ./user/Dasha.nix ./user/Voronind.nix ]; }; + # Live ISO configuration. nixosConfigurations.live = self.mkHost { hostname = "live"; system = "x86_64-linux"; modules = [ + # Those are basic modules for Live ISO image. + # You can discover other possible base images here: + # https://github.com/NixOS/nixpkgs/tree/master/nixos/modules/installer/cd-dvd "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix" "${nixpkgs}/nixos/modules/installer/cd-dvd/channel.nix" - { networking.wireless.enable = nixpkgs.lib.mkForce false; } + + # This is required for Live ISO in my case because I use NetworkManager, + # but base Live images require this. + { networking.wireless.enable = nixpkgs.lib.mkForce false; } + + # Override my settings to allow SSH logins using root password. { services.openssh.settings.PasswordAuthentication = nixpkgs.lib.mkForce true; } { services.openssh.settings.PermitRootLogin = nixpkgs.lib.mkForce "yes"; } - { system.autoUpgrade.enable = nixpkgs.lib.mkForce false; } - ({ pkgs, ... }: { boot.kernelPackages = nixpkgs.lib.mkForce pkgs.linuxPackages; }) + + # Disable auto-updates as they are not possible for Live ISO. + { systemd.services.autoupdate.enable = nixpkgs.lib.mkForce false; } + + # Base Live images also require the LTS kernel. + ({ pkgs, ... }: { boot.kernelPackages = nixpkgs.lib.mkForce pkgs.linuxPackages; }) ]; }; @@ -243,8 +312,7 @@ system = "x86_64-linux"; modules = [ ./module/IntelCpu.nix - # ./module/Ollama.nix - ./module/Powerlimit.nix + ./module/PowerlimitThinkpad.nix ./module/PowersaveIntel.nix ./module/Print.nix ./module/RemoteBuild.nix @@ -256,22 +324,28 @@ # Android. nixOnDroidConfigurations.default = nix-on-droid.lib.nixOnDroidConfiguration { modules = [ + # Android release version. { system.stateVersion = inputs.self.const.droidStateVersion; } - ./module/NixOnDroid.nix + + # I put all my Android configuration there. + ./module/android ]; + # SpecialArgs allows you to pass objects down to other configuration. extraSpecialArgs = let + # We want arm64 packages for Android. pkgs = nixpkgs.legacyPackages."aarch64-linux".pkgs; in { - const = self.const; - flake = self; - inputs = inputs; - key = import ./part/Key.nix {}; - secret = import ./part/Secret.nix {}; - setting = import ./part/Setting.nix {}; - style = import ./part/Style.nix { config = import ./part/style/Gruvbox.nix {}; }; - util = import ./part/Util.nix { pkgs = pkgs; }; + const = self.const; # Constant values. + flake = self; # This Flake itself. + inputs = inputs; # Our dependencies. + key = import ./part/Key.nix {}; # Keyboard keys config. + secret = import ./part/Secret.nix {}; # Secrets (public keys). + setting = import ./part/Setting.nix {}; # My own global settings. + style = import ./part/Style.nix { config = import ./part/style/Gruvbox.nix {}; }; # Style abstraction. Stylix is not available for Android so I provide static Gruvbox style. + util = import ./part/Util.nix { pkgs = pkgs; }; # Util functions. }; }; }; } +# That's it! diff --git a/host/basic/default.nix b/host/basic/default.nix new file mode 100644 index 0000000..7ce1e7c --- /dev/null +++ b/host/basic/default.nix @@ -0,0 +1,5 @@ +# Basic host is a dummy and has no specific configuration. +# I don't really need it, this is just a failsafe that I can definitely install and run. +{ ... }: { + imports = [ ]; +} diff --git a/host/laptop/Configuration.nix b/host/dasha/default.nix similarity index 89% rename from host/laptop/Configuration.nix rename to host/dasha/default.nix index 057a35b..4686244 100644 --- a/host/laptop/Configuration.nix +++ b/host/dasha/default.nix @@ -1,7 +1,6 @@ { lib, ... }: { imports = [ ./Filesystem.nix - ../dasha/Tablet.nix ]; # Disable keyd. diff --git a/host/desktop/Configuration.nix b/host/desktop/default.nix similarity index 100% rename from host/desktop/Configuration.nix rename to host/desktop/default.nix diff --git a/host/fsight/Grub.nix b/host/fsight/Grub.nix index c51d9fc..6fd5169 100644 --- a/host/fsight/Grub.nix +++ b/host/fsight/Grub.nix @@ -1,4 +1,5 @@ { lib, ... }: { + # This host is running inside BIOS VM so it needs the Grub. boot.loader.systemd-boot.enable = lib.mkForce false; boot.loader.efi.canTouchEfiVariables = lib.mkForce false; boot.loader.grub.enable = true; diff --git a/host/fsight/Root.nix b/host/fsight/Root.nix index 2d87185..d56fbda 100644 --- a/host/fsight/Root.nix +++ b/host/fsight/Root.nix @@ -1,3 +1,8 @@ { lib, ... }: { + # Force specific PW for this host. users.users.root.hashedPassword = lib.mkForce "$y$j9T$d4HfwutZr.eNHuLJYRuro/$7swZfgCNS6jEXHFCxsW5um/68jX9BRiiZD1BYcm/gD/"; + + # Allow login with PW for others. + # services.openssh.settings.PasswordAuthentication = lib.mkForce true; + # services.openssh.settings.PermitRootLogin = lib.mkForce "yes"; } diff --git a/host/fsight/Configuration.nix b/host/fsight/default.nix similarity index 100% rename from host/fsight/Configuration.nix rename to host/fsight/default.nix diff --git a/host/home/Configuration.nix b/host/home/default.nix similarity index 100% rename from host/home/Configuration.nix rename to host/home/default.nix diff --git a/host/dasha/Configuration.nix b/host/laptop/default.nix similarity index 87% rename from host/dasha/Configuration.nix rename to host/laptop/default.nix index 212efa6..4686244 100644 --- a/host/dasha/Configuration.nix +++ b/host/laptop/default.nix @@ -1,8 +1,6 @@ { lib, ... }: { imports = [ ./Filesystem.nix - ./Tablet.nix - ./Vpn.nix ]; # Disable keyd. diff --git a/host/live/Configuration.nix b/host/live/Configuration.nix deleted file mode 100644 index 7b01fbf..0000000 --- a/host/live/Configuration.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ ... }: { - imports = [ ]; -} diff --git a/host/basic/Configuration.nix b/host/live/default.nix similarity index 100% rename from host/basic/Configuration.nix rename to host/live/default.nix diff --git a/host/work/Configuration.nix b/host/work/default.nix similarity index 100% rename from host/work/Configuration.nix rename to host/work/default.nix diff --git a/module/AmdCompute.nix b/module/AmdCompute.nix index 2248480..afc0c37 100644 --- a/module/AmdCompute.nix +++ b/module/AmdCompute.nix @@ -1,3 +1,4 @@ +# AMD Rocm support (for Blender). { nixpkgs, pkgs, ... }: { nixpkgs.config.rocmSupport = true; systemd.tmpfiles.rules = [ diff --git a/module/AmdCpu.nix b/module/AmdCpu.nix index 7c0f9b7..3bdddf7 100644 --- a/module/AmdCpu.nix +++ b/module/AmdCpu.nix @@ -1,3 +1,4 @@ +# AMD CPU specific configuration. { lib, config, ... }: { boot.kernelModules = [ "kvm-amd" ]; hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; diff --git a/module/AmdGpu.nix b/module/AmdGpu.nix index f936b84..b07d7ed 100644 --- a/module/AmdGpu.nix +++ b/module/AmdGpu.nix @@ -1,3 +1,5 @@ +# AMD GPU specific configuration. +# No, I do not own any Nvidia/Intel GPUs, so I have no configuration for them. { nixpkgs, pkgs, ... }: { boot.initrd.kernelModules = [ "amdgpu" ]; services.xserver.videoDrivers = [ "amdgpu" ]; diff --git a/module/CapsToggle.nix b/module/CapsToggle.nix new file mode 100644 index 0000000..b2fbce9 --- /dev/null +++ b/module/CapsToggle.nix @@ -0,0 +1,6 @@ +# Toggle language with CapsLock. My wife prefers this. +{ lib, ... }: { + services.xserver.xkb = { + options = lib.mkForce "grp:caps_toggle"; + }; +} diff --git a/module/Flatpak.nix b/module/Flatpak.nix deleted file mode 100644 index 198a176..0000000 --- a/module/Flatpak.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ pkgs, lib, ... }: let - list = "~/.config/linux/Flatpak.txt"; -in { - # Enable Flatpaks. - services.flatpak.enable = true; - - # Bootstrap apps on boot. - systemd.services.flatpakinstall = { - description = "Install Flatpak apps."; - wantedBy = [ "multi-user.target" ]; - wants = [ "dotfiles.service" ]; - after = [ "dotfiles.service" ]; - serviceConfig.Type = "oneshot"; - script = '' - ${lib.getExe pkgs.flatpak} remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo - [[ -f ${list} ]] && cat ${list} | cut -f2 | ${lib.getExe pkgs.parallel} -j1 -- ${lib.getExe pkgs.flatpak} install -y --system {} - ''; - }; -} diff --git a/module/Gnome.nix b/module/Gnome.nix index c1543a5..f829437 100644 --- a/module/Gnome.nix +++ b/module/Gnome.nix @@ -4,17 +4,15 @@ ./desktop/Dconf.nix ./desktop/DisplayManager.nix ./desktop/Sound.nix + ./desktop/Wayland.nix ]; environment.systemPackages = with pkgs; [ - adwsteamgtk - gnome.gnome-remote-desktop - gnome.gnome-tweaks - gradience - openssl - wl-clipboard + gnome.gnome-tweaks # Gnome "hidden" settings. + openssl # It was needed for something, can't remember. ]; + # Disable some Gnome apps. services.gnome.gnome-keyring.enable = lib.mkForce false; environment.gnome.excludePackages = with pkgs.gnome; [ # baobab # Disk usage analyzer. diff --git a/module/IntelCpu.nix b/module/IntelCpu.nix index 4fce603..0547212 100644 --- a/module/IntelCpu.nix +++ b/module/IntelCpu.nix @@ -1,3 +1,4 @@ +# Intel CPU specific configuration. { ... }: { boot.kernelModules = [ "kvm-intel" ]; } diff --git a/module/NixOnDroid.nix b/module/NixOnDroid.nix deleted file mode 100644 index fd1b791..0000000 --- a/module/NixOnDroid.nix +++ /dev/null @@ -1,120 +0,0 @@ -{ pkgs, inputs, const, style, util, key, setting, secret, ... } @args: let - homePath = "/data/data/com.termux.nix/files/home"; - tmux = import ./common/tmux args; - bash = import ./common/bash args; - nvim = import ./common/nvim args; - ssh = import ./common/ssh args; - font = pkgs.runCommandNoCC "font" {} '' - cp ${pkgs.nerdfonts.override { fonts = [ "Terminus" ]; }}/share/fonts/truetype/NerdFonts/TerminessNerdFontMono-Regular.ttf $out - ''; - colors = '' - background=#${style.color.bg.dark} - foreground=#${style.color.fg.light} - ''; -in { - time.timeZone = const.timeZone; - nix.extraOptions = '' - experimental-features = nix-command flakes - ''; - - home-manager.config = { - home = { - stateVersion = const.droidStateVersion; - file = { - ".dotfiles".source = inputs.self; - ".ssh/config".text = ssh.config; - ".termux/_font.ttf".source = font; - ".termux/_colors.properties".text = colors; - }; - sessionVariables = { - EDITOR = "nvim"; - MANPAGER = "nvim +Man!"; - NIXPKGS_ALLOW_UNFREE = "1"; - NIX_CURRENT_SYSTEM = "${pkgs.stdenv.system}"; - TERM = "xterm-256color"; - }; - }; - - programs = { - bash = { - enable = true; - bashrcExtra = bash.config + '' - [[ -f ~/.termux/font.ttf ]] || { - cp ~/.termux/_font.ttf ~/.termux/font.ttf - cp ~/.termux/_colors.properties ~/.termux/colors.properties - _warn "Termux config installed, please restart." - }; - ''; - }; - - tmux = { - enable = true; - extraConfig = tmux.config; - }; - - git = { - enable = true; - extraConfig = { - credential.helper = "store"; - init.defaultBranch = "main"; - pull.rebase = true; - push.autoSetupRemote = true; - rebase.autoStash = true; - user.signingkey = builtins.readFile secret.crypto.sign.key; - gpg.ssh.allowedSignersFile = toString(secret.crypto.sign.allowed); - gpg.format = secret.crypto.sign.format; - }; - }; - - neovim = { - enable = true; - viAlias = true; - vimAlias = true; - extraConfig = nvim.config; - }; - - gpg = { - enable = true; - publicKeys = secret.crypto.publicKeys; - }; - }; - }; - - environment.packages = with pkgs; [ - android-tools - binwalk - coreutils - curl - diffutils - ffmpeg - file - findutils - gawk - gcc - gdu - git - gnugrep - gnumake - gnused - gnutar - gzip xz - hostname - imagemagick - jq - lsof - man - nmap - openssh - parallel - pv - ripgrep - rsync - sqlite - pkgs.tmux - tree - utillinux - wget - yt-dlp - zip unzip - ]; -} diff --git a/module/Ollama.nix b/module/Ollama.nix index eff75d1..5ddbd4d 100644 --- a/module/Ollama.nix +++ b/module/Ollama.nix @@ -1,5 +1,8 @@ { pkgs, lib, ... }: { + # Add Ollama CLI app. environment.systemPackages = with pkgs; [ ollama ]; + + # Enable Ollama server. systemd.services.ollama = { description = "Ollama LLM server."; wantedBy = [ "multi-user.target" ]; @@ -10,6 +13,8 @@ HOME=/root ${lib.getExe pkgs.ollama} serve ''; }; + + # Download Ollama models. systemd.services.ollamamodel = { description = "Ollama LLM model."; wantedBy = [ "multi-user.target" ]; diff --git a/module/Powerlimit.nix b/module/Powerlimit.nix deleted file mode 100644 index 8514d7a..0000000 --- a/module/Powerlimit.nix +++ /dev/null @@ -1,58 +0,0 @@ -{ pkgs, lib, ... }: let - controlFileMin = "/sys/class/power_supply/BAT0/charge_control_start_threshold"; - controlFileMax = "/sys/class/power_supply/BAT0/charge_control_end_threshold"; - - onMin = "40"; - onMax = "80"; - offMin = "90"; - offMax = "95"; - - script = pkgs.writeShellScriptBin "powerlimit" '' - function toggle() { - if status; then - echo ${offMax} > ${controlFileMax} - echo ${offMin} > ${controlFileMin} - else - echo ${onMin} > ${controlFileMin} - echo ${onMax} > ${controlFileMax} - fi - - true - } - - function waybar() { - status || echo -n "" - } - - function status() { - local current=$(cat ${controlFileMax}) - local enabled="${onMax}" - - [[ "''${current}" = "''${enabled}" ]] - } - - ''${@} - ''; -in { - systemd = { - services.powerlimit = { - description = "Limit battery charge."; - enable = true; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - Type = "simple"; - RemainAfterExit = "yes"; - ExecStart = "${lib.getExe pkgs.bash} -c 'echo 40 > ${controlFileMin}; echo 80 > ${controlFileMax};'"; - ExecStop = "${lib.getExe pkgs.bash} -c 'echo 95 > ${controlFileMax}; echo 90 > ${controlFileMin};'"; - }; - }; - - # HACK: Allow user access. - tmpfiles.rules = [ - "z ${controlFileMax} 0777 - - - -" - "z ${controlFileMin} 0777 - - - -" - ]; - }; - - environment.systemPackages = [ script ]; -} diff --git a/module/PowerlimitThinkpad.nix b/module/PowerlimitThinkpad.nix new file mode 100644 index 0000000..4ed3e8b --- /dev/null +++ b/module/PowerlimitThinkpad.nix @@ -0,0 +1,32 @@ +# ThinkPad charge limits. +{ pkgs, lib, ... } @args: let + controlFileMin = "/sys/class/power_supply/BAT0/charge_control_start_threshold"; + controlFileMax = "/sys/class/power_supply/BAT0/charge_control_end_threshold"; + + onMin = "40"; + onMax = "80"; + offMin = "90"; + offMax = "95"; + + script = pkgs.writeShellScriptBin "powerlimit" (import ./powerlimit/Script.nix { + inherit controlFileMax; + inherit controlFileMin; + inherit onMin; + inherit onMax; + inherit offMin; + inherit offMax; + }).script; +in { + imports = [ + (import ./powerlimit ({ + inherit controlFileMax; + inherit controlFileMin; + inherit onMin; + inherit onMax; + inherit offMin; + inherit offMax; + } // args)) + ]; + + environment.systemPackages = [ script ]; +} diff --git a/module/PowersaveAmd.nix b/module/PowersaveAmd.nix index 9df393c..a750117 100644 --- a/module/PowersaveAmd.nix +++ b/module/PowersaveAmd.nix @@ -1,3 +1,4 @@ +# AMD CPU boost control. { pkgs, ... } @args: let controlFile = "/sys/devices/system/cpu/cpufreq/boost"; enable = "0"; diff --git a/module/PowersaveIntel.nix b/module/PowersaveIntel.nix index be83e70..b6719f5 100644 --- a/module/PowersaveIntel.nix +++ b/module/PowersaveIntel.nix @@ -1,3 +1,4 @@ +# Intel CPU boost control. { pkgs, ... } @args: let controlFile = "/sys/devices/system/cpu/intel_pstate/no_turbo"; enable = "1"; diff --git a/module/RemoteBuild.nix b/module/RemoteBuild.nix index cff868c..2b8bcda 100644 --- a/module/RemoteBuild.nix +++ b/module/RemoteBuild.nix @@ -1,5 +1,6 @@ +# Module that enables remote builds. This is a client configuration. { config, pkgs, ... }: { - # NOTE: Requires key to be present in secret.ssh.builderKeys. + # NOTE: Requires host private key to be present in secret.ssh.builderKeys. nix.buildMachines = [{ hostName = "nixbuilder"; protocol = "ssh-ng"; diff --git a/module/RemoteBuilder.nix b/module/RemoteBuilder.nix index 431042b..e9a2583 100644 --- a/module/RemoteBuilder.nix +++ b/module/RemoteBuilder.nix @@ -1,6 +1,9 @@ +# Module that enables remote builds. This is a server configuration. { pkgs, secret, lib, ... }: let keyPath = "/root/.nixbuilder"; in { + # Service that generates new key on boot if not present. + # Don't forget to add new key to secret.ssh.builderKeys. systemd.services.generate-nix-cache-key = { wantedBy = [ "multi-user.target" ]; serviceConfig.Type = "oneshot"; @@ -13,6 +16,7 @@ in { ''; }; + # Add `nixbuilder` restricted user. users.groups.nixbuilder = {}; users.users.nixbuilder = { openssh.authorizedKeys.keys = secret.ssh.builderKeys; @@ -24,7 +28,8 @@ in { group = "nixbuilder"; }; - # To apply: nix store sign --all -k /path/to/secret-key-file + # Sign store automatically. + # Sign existing store with: nix store sign --all -k /path/to/secret-key-file nix.extraOptions = '' trusted-users = nixbuilder secret-key-files = ${keyPath}/private-key diff --git a/host/dasha/Vpn.nix b/module/StrongSwan.nix similarity index 100% rename from host/dasha/Vpn.nix rename to module/StrongSwan.nix diff --git a/module/Sway.nix b/module/Sway.nix index 0ce4366..33bb9c2 100644 --- a/module/Sway.nix +++ b/module/Sway.nix @@ -8,23 +8,20 @@ in { ./desktop/Bluetooth.nix ./desktop/Brightness.nix ./desktop/Dconf.nix - ./desktop/GnomeApps.nix ./desktop/Portal.nix ./desktop/Realtime.nix ./desktop/Sound.nix ./desktop/Waybar.nix + ./desktop/Wayland.nix ]; services.gnome.gnome-keyring.enable = lib.mkForce false; - systemd.services.keyd.path = [ script pkgs.sway ]; environment.systemPackages = with pkgs; [ - gnome.adwaita-icon-theme # GTK icons. grim slurp # Screenshot. mako # Notification system. networkmanagerapplet # Internet configuration. pamixer pavucontrol pulseaudio # Audio. playerctl # Multimedia controls. - wl-clipboard # Clipboard. script ]; diff --git a/host/dasha/Tablet.nix b/module/Tablet.nix similarity index 100% rename from host/dasha/Tablet.nix rename to module/Tablet.nix diff --git a/module/VirtManager.nix b/module/VirtManager.nix index 6b4d817..d4390fb 100644 --- a/module/VirtManager.nix +++ b/module/VirtManager.nix @@ -8,5 +8,4 @@ # glib gnome3.adwaita-icon-theme # default gnome cursors, ]; - ### } diff --git a/module/android/Environment.nix b/module/android/Environment.nix new file mode 100644 index 0000000..d34bc11 --- /dev/null +++ b/module/android/Environment.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: { + variables = { + EDITOR = "nvim"; + MANPAGER = "nvim +Man!"; + NIXPKGS_ALLOW_UNFREE = "1"; + NIX_CURRENT_SYSTEM = "${pkgs.stdenv.system}"; + TERM = "xterm-256color"; + }; +} diff --git a/module/android/Git.nix b/module/android/Git.nix new file mode 100644 index 0000000..2307e82 --- /dev/null +++ b/module/android/Git.nix @@ -0,0 +1,12 @@ +{ secret, ... }: { + config = { + credential.helper = "store"; + gpg.format = secret.crypto.sign.format; + gpg.ssh.allowedSignersFile = toString(secret.crypto.sign.allowed); + init.defaultBranch = "main"; + pull.rebase = true; + push.autoSetupRemote = true; + rebase.autoStash = true; + user.signingkey = builtins.readFile secret.crypto.sign.key; + }; +} diff --git a/module/android/Nix.nix b/module/android/Nix.nix new file mode 100644 index 0000000..0c87208 --- /dev/null +++ b/module/android/Nix.nix @@ -0,0 +1,5 @@ +{ ... }: { + extraOptions = '' + experimental-features = nix-command flakes + ''; +} diff --git a/module/android/Package.nix b/module/android/Package.nix new file mode 100644 index 0000000..baf759a --- /dev/null +++ b/module/android/Package.nix @@ -0,0 +1,31 @@ +{ pkgs, ... }: { + list = with pkgs; [ + android-tools + binwalk + coreutils diffutils findutils utillinux + curl + ffmpeg + file + gawk gnused gnugrep gnumake ripgrep + gcc + gdu + git + gnutar gzip xz + hostname + imagemagick + jq + lsof + man + nmap + openssh + parallel + pv + rsync + sqlite + pkgs.tmux + tree + wget + yt-dlp + zip unzip + ]; +} diff --git a/module/android/Termux.nix b/module/android/Termux.nix new file mode 100644 index 0000000..537cd44 --- /dev/null +++ b/module/android/Termux.nix @@ -0,0 +1,18 @@ +{ pkgs, style, util, ... }: { + font = pkgs.runCommandNoCC "font" {} '' + cp ${pkgs.nerdfonts.override { fonts = [ "Terminus" ]; }}/share/fonts/truetype/NerdFonts/TerminessNerdFontMono-Regular.ttf $out + ''; + + colors = util.trimTabs '' + background=#${style.color.bg.dark} + foreground=#${style.color.fg.light} + ''; + + initScript = util.trimTabs '' + [[ -f ~/.termux/font.ttf ]] || { + cp ~/.termux/_font.ttf ~/.termux/font.ttf + cp ~/.termux/_colors.properties ~/.termux/colors.properties + _warn "Termux config installed, please restart." + }; + ''; +} diff --git a/module/android/default.nix b/module/android/default.nix new file mode 100644 index 0000000..2efedbd --- /dev/null +++ b/module/android/default.nix @@ -0,0 +1,62 @@ +{ pkgs, inputs, const, style, util, key, setting, secret, ... } @args: let + # Path where Termux stores user data. + homePath = "/data/data/com.termux.nix/files/home"; + + # Android modules. + environment = import ./Environment.nix args; + git = import ./Git.nix args; + nix = import ./Nix.nix args; + package = import ./Package.nix args; + termux = import ./Termux.nix args; + + # External modules. + bash = import ../common/bash args; + nvim = import ../common/nvim args; + ssh = import ../common/ssh args; + tmux = import ../common/tmux args; +in { + time.timeZone = const.timeZone; + nix.extraOptions = nix.extraOptions; + + environment.packages = package.list; + + home-manager.config = { + home = { + stateVersion = const.droidStateVersion; + sessionVariables = environment.variables; + file = { + ".dotfiles".source = inputs.self; + ".ssh/config".text = ssh.config; + ".termux/_font.ttf".source = termux.font; + ".termux/_colors.properties".text = termux.colors; + }; + }; + + programs = { + bash = { + enable = true; + bashrcExtra = bash.config + termux.initScript; + }; + + tmux = { + enable = true; + extraConfig = tmux.config; + }; + + git = { + enable = true; + extraConfig = git.config; + }; + + neovim = { + enable = true; + extraConfig = nvim.config; + }; + + gpg = { + enable = true; + publicKeys = secret.crypto.publicKeys; + }; + }; + }; +} diff --git a/module/common/AutoUpdateSigned.nix b/module/common/AutoUpdateSigned.nix index 0a2cd99..09d5c72 100644 --- a/module/common/AutoUpdateSigned.nix +++ b/module/common/AutoUpdateSigned.nix @@ -1,3 +1,7 @@ +# System automatic updates. +# This is a systemd service that pulls updates every hour. +# Unlike system.autoUpgrade, this script also verifies my git signature +# to prevent unathorized changes to hosts. { const, pkgs, lib, secret, util, ... }: { systemd.services.autoupdate = util.mkStaticSystemdService { enable = true; diff --git a/module/common/Bash.nix b/module/common/Bash.nix index 1f5ab3e..8d239d0 100644 --- a/module/common/Bash.nix +++ b/module/common/Bash.nix @@ -1,9 +1,14 @@ { lib, style, util, pkgs, ... } @args: let bash = import ./bash args; in { + # Add my bash configuration to all *interactive* shells. programs.bash.interactiveShellInit = bash.config; + + # Remove default aliases for `l`, `ll` etc as they break my function definitions. environment.shellAliases = lib.mkForce {}; + environment.variables = { + # Specify terminal mode. TERM = "xterm-256color"; }; } diff --git a/module/common/Bootloader.nix b/module/common/Bootloader.nix index fbf5c2c..d642b13 100644 --- a/module/common/Bootloader.nix +++ b/module/common/Bootloader.nix @@ -7,17 +7,24 @@ loader = { efi.canTouchEfiVariables = true; + # Use systemd to boot. systemd-boot = { enable = true; + + # Limit the amound of generations availabe for rollback. + # This helps to save storage space. configurationLimit = 10; }; }; - tmp.useTmpfs = true; - initrd = { - kernelModules = [ - "dm-snapshot" - ]; + # Mount /tmp on tmpfs. + tmp.useTmpfs = true; + + initrd = { + # Don't really know if I need it. Kept from hardware-configuration. + kernelModules = [ "dm-snapshot" ]; + + # Kernel modules available for all the hosts. availableKernelModules = [ "ahci" "ata_piix" diff --git a/module/common/Crypto.nix b/module/common/Crypto.nix index b4a42af..a82eccc 100644 --- a/module/common/Crypto.nix +++ b/module/common/Crypto.nix @@ -12,16 +12,16 @@ services.pcscd.enable = true; # Yubikey touch notification. + # ISSUE: Not working on Sway with Mako for some reason. # programs.yubikey-touch-detector.enable = true; - # Extra packages. environment.systemPackages = with pkgs; [ - yubikey-manager # Yubikey Manager. + yubikey-manager # yubioath-desktop # OTP. ]; # Store GPG data on tmpfs. - environment.variables = { - # GNUPGHOME = "$(mktemp -d -t gnupg-$(date +%Y-%m-%d)-XXXXXXXXXX)"; - }; + # environment.variables = { + # GNUPGHOME = "$(mktemp -d -t gnupg-$(date +%Y-%m-%d)-XXXXXXXXXX)"; + # }; } diff --git a/module/common/Distrobox.nix b/module/common/Distrobox.nix index 092b37d..906df39 100644 --- a/module/common/Distrobox.nix +++ b/module/common/Distrobox.nix @@ -1,13 +1,8 @@ { pkgs, ... }: { + # Distrobox works best with Podman, so enable it here. + imports = [ ./Podman.nix ]; + environment.systemPackages = with pkgs; [ distrobox ]; - - virtualisation = { - podman = { - enable = true; - defaultNetwork.settings.dns_enabled = false; - dockerCompat = false; - }; - }; } diff --git a/module/common/Dotfiles.nix b/module/common/Dotfiles.nix index 3436790..7e287b5 100644 --- a/module/common/Dotfiles.nix +++ b/module/common/Dotfiles.nix @@ -1,4 +1,4 @@ { inputs, ... }: { - # Easy to find copy just in case. + # Add a link for the active configuration to /etc/dotfiles. environment.etc.dotfiles.source = inputs.self; } diff --git a/module/common/Filesystem.nix b/module/common/Filesystem.nix index c64251d..fea5afe 100644 --- a/module/common/Filesystem.nix +++ b/module/common/Filesystem.nix @@ -1,9 +1,12 @@ +# I use the same layout on all hosts with GPT labels. +# This way I can configure system's FS in one place here. { ... }: { fileSystems."/" = { device = "/dev/disk/by-partlabel/NIXROOT"; fsType = "ext4"; options = [ "noatime" ]; }; + fileSystems."/boot" = { device = "/dev/disk/by-partlabel/NIXBOOT"; fsType = "vfat"; diff --git a/module/common/Firewall.nix b/module/common/Firewall.nix index 9c6bfc8..7a53250 100644 --- a/module/common/Firewall.nix +++ b/module/common/Firewall.nix @@ -1,3 +1,4 @@ { ... }: { + # Disable firewall as I configure firewall on my router. networking.firewall.enable = false; } diff --git a/module/common/Font.nix b/module/common/Font.nix index e7ea178..db9b4f9 100644 --- a/module/common/Font.nix +++ b/module/common/Font.nix @@ -1,7 +1,12 @@ { pkgs, ... }: { fonts.packages = with pkgs; [ + # Use Apple fonts for system and text. (pkgs.callPackage ./applefont {}) + + # Use Nerd version of Terminus for monospaced fonts. (nerdfonts.override { fonts = [ "Terminus" ]; }) + + # I don't use FA, but add it for compatibility. font-awesome ]; } diff --git a/module/common/Kernel.nix b/module/common/Kernel.nix index f8b242f..91b3f1a 100644 --- a/module/common/Kernel.nix +++ b/module/common/Kernel.nix @@ -2,7 +2,6 @@ # Use latest kernel. boot.kernelPackages = pkgs.linuxPackages_latest; - # Sysctl. boot.kernel.sysctl = { # Spoof protection. "net.ipv4.conf.default.rp_filter" = 1; diff --git a/module/common/Keyd.nix b/module/common/Keyd.nix index ff9e242..9a0c891 100644 --- a/module/common/Keyd.nix +++ b/module/common/Keyd.nix @@ -12,11 +12,11 @@ compose = "layer(layer_macro)"; # Input macros. esc = "${key.sysctrl}"; # System controls. leftcontrol = "overload(layer_alternative, leftcontrol)"; # Alternative layer for home, end etc. - rightalt = "capslock"; # Language toggle. rightcontrol = "layer(layer_control)"; # Media and other controls. rightshift = "backspace"; # Backspace. }; + # Alternative navigation. layer_alternative = { w = "pageup"; a = "home"; @@ -29,9 +29,10 @@ j = "down"; k = "up"; l = "right"; - # space = "macro2(1, 100, macro(space))"; # NOTE: Possible bhop example. + # space = "macro2(1, 100, macro(space))"; # NOTE: Possible bhop example. Use in per-application, not here. }; + # Media controls. layer_control = { space = "playpause"; w = "volumeup"; @@ -53,5 +54,6 @@ users.groups.keyd = {}; systemd.services.keyd.serviceConfig.CapabilityBoundingSet = [ "CAP_SETGID" ]; + # Debug toggle just in case I need it again. # systemd.services.keyd.environment.KEYD_DEBUG = "1"; } diff --git a/module/common/Ld.nix b/module/common/Ld.nix index aa5f42e..7914e8f 100644 --- a/module/common/Ld.nix +++ b/module/common/Ld.nix @@ -1,4 +1,7 @@ { pkgs, ... }: { + # This thing allow you to run ELF (binary) files just like in other distros. + # The only difference is that we need to specify their linking dependencies + # bellow in `libraries` section. programs.nix-ld = { enable = true; package = pkgs.nix-ld; diff --git a/module/common/Locale.nix b/module/common/Locale.nix index 8b64978..a47f1bb 100644 --- a/module/common/Locale.nix +++ b/module/common/Locale.nix @@ -1,6 +1,8 @@ { const, ... }: { time.timeZone = const.timeZone; i18n.defaultLocale = "en_US.UTF-8"; + + # You can customize your Locale in detail like that. # i18n.extraLocaleSettings = { # LC_ADDRESS = "ru_RU.UTF-8"; # LC_IDENTIFICATION = "ru_RU.UTF-8"; diff --git a/module/common/Nix.nix b/module/common/Nix.nix index a518986..bb10854 100644 --- a/module/common/Nix.nix +++ b/module/common/Nix.nix @@ -1,10 +1,23 @@ { pkgs, ... }: { environment.variables = { + # Allow running of proprietary software. NIXPKGS_ALLOW_UNFREE = "1"; - NIX_CURRENT_SYSTEM = "${pkgs.stdenv.system}"; + + # I use this env variable to get currently running architecture. + NIX_CURRENT_SYSTEM = "${pkgs.stdenv.system}"; }; - nixpkgs.config.allowUnfree = true; + + # Allow installation of proprietary software. + nixpkgs.config.allowUnfree = true; + + # Deduplicate store automatically. Slows down switches a bit, but saves space. nix.settings.auto-optimise-store = true; + + # Extra configuration line-by-line: + # 1. Allow use of flakes. + # 2. When running GC, keep .drv files. + # 3. When running GC, keep build dependencies. + # 4. Run GC automatically when there's a 50 GB or less free space. nix.extraOptions = '' experimental-features = nix-command flakes keep-derivations = true @@ -12,7 +25,11 @@ min-free = ${toString(50 * 1000 * 1000 * 1000)} ''; - # max-free = ${toString(10 * 1024 * 1024 * 1024)} + # NOTE: Currently I run GC completely, but this setting (put above near min-free) + # can stop GC when you hit 101 GB of free space available. + # max-free = ${toString(101 * 1024 * 1024 * 1024)} + + # NOTE: Enable this if you want to run GC on schedule. I instead use `min-free`. # nix.gc = { # automatic = true; # dates = "weekly"; diff --git a/module/common/Nvim.nix b/module/common/Nvim.nix index 68a7ae8..29b8a62 100644 --- a/module/common/Nvim.nix +++ b/module/common/Nvim.nix @@ -3,19 +3,16 @@ in { environment = { variables = { - EDITOR = "nvim"; - MANPAGER = "nvim +Man!"; + EDITOR = "nvim"; # Use Nvim as a default editor. + MANPAGER = "nvim +Man!"; # Use Nvim to read man pages. }; systemPackages = with pkgs; [ - gcc + gcc # Required for Treesitter parsers. ]; }; + programs.neovim = { - enable = true; - viAlias = true; - vimAlias = true; - configure = { - customRC = nvim.config; - }; + enable = true; + configure.customRC = nvim.config; }; } diff --git a/module/common/Package.nix b/module/common/Package.nix index f37ac63..9091657 100644 --- a/module/common/Package.nix +++ b/module/common/Package.nix @@ -1,41 +1,40 @@ { pkgs, ... }: { + # List of common packages I use. environment.systemPackages = with pkgs; [ - binwalk - btop htop - coreutils - cryptsetup - curl - ddrescue testdisk - ffmpeg - file - gcc - gdu - gnumake - gnused - gparted - imagemagick - jdk jdk11 jdk19 jdk20 - jq - lm_sensors - lshw - lsof - ltex-ls - neofetch - nixd - nmap - parallel - parted - pv - ripgrep - scanmem - smartmontools - sqlite - tree - universal-android-debloater - usbutils - ventoy - wget - zip unzip + binwalk # Can analyze files for other files inside them. + btop htop # System monitors. + coreutils usbutils # Common utilities. + cryptsetup # Filesystem encryption (LUKS). + curl # CLI http client. + ddrescue testdisk # Apps to recover data from drives. + fastfetch # Systeminfo summary. + ffmpeg # Video/audio converter. + file # Get general info about a file. + gcc # C compiler. + gdu # TUI storage analyzer. + gnumake gnused # GNU utils. + gparted parted # GUI/CLI disk partition tool. + imagemagick # Image converter and transformation tool. + jdk # Java. + jq # Json parser. + lm_sensors # Hardware sensors, like temperature and fan speeds. + lshw # Detailed hardware info tool. + lsof # Find current file users. + ltex-ls # Latex LSP for neovim spellcheck. + nixd # Nix LSP. + nmap # Network analyzer. + parallel # Run programs in parallel. + pv # IO progress bar. + ripgrep # Grep for file search. + scanmem # Memory edit tool. + smartmontools # S.M.A.R.T. tools. + sqlite # Serverless file-based database engine. + tree # Show directory stricture as a tree. + ventoy # Boot multiple ISO/images from a single USB stick. + wget # CLI http download tool. + zip unzip # Zip archive/unarchive tools. + + universal-android-debloater # Debloat Android devices. ]; # Special packages. diff --git a/module/common/Podman.nix b/module/common/Podman.nix new file mode 100644 index 0000000..4f92f0d --- /dev/null +++ b/module/common/Podman.nix @@ -0,0 +1,14 @@ +{ ... }: { + virtualisation = { + podman = { + enable = true; + + # Free the 53 port ffs. + defaultNetwork.settings.dns_enabled = false; + + # Do not interfere with Docker so we can have both installed at the same time. + # Podman can't replace Docker anyway. + dockerCompat = false; + }; + }; +} diff --git a/module/common/Ssh.nix b/module/common/Ssh.nix index 0d71951..877e0a8 100644 --- a/module/common/Ssh.nix +++ b/module/common/Ssh.nix @@ -1,6 +1,8 @@ { pkgs, util, ... } @args: let ssh = import ./ssh args; in { + programs.ssh.extraConfig = ssh.config; + + # Add SSHFS to mount remote filesystems over SSH. environment.systemPackages = with pkgs; [ sshfs ]; - programs.ssh.extraConfig = ssh.config; } diff --git a/module/common/Sshd.nix b/module/common/Sshd.nix index d429b48..d872e89 100644 --- a/module/common/Sshd.nix +++ b/module/common/Sshd.nix @@ -1,5 +1,6 @@ { secret, ... }: { users.users.root.openssh.authorizedKeys.keys = secret.ssh.trustedKeys; + services.openssh = { enable = true; allowSFTP = true; diff --git a/module/common/Stylix.nix b/module/common/Stylix.nix index 82b9d2f..a8c1247 100644 --- a/module/common/Stylix.nix +++ b/module/common/Stylix.nix @@ -1,7 +1,11 @@ { pkgs, config, wallpaper, ... }: let + # Sometimes stylix does not generate enough contrast for text. + # This setting forces white text to ensure contrast on dark backgrounds. forceWhiteText = false; in { + # Add a permanent link for the wallpaper to /etc/wallpaper. environment.etc.wallpaper.source = wallpaper.path; + stylix = { image = wallpaper.path; autoEnable = true; diff --git a/module/common/Swap.nix b/module/common/Swap.nix index 88b99ca..24b1318 100644 --- a/module/common/Swap.nix +++ b/module/common/Swap.nix @@ -1,4 +1,3 @@ { ... }: { zramSwap.enable = true; - swapDevices = [ ]; } diff --git a/module/common/Users.nix b/module/common/Users.nix index 8037eb9..6f7c8ea 100644 --- a/module/common/Users.nix +++ b/module/common/Users.nix @@ -1,4 +1,7 @@ { ... }: { + # Default UMASK. security.loginDefs.settings.UMASK = "077"; + + # Disallow users modification outside of this config. users.mutableUsers = false; } diff --git a/module/common/YtDlp.nix b/module/common/YtDlp.nix index b73c63e..191498a 100644 --- a/module/common/YtDlp.nix +++ b/module/common/YtDlp.nix @@ -1,4 +1,6 @@ { pkgs, ... }: { + # Instead of overlaying and rebuilding YtDlp I download the release from + # GitHub and patch it for Nix. environment.systemPackages = with pkgs; [ (pkgs.callPackage ./ytdlp {}) ]; diff --git a/module/common/applefont/default.nix b/module/common/applefont/default.nix index ddc5897..5e4bf5e 100644 --- a/module/common/applefont/default.nix +++ b/module/common/applefont/default.nix @@ -1,3 +1,6 @@ +# Apple San Francisco and New York fonts. +# They are not available in Nixpkgs repo, so this script +# downloads the fonts from Apple website and adds them to Nix store. { lib, stdenv, fetchurl, p7zip }: let pro = fetchurl { url = "https://devimages-cdn.apple.com/design/resources/download/SF-Pro.dmg"; diff --git a/module/common/bash/default.nix b/module/common/bash/default.nix index e90af23..288e184 100644 --- a/module/common/bash/default.nix +++ b/module/common/bash/default.nix @@ -4,12 +4,7 @@ in { inherit modules; - config = util.trimTabs ('' - # If not running interactively, don't do anything. - # [[ "$-" != *i* ]] && return - - '') + modules + util.trimTabs ('' - + config = modules + util.trimTabs ('' # Find all functions. function find_function() { /usr/bin/env cat ${modulesFile} | /usr/bin/env grep "^function.*()" | /usr/bin/env sed -e "s/^function //" -e "s/().*//" diff --git a/module/common/nvim/default.nix b/module/common/nvim/default.nix index c84f9ce..2f9f66b 100644 --- a/module/common/nvim/default.nix +++ b/module/common/nvim/default.nix @@ -1,17 +1,19 @@ { inputs, pkgs, util, key, ... } @args: let - nvimRc = { runtimes, cfgs }: let - runtimeRc = builtins.foldl' (acc: r: + # Create Neovim configuration. + nvimRc = { runtimes, configs }: let + # Plugin paths to install. + runtimeRc = util.trimTabs (builtins.foldl' (acc: r: acc + "set runtimepath+=${r}\n" - ) "" runtimes; + ) "" runtimes); - config = pkgs.writeText "nvimRc" (builtins.foldl' (acc: cfg: - acc + (import cfg args).text - ) "" cfgs); + # My configuration files combined into one big file. + config = pkgs.writeText "nvimRc" (util.catText configs args); - cfgRc = "lua dofile(\"${config}\")"; - in runtimeRc + cfgRc; + # Tell Neovim to load this file. + configRc = "lua dofile(\"${config}\")"; + in runtimeRc + configRc; in { - config = util.trimTabs (nvimRc { + config = nvimRc { runtimes = [ "~/.cache/nvim" "~/.cache/nvim/treesitter" @@ -36,7 +38,8 @@ in { "${inputs.nvimTrouble}" "${inputs.nvimWhichKey}" ]; - cfgs = [ + + configs = [ ./module/key/Rekey.nix ./module/key/Leader.nix ./module/config/Autoread.nix @@ -79,5 +82,5 @@ in { ./module/key/Trouble.nix ./module/key/Whichkey.nix ]; - }); + }; } diff --git a/module/common/ssh/default.nix b/module/common/ssh/default.nix index 58590cc..f94e638 100644 --- a/module/common/ssh/default.nix +++ b/module/common/ssh/default.nix @@ -1,3 +1,4 @@ +# SSH client configuration. { util, ... }: { config = util.trimTabs '' Host dasha diff --git a/module/common/stylix/Gruvbox.yaml b/module/common/stylix/Gruvbox.yaml deleted file mode 100644 index e362226..0000000 --- a/module/common/stylix/Gruvbox.yaml +++ /dev/null @@ -1,18 +0,0 @@ -scheme: "Gruvbox" -author: "voronind" -base00: "121212" # Background. -base01: "212526" # Line cursor. -base02: "38403f" # Statusline. -base03: "47433e" # Line numbers. -base04: "6e78a1" # Selected line number. -base05: "b3afaf" # Foreground. -base06: "d8a9a9" # Function. -base07: "fcf4de" # Bright yellow. -base08: "a74049" # Cyan. -base09: "d35f5a" # Blue. -base0A: "ac5d5d" # Yellow. -base0B: "9f7b7b" # String green. -base0C: "3a877e" # Comment green. -base0D: "686995" # Purple. -base0E: "84abab" # Orange. -base0F: "9e446f" # Gray. diff --git a/module/common/tmux/module/Config.nix b/module/common/tmux/module/Config.nix index c2c73b4..73eaae6 100644 --- a/module/common/tmux/module/Config.nix +++ b/module/common/tmux/module/Config.nix @@ -2,6 +2,7 @@ mod = key.tmux.mod; in { text = '' + unbind-key C-b bind -n ${mod}-${key.tmux.reload} source-file /etc/tmux.conf ''; } diff --git a/module/desktop/App.nix b/module/desktop/App.nix index 05a418a..b5a96ce 100644 --- a/module/desktop/App.nix +++ b/module/desktop/App.nix @@ -30,21 +30,28 @@ in { environment = { systemPackages = with pkgs; [ - android-studio jetbrains.idea-community - appimage-run - aseprite - blender-hip - bottles dxvk gamescope pkgs.mangohud vkd3d wine64 - calibre - gimp - godot_4 - jellyfin-media-player - (mpv.override {scripts = [mpvScripts.mpris];}) - obs-studio - onlyoffice-bin - scanmem - steam-run - tor-browser + adwsteamgtk # Steam GTK theme. Need to run the app to apply. + appimage-run # Tool to run .AppImage files in NixOS. + aseprite # Pixel Art draw app. WARNING: Always builds from source. + blender-hip # Blender with HiP support. + calibre # Book library manager. + evince # Document viewer. + gimp # Image manipulation program. + gnome.adwaita-icon-theme # GTK icons. + gnome.gnome-calculator # Calculator. + gnome.gnome-font-viewer # Font viewer. + gnome.nautilus # File manager. + godot_4 # Game development engine. + jellyfin-media-player # Jellyfin client (self-hosted Netflix). + loupe # Image viewer. + obs-studio # Streaming/recording app. + onlyoffice-bin # Office documents app suite. + steam-run # Run native apps in Steam environment, like Minecraft. For Windows games use Bottles. + tor-browser # Privacy browser. + + android-studio jetbrains.idea-community # JetBrans IDEs. + bottles dxvk gamescope pkgs.mangohud vkd3d wine64 # Gaming! + (mpv.override {scripts = [mpvScripts.mpris];}) # Media player. ]; variables = { @@ -58,6 +65,12 @@ in { }; }; + # File manager file previews. + services.gnome.sushi.enable = true; + + # File manager network features. + services.gvfs.enable = true; + # Special packages. programs.steam.enable = true; } diff --git a/module/desktop/Dconf.nix b/module/desktop/Dconf.nix index 7880392..45590df 100644 --- a/module/desktop/Dconf.nix +++ b/module/desktop/Dconf.nix @@ -1,6 +1,7 @@ { lib, key, ... }: let mod = key.gnome.mod; in { + # Gnome DE and GTK apps configuration. programs.dconf.enable = true; programs.dconf.profiles.user = { enableUserDb = true; # Delete `~/.config/dconf/user` to reset user settings. diff --git a/module/desktop/DisplayManager.nix b/module/desktop/DisplayManager.nix index 8759508..ff5461a 100644 --- a/module/desktop/DisplayManager.nix +++ b/module/desktop/DisplayManager.nix @@ -4,6 +4,6 @@ services.xserver.desktopManager.gnome.enable = true; services.xserver.xkb = { layout = "us,ru"; - options = "grp:caps_toggle,lv3:ralt_switch"; + options = "grp:toggle"; }; } diff --git a/module/desktop/GnomeApps.nix b/module/desktop/GnomeApps.nix deleted file mode 100644 index ad57673..0000000 --- a/module/desktop/GnomeApps.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ pkgs, ... }: { - environment.systemPackages = with pkgs; [ - adwsteamgtk - evince - gnome.adwaita-icon-theme - gnome.gnome-calculator - gnome.nautilus - loupe - gnome.gnome-font-viewer - # gnome.gnome-keyring - ]; - - # Nautilus previews. - services.gnome.sushi.enable = true; - - # Nautilus network. - services.gvfs.enable = true; -} diff --git a/module/desktop/Polkit.nix b/module/desktop/Polkit.nix index 400d19b..b07cd3d 100644 --- a/module/desktop/Polkit.nix +++ b/module/desktop/Polkit.nix @@ -1,3 +1,4 @@ +# Polkit agent is used by apps to ask for Root password with a popup. { pkgs, lib, ... }: { security.polkit.enable = true; systemd = { diff --git a/module/desktop/Portal.nix b/module/desktop/Portal.nix index bc8c1b2..484c471 100644 --- a/module/desktop/Portal.nix +++ b/module/desktop/Portal.nix @@ -1,3 +1,4 @@ +# Portals are needed for Wayland apps to select files, screen shares etc. { pkgs, ... }: { xdg.portal = { enable = true; diff --git a/module/desktop/Realtime.nix b/module/desktop/Realtime.nix index a3b7164..02841fa 100644 --- a/module/desktop/Realtime.nix +++ b/module/desktop/Realtime.nix @@ -1,3 +1,4 @@ +# Improve DE performance. { ... }: { security.pam.loginLimits = [ { domain = "@users"; item = "rtprio"; type = "-"; value = 1; } diff --git a/module/desktop/Systemd.nix b/module/desktop/Systemd.nix index ff6a43f..182b9e0 100644 --- a/module/desktop/Systemd.nix +++ b/module/desktop/Systemd.nix @@ -1,4 +1,5 @@ { ... }: { + # Systemd custom target for Sway. systemd.user.targets.gui-session = { after = [ "graphical-session-pre.target" ]; bindsTo = [ "graphical-session.target" ]; diff --git a/module/desktop/Waybar.nix b/module/desktop/Waybar.nix index 849a9dd..56e4239 100644 --- a/module/desktop/Waybar.nix +++ b/module/desktop/Waybar.nix @@ -2,6 +2,9 @@ waybar = import ./waybar args; in { programs.waybar.enable = true; - environment.variables.WAYBAR_CONFIG = pkgs.writeText "waybarConfig" waybar.config; - environment.variables.WAYBAR_STYLE = pkgs.writeText "waybarStyle" waybar.style; + + environment.variables = { + WAYBAR_CONFIG = pkgs.writeText "waybarConfig" waybar.config; + WAYBAR_STYLE = pkgs.writeText "waybarStyle" waybar.style; + }; } diff --git a/module/desktop/Wayland.nix b/module/desktop/Wayland.nix new file mode 100644 index 0000000..65b54bb --- /dev/null +++ b/module/desktop/Wayland.nix @@ -0,0 +1,5 @@ +{ pkgs, ... }: { + environment.systemPackages = with pkgs; [ + wl-clipboard + ]; +} diff --git a/module/desktop/firefox/default.nix b/module/desktop/firefox/default.nix index 87ea620..34a0c36 100644 --- a/module/desktop/firefox/default.nix +++ b/module/desktop/firefox/default.nix @@ -35,6 +35,7 @@ in { ]; ExtensionUpdate = true; ExtensionSettings = { + # Block extension installation outside of this config. "*" = { install_sources = [ "*" ]; installation_mode = "blocked"; @@ -45,9 +46,11 @@ in { "{446900e4-71c2-419f-a6a7-df9c091e268b}" = mkExtension "https://addons.mozilla.org/firefox/downloads/latest/bitwarden-password-manager/latest.xpi"; "{d7742d87-e61d-4b78-b8a1-b469842139fa}" = mkExtension "https://addons.mozilla.org/firefox/downloads/latest/vimium-ff/latest.xpi"; "{e7625f06-e252-479d-ac7a-db68aeaff2cb}" = mkExtension "https://addons.mozilla.org/firefox/downloads/latest/togglefonts/latest.xpi"; + # NOTE: This extension is helpful to find the required parameters for this config. + # Or find them yourself inside the `about:support`. # "queryamoid@kaply.com" = mkExtension "https://github.com/mkaply/queryamoid/releases/download/v0.1/query_amo_addon_id-0.1-fx.xpi"; - # "{08d5243b-4236-4a27-984b-1ded22ce01c3}" = mkExtension "https://addons.mozilla.org/firefox/downloads/latest/gruvboxgruvboxgruvboxgruvboxgr/latest.xpi"; }; + # NOTE: `firefox-esr` edition is required to change default search engine. SearchEngines = { Default = "Whoogle"; Add = [ diff --git a/module/desktop/waybar/style/Button.nix b/module/desktop/waybar/style/Button.nix deleted file mode 100644 index 5df2377..0000000 --- a/module/desktop/waybar/style/Button.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ ... }: { - text = '' - 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; - } - - /* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ - button:hover { - background: inherit; - box-shadow: inset 0 -3px #ffffff; - } - ''; -} diff --git a/module/desktop/waybar/style/Font.nix b/module/desktop/waybar/style/Font.nix index 78cfd04..7d0bde7 100644 --- a/module/desktop/waybar/style/Font.nix +++ b/module/desktop/waybar/style/Font.nix @@ -1,7 +1,6 @@ { style, ... }: { text = '' * { - /* `otf-font-awesome` is required to be installed for icons */ font-family: "${style.font.serif.name}", "Terminess Nerd Font Propo"; font-size: ${toString(style.font.size.desktop)}px; } diff --git a/module/powerlimit/Script.nix b/module/powerlimit/Script.nix new file mode 100644 index 0000000..5820f49 --- /dev/null +++ b/module/powerlimit/Script.nix @@ -0,0 +1,34 @@ +{ controlFileMax +, controlFileMin +, onMax +, onMin +, offMax +, offMin +, ... }: { + script = '' + function toggle() { + if status; then + echo ${offMax} > ${controlFileMax} + echo ${offMin} > ${controlFileMin} + else + echo ${onMin} > ${controlFileMin} + echo ${onMax} > ${controlFileMax} + fi + + true + } + + function waybar() { + status || echo -n "" + } + + function status() { + local current=$(cat ${controlFileMax}) + local enabled="${onMax}" + + [[ "''${current}" = "''${enabled}" ]] + } + + ''${@} + ''; +} diff --git a/module/powerlimit/default.nix b/module/powerlimit/default.nix new file mode 100644 index 0000000..cd68af7 --- /dev/null +++ b/module/powerlimit/default.nix @@ -0,0 +1,31 @@ +# Control battery charge limits. Control with `powerlimit` script. +{ pkgs +, lib +, controlFileMax +, controlFileMin +, onMax +, onMin +, offMax +, offMin +, ... }: { + systemd = { + services.powerlimit = { + description = "Limit battery charge."; + enable = true; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "simple"; + RemainAfterExit = "yes"; + ExecStart = "${lib.getExe pkgs.bash} -c 'echo ${onMin} > ${controlFileMin}; echo ${onMax} > ${controlFileMax};'"; + ExecStop = "${lib.getExe pkgs.bash} -c 'echo ${offMax} > ${controlFileMax}; echo ${offMin} > ${controlFileMin};'"; + }; + }; + + # HACK: Allow user access. + tmpfiles.rules = [ + "z ${controlFileMax} 0777 - - - -" + "z ${controlFileMin} 0777 - - - -" + ]; + }; +} + diff --git a/module/powersave/Script.nix b/module/powersave/Script.nix index 2a1a8c8..73cc186 100644 --- a/module/powersave/Script.nix +++ b/module/powersave/Script.nix @@ -1,3 +1,4 @@ +# Script to control CPU boost. { controlFile, enable, disable, ... }: { script = '' function toggle() { diff --git a/module/powersave/default.nix b/module/powersave/default.nix index 7432d41..14346ea 100644 --- a/module/powersave/default.nix +++ b/module/powersave/default.nix @@ -1,3 +1,4 @@ +# Disable CPU boost after boot. Control with `powersave` script. { lib, pkgs, controlFile, enable, disable, ... }: { systemd = { services.powersave = { diff --git a/module/sway/default.nix b/module/sway/default.nix index 35d5da9..d5bf9fb 100644 --- a/module/sway/default.nix +++ b/module/sway/default.nix @@ -1,4 +1,5 @@ { pkgs, wallpaper, style, util, setting, ... } @args: let + # Order is required for Sway configuration. swayRc = util.catText [ ./module/Style.nix ./module/Display.nix diff --git a/module/sway/module/Input.nix b/module/sway/module/Input.nix index 9f57c62..d181396 100644 --- a/module/sway/module/Input.nix +++ b/module/sway/module/Input.nix @@ -34,7 +34,7 @@ input type:keyboard { xkb_layout us,ru - xkb_options grp:caps_toggle + xkb_options grp:toggle } # Hide mouse cursor after a period of inactivity. diff --git a/module/sway/script/Monitor.nix b/module/sway/script/Monitor.nix index 6d33c1a..2300133 100644 --- a/module/sway/script/Monitor.nix +++ b/module/sway/script/Monitor.nix @@ -1,10 +1,17 @@ { ... }: { text = '' + export _swaymonlist=( + "ASUSTek COMPUTER INC ASUS VA24E R2LMTF127165" + "AU Optronics 0x418D Unknown" + ) + # Enable monitors. function monon() { on() { + for mon in ''${_swaymonlist[@]}; do + swaymsg "output \"''${mon}\" power on" + done _monstate on - swaymsg 'output "ASUSTek COMPUTER INC ASUS VA24E R2LMTF127165" power on' } _sway_iterate_sockets on } @@ -12,8 +19,10 @@ # Disable monitors. function monoff() { off() { + for mon in ''${_swaymonlist[@]}; do + swaymsg "output \"''${mon}\" power off" + done _monstate off - swaymsg 'output "ASUSTek COMPUTER INC ASUS VA24E R2LMTF127165" power off' } _sway_iterate_sockets off } diff --git a/module/sway/script/Vrr.nix b/module/sway/script/Vrr.nix index 645435a..81d6b51 100644 --- a/module/sway/script/Vrr.nix +++ b/module/sway/script/Vrr.nix @@ -1,10 +1,16 @@ { ... }: { text = '' + export _swayvrrlist=( + "Huawei Technologies Co., Inc. ZQE-CBA 0xC080F622" + ) + # Enable VRR. function vrron() { on() { + for vrr in ''${_swayvrrlist[@]}; do + swaymsg "output \"''${vrr}\" adaptive_sync on" + done _vrrstate on - swaymsg 'output "Huawei Technologies Co., Inc. ZQE-CBA 0xC080F622" adaptive_sync on' } _sway_iterate_sockets on } @@ -12,8 +18,10 @@ # Disable VRR. function vrroff() { off() { + for vrr in ''${_swayvrrlist[@]}; do + swaymsg "output \"''${vrr}\" adaptive_sync off" + done _vrrstate off - swaymsg 'output "Huawei Technologies Co., Inc. ZQE-CBA 0xC080F622" adaptive_sync off' } _sway_iterate_sockets off } diff --git a/overlay/Example.nix b/overlay/Example.nix index 0c4f326..88a5679 100644 --- a/overlay/Example.nix +++ b/overlay/Example.nix @@ -1,3 +1,7 @@ +# Example overlay file. +# Overlays can change parameters in package builds, like source version. +# This way you can change something in package without recreating the whole build process. +# More info: https://nixos.wiki/wiki/Overlays { ... }: { # nixpkgs.overlays = [ (final: prev: { # yt-dlp = prev.yt-dlp.overrideAttrs (old: { diff --git a/part/Key.nix b/part/Key.nix index 2a958c5..6c2df59 100644 --- a/part/Key.nix +++ b/part/Key.nix @@ -1,3 +1,4 @@ +# Keyboard keys configuration. { ... }: { navigation = { go = { diff --git a/part/Secret.nix b/part/Secret.nix index 46b5b97..0d70cd2 100644 --- a/part/Secret.nix +++ b/part/Secret.nix @@ -1,3 +1,4 @@ +# Secrets configuration. { ... }: { hashedPassword = "$y$j9T$oqCB16i5E2t1t/HAWaFd5.$tTaHtAcifXaDVpTcRv.yH2/eWKxKE9xM8KcqXHfHrD7"; # Use `mkpasswd`. diff --git a/part/Setting.nix b/part/Setting.nix index 9a1bd90..bd65dc2 100644 --- a/part/Setting.nix +++ b/part/Setting.nix @@ -1,3 +1,5 @@ +# Global settings. +# Just like I can configure each package, here I configure my config! :O) { ... }: { tmux = { resize.step = { diff --git a/part/Style.nix b/part/Style.nix index 13f8502..d99e3c6 100644 --- a/part/Style.nix +++ b/part/Style.nix @@ -1,3 +1,4 @@ +# Abstraction over Stylix. { config, ... }: { color = { bg = { diff --git a/part/Util.nix b/part/Util.nix index ff70dfc..e86262e 100644 --- a/part/Util.nix +++ b/part/Util.nix @@ -1,3 +1,4 @@ +# Collection of common functions. { pkgs, ... }: rec { # Remove tabs indentation, trimTabs = text: let diff --git a/user/Dasha.nix b/user/Dasha.nix index 94f7bb5..44714e3 100644 --- a/user/Dasha.nix +++ b/user/Dasha.nix @@ -1,4 +1,12 @@ -{ const, util, style, pkgs, lib, setting, key, secret, ... } @args: { +{ const +, util +, style +, pkgs +, lib +, setting +, key +, secret +, ... } @args: { imports = [ (import ./common (args // { username = "dasha"; diff --git a/user/Root.nix b/user/Root.nix index 2c7d3fa..fbdcd27 100644 --- a/user/Root.nix +++ b/user/Root.nix @@ -1,4 +1,11 @@ -{ const, util, style, pkgs, setting, key, secret, ... } @args: { +{ const +, util +, style +, pkgs +, setting +, key +, secret +, ... } @args: { imports = [ (import ./common (args // { username = "root"; diff --git a/user/Voronind.nix b/user/Voronind.nix index 2f14ed3..c6932c4 100644 --- a/user/Voronind.nix +++ b/user/Voronind.nix @@ -1,4 +1,12 @@ -{ const, util, style, pkgs, lib, setting, key, secret, ... } @args: { +{ const +, util +, style +, pkgs +, lib +, setting +, key +, secret +, ... } @args: { imports = [ (import ./common (args // { username = "voronind"; diff --git a/user/common/default.nix b/user/common/default.nix index 7d2b91b..e2f70e7 100644 --- a/user/common/default.nix +++ b/user/common/default.nix @@ -1,3 +1,4 @@ +# This is a common user configuration. { const , homeDir , key @@ -8,6 +9,7 @@ , username , util , ... } @args: let + # Configuration modules. btop = import ./top/btop args; editorconfig = import ./editorconfig args; foot = import ./foot args; @@ -17,6 +19,7 @@ mako = import ./mako args; in { home-manager = { + # If file exists, rename it with a new extension. backupFileExtension = "old"; users.${username} = {