Compare commits

..

22 commits

Author SHA1 Message Date
Dmitry Voronin b53969c87a
Idea : Fix shift keys. 2024-05-13 13:29:22 +03:00
Dmitry Voronin a24b5bdd99
Secret : Add comments. 2024-05-12 04:22:57 +03:00
Dmitry Voronin 16d734d81e
Dconf : Split config. 2024-05-12 03:05:31 +03:00
Dmitry Voronin a2f4c737a1
Sway : Move config to desktop module. 2024-05-12 02:17:20 +03:00
Dmitry Voronin 5ad546abd2
Readme : Add current wallpaper link. 2024-05-12 01:16:12 +03:00
Dmitry Voronin 5b3286434a
Readme : Fix wallpaper link. 2024-05-12 01:10:53 +03:00
Dmitry Voronin 97559710c5
Honey wake up, a documentation update just dropped. 2024-05-12 01:03:38 +03:00
Dmitry Voronin 6236a8e65b
Home : Make services switch-independent. 2024-05-10 20:34:15 +03:00
Dmitry Voronin 0fd72bc32c
DRG : Add delays for chat macros. 2024-05-09 03:19:18 +03:00
Dmitry Voronin 4bd377c94d
Waybar : Swap sound clicks. 2024-05-09 00:42:12 +03:00
Dmitry Voronin a190f35e8f
Keyd : Move system controls to Sway. 2024-05-09 00:20:56 +03:00
Dmitry Voronin 338b65429f
Waybar : Fix scratchpad kill. 2024-05-08 23:54:06 +03:00
Dmitry Voronin 0ac1617f7f
Sway : Extra notes for keyd issue. 2024-05-08 23:42:54 +03:00
Dmitry Voronin 702e57dba3
Waybar : Disable broken temperature. 2024-05-08 22:34:32 +03:00
Dmitry Voronin c8c343e0d7
Home : Fix backup path. 2024-05-08 22:27:10 +03:00
Dmitry Voronin b88a17524e
Waybar : Add a hack for tooltip. 2024-05-08 21:53:43 +03:00
Dmitry Voronin 700a0d9a39
Waybar : Disable breaking tooltip temporarely. 2024-05-08 21:38:15 +03:00
Dmitry Voronin 4087367124
Home : Fix backup archive changes. 2024-05-08 21:19:35 +03:00
Dmitry Voronin 83a5c4122a
Sway : Add tooltip for display. 2024-05-08 21:16:11 +03:00
Dmitry Voronin 97645805aa
Swayscript : Add default pring outputs. 2024-05-08 19:50:09 +03:00
Dmitry Voronin 54d6370d1a
Sway : Fix default vrr state. 2024-05-08 19:22:04 +03:00
Dmitry Voronin 5048ab2e99
Waybar : Add vrr/mon toggle. 2024-05-08 19:19:59 +03:00
146 changed files with 1148 additions and 881 deletions

55
Readme.md Normal file
View file

@ -0,0 +1,55 @@
# Voronind NixOS configuration.
## Screenshot.
![Screenshot](https://i.imgur.com/aGmmVJa.png)
[Wallpaper from the Screenshot](https://git.voronind.com/voronind/nixos/src/commit/97559710c57f81e42a32b11139d6d4c3dff20ab3/part/Wallpaper.nix#L2)
[My current wallpaper](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.

152
flake.nix
View file

@ -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 = { 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"; 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 = { home-manager = {
url = "github:nix-community/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"; 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 = { nix-on-droid = {
url = "github:t184256/nix-on-droid/release-23.05"; url = "github:t184256/nix-on-droid/release-23.05";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager"; 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 = { nvimAlign = {
url = "github:echasnovski/mini.align"; url = "github:echasnovski/mini.align";
flake = false; 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: { outputs = { self, nixpkgs, nix-on-droid, home-manager, stylix, ... } @inputs: {
# Constant values. # Constant values.
const = { const = {
@ -107,51 +130,79 @@
url = "https://git.voronind.com/voronind/nixos.git"; url = "https://git.voronind.com/voronind/nixos.git";
}; };
# Common modules used across all hosts. # Common modules used across all the hosts.
nixosModules.common = let 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}") ( lsFiles = path: map (f: "${path}/${f}") (
builtins.filter (i: builtins.readFileType "${path}/${i}" == "regular") ( builtins.filter (i: builtins.readFileType "${path}/${i}" == "regular") (
builtins.attrNames (builtins.readDir path) builtins.attrNames (builtins.readDir path)
) )
); );
in { in {
# Here I import everything from those directories.
imports = (lsFiles ./module/common) ++ (lsFiles ./overlay) ++ [ ./user/Root.nix ]; 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 { 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; inherit system;
# List of modules to use by defualt for all the hosts.
modules = [ modules = [
./host/${hostname}/Configuration.nix # There I put host-specific configurations.
{ networking.hostName = hostname; } ./host/${hostname}
{ system.stateVersion = self.const.stateVersion; }
inputs.self.nixosModules.common
home-manager.nixosModules.home-manager
stylix.nixosModules.stylix
] ++ modules;
# 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 specialArgs = let
pkgs = nixpkgs.legacyPackages.${system}.pkgs; pkgs = nixpkgs.legacyPackages.${system}.pkgs;
lib = nixpkgs.lib;
config = self.nixosConfigurations.${hostname}.config; config = self.nixosConfigurations.${hostname}.config;
in { in {
const = self.const; const = self.const; # Constant values.
flake = self; flake = self; # This Flake itself.
inputs = inputs; inputs = inputs; # Our dependencies.
key = import ./part/Key.nix {}; key = import ./part/Key.nix {}; # Keyboard keys config.
secret = import ./part/Secret.nix {}; secret = import ./part/Secret.nix {}; # Secrets (public keys).
setting = import ./part/Setting.nix {}; setting = import ./part/Setting.nix {}; # My own global settings.
style = import ./part/Style.nix { config = config; }; style = import ./part/Style.nix { inherit config; }; # Style abstraction.
util = import ./part/Util.nix { pkgs = pkgs; }; util = import ./part/Util.nix { inherit pkgs lib; }; # Util functions.
wallpaper = import ./part/Wallpaper.nix { pkgs = pkgs; }; wallpaper = import ./part/Wallpaper.nix { inherit 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 { nixosConfigurations.basic = self.mkHost {
hostname = "basic"; hostname = "basic"; # Hostname to use.
system = "x86_64-linux"; system = "x86_64-linux"; # System architecture.
# Host-specific modules.
modules = [ modules = [
# Force LTS kernel.
({ pkgs, ... }: { boot.kernelPackages = nixpkgs.lib.mkForce pkgs.linuxPackages; }) ({ pkgs, ... }: { boot.kernelPackages = nixpkgs.lib.mkForce pkgs.linuxPackages; })
]; ];
}; };
@ -161,11 +212,14 @@
system = "x86_64-linux"; system = "x86_64-linux";
modules = [ modules = [
./module/AmdGpu.nix ./module/AmdGpu.nix
./module/CapsToggle.nix
./module/Gnome.nix ./module/Gnome.nix
./module/IntelCpu.nix ./module/IntelCpu.nix
./module/PowersaveIntel.nix ./module/PowersaveIntel.nix
./module/Print.nix ./module/Print.nix
./module/RemoteBuild.nix ./module/RemoteBuild.nix
./module/StrongSwan.nix
./module/Tablet.nix
./user/Dasha.nix ./user/Dasha.nix
]; ];
}; };
@ -177,7 +231,7 @@
./module/AmdCompute.nix ./module/AmdCompute.nix
./module/AmdCpu.nix ./module/AmdCpu.nix
./module/AmdGpu.nix ./module/AmdGpu.nix
# ./module/Ollama.nix # ./module/Ollama.nix # ISSUE: Currently broken.
./module/PowersaveAmd.nix ./module/PowersaveAmd.nix
./module/Print.nix ./module/Print.nix
./module/RemoteBuild.nix ./module/RemoteBuild.nix
@ -215,25 +269,41 @@
modules = [ modules = [
./module/AmdCpu.nix ./module/AmdCpu.nix
./module/AmdGpu.nix ./module/AmdGpu.nix
./module/CapsToggle.nix
./module/Gnome.nix ./module/Gnome.nix
./module/PowersaveAmd.nix ./module/PowersaveAmd.nix
./module/Print.nix ./module/Print.nix
./module/RemoteBuild.nix ./module/RemoteBuild.nix
./module/StrongSwan.nix
./module/Tablet.nix
./user/Dasha.nix ./user/Dasha.nix
./user/Voronind.nix ./user/Voronind.nix
]; ];
}; };
# Live ISO configuration.
nixosConfigurations.live = self.mkHost { nixosConfigurations.live = self.mkHost {
hostname = "live"; hostname = "live";
system = "x86_64-linux"; system = "x86_64-linux";
modules = [ 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/installation-cd-minimal.nix"
"${nixpkgs}/nixos/modules/installer/cd-dvd/channel.nix" "${nixpkgs}/nixos/modules/installer/cd-dvd/channel.nix"
# 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; } { 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.PasswordAuthentication = nixpkgs.lib.mkForce true; }
{ services.openssh.settings.PermitRootLogin = nixpkgs.lib.mkForce "yes"; } { services.openssh.settings.PermitRootLogin = nixpkgs.lib.mkForce "yes"; }
{ system.autoUpgrade.enable = nixpkgs.lib.mkForce false; }
# 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; }) ({ pkgs, ... }: { boot.kernelPackages = nixpkgs.lib.mkForce pkgs.linuxPackages; })
]; ];
}; };
@ -243,8 +313,7 @@
system = "x86_64-linux"; system = "x86_64-linux";
modules = [ modules = [
./module/IntelCpu.nix ./module/IntelCpu.nix
# ./module/Ollama.nix ./module/PowerlimitThinkpad.nix
./module/Powerlimit.nix
./module/PowersaveIntel.nix ./module/PowersaveIntel.nix
./module/Print.nix ./module/Print.nix
./module/RemoteBuild.nix ./module/RemoteBuild.nix
@ -256,22 +325,29 @@
# Android. # Android.
nixOnDroidConfigurations.default = nix-on-droid.lib.nixOnDroidConfiguration { nixOnDroidConfigurations.default = nix-on-droid.lib.nixOnDroidConfiguration {
modules = [ modules = [
# Android release version.
{ system.stateVersion = inputs.self.const.droidStateVersion; } { 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 extraSpecialArgs = let
# We want arm64 packages for Android.
pkgs = nixpkgs.legacyPackages."aarch64-linux".pkgs; pkgs = nixpkgs.legacyPackages."aarch64-linux".pkgs;
lib = nixpkgs.lib;
in { in {
const = self.const; const = self.const; # Constant values.
flake = self; flake = self; # This Flake itself.
inputs = inputs; inputs = inputs; # Our dependencies.
key = import ./part/Key.nix {}; key = import ./part/Key.nix {}; # Keyboard keys config.
secret = import ./part/Secret.nix {}; secret = import ./part/Secret.nix {}; # Secrets (public keys).
setting = import ./part/Setting.nix {}; setting = import ./part/Setting.nix {}; # My own global settings.
style = import ./part/Style.nix { config = import ./part/style/Gruvbox.nix {}; }; 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 = import ./part/Util.nix { inherit pkgs lib; }; # Util functions.
}; };
}; };
}; };
} }
# That's it!

5
host/basic/default.nix Normal file
View file

@ -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 = [ ];
}

View file

@ -1,7 +1,6 @@
{ lib, ... }: { { lib, ... }: {
imports = [ imports = [
./Filesystem.nix ./Filesystem.nix
../dasha/Tablet.nix
]; ];
# Disable keyd. # Disable keyd.

View file

@ -1,4 +1,5 @@
{ lib, ... }: { { lib, ... }: {
# This host is running inside BIOS VM so it needs the Grub.
boot.loader.systemd-boot.enable = lib.mkForce false; boot.loader.systemd-boot.enable = lib.mkForce false;
boot.loader.efi.canTouchEfiVariables = lib.mkForce false; boot.loader.efi.canTouchEfiVariables = lib.mkForce false;
boot.loader.grub.enable = true; boot.loader.grub.enable = true;

View file

@ -1,3 +1,8 @@
{ lib, ... }: { { lib, ... }: {
# Force specific PW for this host.
users.users.root.hashedPassword = lib.mkForce "$y$j9T$d4HfwutZr.eNHuLJYRuro/$7swZfgCNS6jEXHFCxsW5um/68jX9BRiiZD1BYcm/gD/"; 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";
} }

View file

@ -33,17 +33,17 @@
# Save media list. # Save media list.
find ''${path_media} -type d > ''${path_backup}/cold/ColdMedia.txt || report "Backup : Failed to save media list!" find ''${path_media} -type d > ''${path_backup}/cold/ColdMedia.txt || report "Backup : Failed to save media list!"
cd ''${path_backup}/cold/ cd ''${path_backup}/cold/
archive_fast ColdMedia.txt && rm ColdMedia.txt || report "Backup : Failed to archive media list!" archive ColdMedia.txt && rm ColdMedia.txt || report "Backup : Failed to archive media list!"
cd - cd -
# Backup docker. # Backup docker.
docker=$(archive_fast docker/) docker=$(archive docker/)
bupsize=$(tdu ''${docker} | awk '{print $1}') bupsize=$(tdu ''${docker} | awk '{print $1}')
mv ''${docker} ''${path_docker}/ || report "Backup : Failed to save docker!" mv ''${docker} ''${path_docker}/ || report "Backup : Failed to save docker!"
# Backup some media. # Backup some media.
cd ''${path_src}/media/ cd ''${path_src}/media/
paper=$(archive_fast paper/) paper=$(archive paper/)
mv ''${paper} ''${path_backup}/paper/ || report "Backup : Failed to save paper!" mv ''${paper} ''${path_backup}/paper/ || report "Backup : Failed to save paper!"
cd - cd -
@ -74,7 +74,7 @@
echo "Backup : Complete ''${bupsize}." echo "Backup : Complete ''${bupsize}."
''; '';
in { in {
systemd.services.backup = { systemd.services.backup = util.mkStaticSystemdService {
enable = true; enable = true;
description = "Home system backup."; description = "Home system backup.";
serviceConfig = { serviceConfig = {
@ -83,10 +83,11 @@ in {
path = with pkgs; [ path = with pkgs; [
bashInteractive bashInteractive
curl curl
gnutar
gzip
gawk gawk
gnutar
procps
pv pv
xz
]; ];
script = '' script = ''
${pkgs.bashInteractive}/bin/bash ${script} ${pkgs.bashInteractive}/bin/bash ${script}

View file

@ -4,7 +4,7 @@
docker exec -u 33 cloud php -f /var/www/html/cron.php || notify 'Nextcloud : Failed to run cron.' docker exec -u 33 cloud php -f /var/www/html/cron.php || notify 'Nextcloud : Failed to run cron.'
''; '';
in { in {
systemd.services.nextcloud = { systemd.services.nextcloud = util.mkStaticSystemdService {
enable = true; enable = true;
description = "Nextcloud worker."; description = "Nextcloud worker.";
serviceConfig = { serviceConfig = {

View file

@ -1,11 +1,11 @@
{ pkgs, ... }: let { pkgs, util, ... }: let
script = '' script = ''
in="/storage/hot/docker/cloud/data/data/cakee/files/media/photo/" in="/storage/hot/docker/cloud/data/data/cakee/files/media/photo/"
out="/storage/cold_1/backup/tmp/photo/" out="/storage/cold_1/backup/tmp/photo/"
docker run --rm -v "''${in}":/in -v "''${out}":/out voronind.com/photoprocess:latest docker run --rm -v "''${in}":/in -v "''${out}":/out voronind.com/photoprocess:latest
''; '';
in { in {
systemd.services.photos_process = { systemd.services.photos_process = util.mkStaticSystemdService {
enable = true; enable = true;
description = "Process uploaded photos."; description = "Process uploaded photos.";
serviceConfig = { serviceConfig = {

View file

@ -1,10 +1,10 @@
{ pkgs, ... }: let { pkgs, util, ... }: let
script = '' script = ''
music="/storage/hot/media/music/" music="/storage/hot/media/music/"
docker run --rm -v "''${music}":/music voronind.com/yamusic:latest docker run --rm -v "''${music}":/music voronind.com/yamusic:latest
''; '';
in { in {
systemd.services.yandex_music = { systemd.services.yandex_music = util.mkStaticSystemdService {
enable = true; enable = true;
description = "Sync music from Yandex.Music."; description = "Sync music from Yandex.Music.";
serviceConfig = { serviceConfig = {

View file

@ -1,8 +1,6 @@
{ lib, ... }: { { lib, ... }: {
imports = [ imports = [
./Filesystem.nix ./Filesystem.nix
./Tablet.nix
./Vpn.nix
]; ];
# Disable keyd. # Disable keyd.

View file

@ -1,3 +0,0 @@
{ ... }: {
imports = [ ];
}

View file

@ -1,5 +0,0 @@
{ ... }: {
imports = [
./Fprint.nix
];
}

8
host/work/default.nix Normal file
View file

@ -0,0 +1,8 @@
{ ... }: {
imports = [
./Fprint.nix
];
# Keyd Print to Macro remap.
services.keyd.keyboards.default.settings.main.print = "layer(layer_macro)";
}

View file

@ -1,3 +1,4 @@
# AMD Rocm support (for Blender).
{ nixpkgs, pkgs, ... }: { { nixpkgs, pkgs, ... }: {
nixpkgs.config.rocmSupport = true; nixpkgs.config.rocmSupport = true;
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [

View file

@ -1,3 +1,4 @@
# AMD CPU specific configuration.
{ lib, config, ... }: { { lib, config, ... }: {
boot.kernelModules = [ "kvm-amd" ]; boot.kernelModules = [ "kvm-amd" ];
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;

View file

@ -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, ... }: { { nixpkgs, pkgs, ... }: {
boot.initrd.kernelModules = [ "amdgpu" ]; boot.initrd.kernelModules = [ "amdgpu" ];
services.xserver.videoDrivers = [ "amdgpu" ]; services.xserver.videoDrivers = [ "amdgpu" ];

6
module/CapsToggle.nix Normal file
View file

@ -0,0 +1,6 @@
# Toggle language with CapsLock. My wife prefers this.
{ lib, ... }: {
services.xserver.xkb = {
options = lib.mkForce "grp:caps_toggle";
};
}

View file

@ -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 {}
'';
};
}

View file

@ -4,17 +4,15 @@
./desktop/Dconf.nix ./desktop/Dconf.nix
./desktop/DisplayManager.nix ./desktop/DisplayManager.nix
./desktop/Sound.nix ./desktop/Sound.nix
./desktop/Wayland.nix
]; ];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
adwsteamgtk gnome.gnome-tweaks # Gnome "hidden" settings.
gnome.gnome-remote-desktop openssl # It was needed for something, can't remember.
gnome.gnome-tweaks
gradience
openssl
wl-clipboard
]; ];
# Disable some Gnome apps.
services.gnome.gnome-keyring.enable = lib.mkForce false; services.gnome.gnome-keyring.enable = lib.mkForce false;
environment.gnome.excludePackages = with pkgs.gnome; [ environment.gnome.excludePackages = with pkgs.gnome; [
# baobab # Disk usage analyzer. # baobab # Disk usage analyzer.

View file

@ -1,3 +1,4 @@
# Intel CPU specific configuration.
{ ... }: { { ... }: {
boot.kernelModules = [ "kvm-intel" ]; boot.kernelModules = [ "kvm-intel" ];
} }

View file

@ -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
];
}

View file

@ -1,5 +1,8 @@
{ pkgs, lib, ... }: { { pkgs, lib, ... }: {
# Add Ollama CLI app.
environment.systemPackages = with pkgs; [ ollama ]; environment.systemPackages = with pkgs; [ ollama ];
# Enable Ollama server.
systemd.services.ollama = { systemd.services.ollama = {
description = "Ollama LLM server."; description = "Ollama LLM server.";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
@ -10,6 +13,8 @@
HOME=/root ${lib.getExe pkgs.ollama} serve HOME=/root ${lib.getExe pkgs.ollama} serve
''; '';
}; };
# Download Ollama models.
systemd.services.ollamamodel = { systemd.services.ollamamodel = {
description = "Ollama LLM model."; description = "Ollama LLM model.";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];

View file

@ -1,59 +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 - - - -"
];
};
systemd.services.keyd.path = [ script ];
environment.systemPackages = [ script ];
}

View file

@ -0,0 +1,22 @@
# 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 controlFileMin onMin onMax offMin offMax;
}).script;
in {
imports = [
(import ./powerlimit ({
inherit controlFileMax controlFileMin onMin onMax offMin offMax;
} // args))
];
environment.systemPackages = [ script ];
}

View file

@ -1,12 +1,11 @@
# AMD CPU boost control.
{ pkgs, ... } @args: let { pkgs, ... } @args: let
controlFile = "/sys/devices/system/cpu/cpufreq/boost"; controlFile = "/sys/devices/system/cpu/cpufreq/boost";
enable = "0"; enable = "0";
disable = "1"; disable = "1";
script = pkgs.writeShellScriptBin "powersave" (import ./powersave/Script.nix { script = pkgs.writeShellScriptBin "powersave" (import ./powersave/Script.nix {
inherit controlFile; inherit controlFile enable disable;
inherit enable;
inherit disable;
}).script; }).script;
in { in {
# Requirements: # Requirements:
@ -14,12 +13,9 @@ in {
# PSS (Cool and Quiet) - Enabled. # PSS (Cool and Quiet) - Enabled.
imports = [ imports = [
(import ./powersave ({ (import ./powersave ({
inherit controlFile; inherit controlFile enable disable;
inherit enable;
inherit disable;
} // args)) } // args))
]; ];
systemd.services.keyd.path = [ script ];
environment.systemPackages = [ script ]; environment.systemPackages = [ script ];
} }

View file

@ -1,22 +1,18 @@
# Intel CPU boost control.
{ pkgs, ... } @args: let { pkgs, ... } @args: let
controlFile = "/sys/devices/system/cpu/intel_pstate/no_turbo"; controlFile = "/sys/devices/system/cpu/intel_pstate/no_turbo";
enable = "1"; enable = "1";
disable = "0"; disable = "0";
script = pkgs.writeShellScriptBin "powersave" (import ./powersave/Script.nix { script = pkgs.writeShellScriptBin "powersave" (import ./powersave/Script.nix {
inherit controlFile; inherit controlFile enable disable;
inherit enable;
inherit disable;
}).script; }).script;
in { in {
imports = [ imports = [
(import ./powersave ({ (import ./powersave ({
inherit controlFile; inherit controlFile enable disable;
inherit enable;
inherit disable;
} // args)) } // args))
]; ];
systemd.services.keyd.path = [ script ];
environment.systemPackages = [ script ]; environment.systemPackages = [ script ];
} }

View file

@ -1,5 +1,6 @@
# Module that enables remote builds. This is a client configuration.
{ config, pkgs, ... }: { { 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 = [{ nix.buildMachines = [{
hostName = "nixbuilder"; hostName = "nixbuilder";
protocol = "ssh-ng"; protocol = "ssh-ng";

View file

@ -1,6 +1,9 @@
# Module that enables remote builds. This is a server configuration.
{ pkgs, secret, lib, ... }: let { pkgs, secret, lib, ... }: let
keyPath = "/root/.nixbuilder"; keyPath = "/root/.nixbuilder";
in { 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 = { systemd.services.generate-nix-cache-key = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";
@ -13,6 +16,7 @@ in {
''; '';
}; };
# Add `nixbuilder` restricted user.
users.groups.nixbuilder = {}; users.groups.nixbuilder = {};
users.users.nixbuilder = { users.users.nixbuilder = {
openssh.authorizedKeys.keys = secret.ssh.builderKeys; openssh.authorizedKeys.keys = secret.ssh.builderKeys;
@ -24,7 +28,8 @@ in {
group = "nixbuilder"; 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 = '' nix.extraOptions = ''
trusted-users = nixbuilder trusted-users = nixbuilder
secret-key-files = ${keyPath}/private-key secret-key-files = ${keyPath}/private-key

View file

@ -1,5 +1,5 @@
{ pkgs, lib, wallpaper, style, ... } @args: let { pkgs, lib, wallpaper, style, ... } @args: let
sway = import ./sway args; sway = import ./desktop/sway args;
config = pkgs.writeText "swayConfig" sway.config; config = pkgs.writeText "swayConfig" sway.config;
script = pkgs.writeShellScriptBin "swayscript" sway.script; script = pkgs.writeShellScriptBin "swayscript" sway.script;
in { in {
@ -8,23 +8,20 @@ in {
./desktop/Bluetooth.nix ./desktop/Bluetooth.nix
./desktop/Brightness.nix ./desktop/Brightness.nix
./desktop/Dconf.nix ./desktop/Dconf.nix
./desktop/GnomeApps.nix
./desktop/Portal.nix ./desktop/Portal.nix
./desktop/Realtime.nix ./desktop/Realtime.nix
./desktop/Sound.nix ./desktop/Sound.nix
./desktop/Waybar.nix ./desktop/Waybar.nix
./desktop/Wayland.nix
]; ];
services.gnome.gnome-keyring.enable = lib.mkForce false; services.gnome.gnome-keyring.enable = lib.mkForce false;
systemd.services.keyd.path = [ script ];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
gnome.adwaita-icon-theme # GTK icons.
grim slurp # Screenshot. grim slurp # Screenshot.
mako # Notification system. mako # Notification system.
networkmanagerapplet # Internet configuration. networkmanagerapplet # Internet configuration.
pamixer pavucontrol pulseaudio # Audio. pamixer pavucontrol pulseaudio # Audio.
playerctl # Multimedia controls. playerctl # Multimedia controls.
wl-clipboard # Clipboard.
script script
]; ];

View file

@ -8,5 +8,4 @@
# glib # glib
gnome3.adwaita-icon-theme # default gnome cursors, gnome3.adwaita-icon-theme # default gnome cursors,
]; ];
###
} }

View file

@ -0,0 +1,9 @@
{ pkgs, ... }: {
variables = {
EDITOR = "nvim";
MANPAGER = "nvim +Man!";
NIXPKGS_ALLOW_UNFREE = "1";
NIX_CURRENT_SYSTEM = "${pkgs.stdenv.system}";
TERM = "xterm-256color";
};
}

12
module/android/Git.nix Normal file
View file

@ -0,0 +1,12 @@
{ secret, ... }: {
config = {
credential.helper = "store";
gpg.format = secret.crypto.sign.gih.format;
gpg.ssh.allowedSignersFile = toString(secret.crypto.sign.git.allowed);
init.defaultBranch = "main";
pull.rebase = true;
push.autoSetupRemote = true;
rebase.autoStash = true;
user.signingkey = builtins.readFile secret.crypto.sign.git.key;
};
}

5
module/android/Nix.nix Normal file
View file

@ -0,0 +1,5 @@
{ ... }: {
extraOptions = ''
experimental-features = nix-command flakes
'';
}

View file

@ -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
];
}

18
module/android/Termux.nix Normal file
View file

@ -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."
};
'';
}

View file

@ -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;
};
};
};
}

View file

@ -1,11 +1,12 @@
{ const, pkgs, lib, secret, ... }: { # System automatic updates.
systemd.services.autoupdate = { # 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; enable = true;
description = "Signed system auto-update."; description = "Signed system auto-update.";
restartIfChanged = false;
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";
stopIfChanged = false;
unitConfig.X-StopOnRemoval = false;
path = with pkgs; [ path = with pkgs; [
bash bash
git git

View file

@ -1,9 +1,14 @@
{ lib, style, util, pkgs, ... } @args: let { lib, style, util, pkgs, ... } @args: let
bash = import ./bash args; bash = import ./bash args;
in { in {
# Add my bash configuration to all *interactive* shells.
programs.bash.interactiveShellInit = bash.config; programs.bash.interactiveShellInit = bash.config;
# Remove default aliases for `l`, `ll` etc as they break my function definitions.
environment.shellAliases = lib.mkForce {}; environment.shellAliases = lib.mkForce {};
environment.variables = { environment.variables = {
# Specify terminal mode.
TERM = "xterm-256color"; TERM = "xterm-256color";
}; };
} }

View file

@ -7,17 +7,24 @@
loader = { loader = {
efi.canTouchEfiVariables = true; efi.canTouchEfiVariables = true;
# Use systemd to boot.
systemd-boot = { systemd-boot = {
enable = true; enable = true;
# Limit the amound of generations availabe for rollback.
# This helps to save storage space.
configurationLimit = 10; 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 = [ availableKernelModules = [
"ahci" "ahci"
"ata_piix" "ata_piix"

View file

@ -12,16 +12,16 @@
services.pcscd.enable = true; services.pcscd.enable = true;
# Yubikey touch notification. # Yubikey touch notification.
# ISSUE: Not working on Sway with Mako for some reason.
# programs.yubikey-touch-detector.enable = true; # programs.yubikey-touch-detector.enable = true;
# Extra packages.
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
yubikey-manager # Yubikey Manager. yubikey-manager
# yubioath-desktop # OTP. # yubioath-desktop # OTP.
]; ];
# Store GPG data on tmpfs. # Store GPG data on tmpfs.
environment.variables = { # environment.variables = {
# GNUPGHOME = "$(mktemp -d -t gnupg-$(date +%Y-%m-%d)-XXXXXXXXXX)"; # GNUPGHOME = "$(mktemp -d -t gnupg-$(date +%Y-%m-%d)-XXXXXXXXXX)";
}; # };
} }

View file

@ -1,13 +1,8 @@
{ pkgs, ... }: { { pkgs, ... }: {
# Distrobox works best with Podman, so enable it here.
imports = [ ./Podman.nix ];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
distrobox distrobox
]; ];
virtualisation = {
podman = {
enable = true;
defaultNetwork.settings.dns_enabled = false;
dockerCompat = false;
};
};
} }

View file

@ -1,4 +1,4 @@
{ inputs, ... }: { { inputs, ... }: {
# Easy to find copy just in case. # Add a link for the active configuration to /etc/dotfiles.
environment.etc.dotfiles.source = inputs.self; environment.etc.dotfiles.source = inputs.self;
} }

View file

@ -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."/" = { fileSystems."/" = {
device = "/dev/disk/by-partlabel/NIXROOT"; device = "/dev/disk/by-partlabel/NIXROOT";
fsType = "ext4"; fsType = "ext4";
options = [ "noatime" ]; options = [ "noatime" ];
}; };
fileSystems."/boot" = { fileSystems."/boot" = {
device = "/dev/disk/by-partlabel/NIXBOOT"; device = "/dev/disk/by-partlabel/NIXBOOT";
fsType = "vfat"; fsType = "vfat";

View file

@ -1,3 +1,4 @@
{ ... }: { { ... }: {
# Disable firewall as I configure firewall on my router.
networking.firewall.enable = false; networking.firewall.enable = false;
} }

View file

@ -1,7 +1,12 @@
{ pkgs, ... }: { { pkgs, ... }: {
fonts.packages = with pkgs; [ fonts.packages = with pkgs; [
# Use Apple fonts for system and text.
(pkgs.callPackage ./applefont {}) (pkgs.callPackage ./applefont {})
# Use Nerd version of Terminus for monospaced fonts.
(nerdfonts.override { fonts = [ "Terminus" ]; }) (nerdfonts.override { fonts = [ "Terminus" ]; })
# I don't use FA, but add it for compatibility.
font-awesome font-awesome
]; ];
} }

View file

@ -7,9 +7,9 @@
pull.rebase = true; pull.rebase = true;
push.autoSetupRemote = true; push.autoSetupRemote = true;
rebase.autoStash = true; rebase.autoStash = true;
user.signingkey = builtins.readFile secret.crypto.sign.key; user.signingkey = builtins.readFile secret.crypto.sign.git.key;
gpg.ssh.allowedSignersFile = toString(secret.crypto.sign.allowed); gpg.ssh.allowedSignersFile = toString(secret.crypto.sign.git.allowed);
gpg.format = secret.crypto.sign.format; gpg.format = secret.crypto.sign.git.format;
}; };
}; };
} }

View file

@ -2,7 +2,6 @@
# Use latest kernel. # Use latest kernel.
boot.kernelPackages = pkgs.linuxPackages_latest; boot.kernelPackages = pkgs.linuxPackages_latest;
# Sysctl.
boot.kernel.sysctl = { boot.kernel.sysctl = {
# Spoof protection. # Spoof protection.
"net.ipv4.conf.default.rp_filter" = 1; "net.ipv4.conf.default.rp_filter" = 1;

View file

@ -1,5 +1,6 @@
{ pkgs, lib, ... }: { { pkgs, lib, key, ... }: {
environment.systemPackages = with pkgs; [ keyd ]; environment.systemPackages = with pkgs; [ keyd ];
services.keyd = { services.keyd = {
enable = true; enable = true;
keyboards.default = { keyboards.default = {
@ -9,14 +10,13 @@
backspace = "delete"; # Delete key on backspace. backspace = "delete"; # Delete key on backspace.
capslock = "overload(control, esc)"; # Ctrl/esc combo. capslock = "overload(control, esc)"; # Ctrl/esc combo.
compose = "layer(layer_macro)"; # Input macros. compose = "layer(layer_macro)"; # Input macros.
esc = "layer(layer_system)"; # System controls. esc = "${key.sysctrl}"; # System controls.
leftcontrol = "overload(layer_alternative, leftcontrol)"; # Alternative layer for home, end etc. leftcontrol = "overload(layer_alternative, leftcontrol)"; # Alternative layer for home, end etc.
print = "layer(layer_macro)"; # ThinkPad remap to compose.
rightalt = "capslock"; # Language toggle.
rightcontrol = "layer(layer_control)"; # Media and other controls. rightcontrol = "layer(layer_control)"; # Media and other controls.
rightshift = "backspace"; # Backspace. rightshift = "backspace"; # Backspace.
}; };
# Alternative navigation.
layer_alternative = { layer_alternative = {
w = "pageup"; w = "pageup";
a = "home"; a = "home";
@ -29,9 +29,10 @@
j = "down"; j = "down";
k = "up"; k = "up";
l = "right"; 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 = { layer_control = {
space = "playpause"; space = "playpause";
w = "volumeup"; w = "volumeup";
@ -44,16 +45,6 @@
z = "stopcd"; z = "stopcd";
}; };
layer_system = {
c = "command(loginctl kill-user voronind)";
l = "command(powerlimit toggle)";
# m = "command(swayscript montoggle)";
p = "command(powersave toggle)";
# v = "command(swayscript vrrtoggle)";
x = "command(systemctl poweroff -i)";
z = "command(systemctl suspend -i)";
};
layer_macro = {}; layer_macro = {};
}; };
}; };
@ -63,8 +54,6 @@
users.groups.keyd = {}; users.groups.keyd = {};
systemd.services.keyd.serviceConfig.CapabilityBoundingSet = [ "CAP_SETGID" ]; systemd.services.keyd.serviceConfig.CapabilityBoundingSet = [ "CAP_SETGID" ];
# HACK: Workaround for powersave/powerlimit/swayscript scripts. # Debug toggle just in case I need it again.
systemd.services.keyd.serviceConfig.ProtectKernelTunables = lib.mkForce false;
systemd.services.keyd.serviceConfig.ProtectHome = lib.mkForce false;
# systemd.services.keyd.environment.KEYD_DEBUG = "1"; # systemd.services.keyd.environment.KEYD_DEBUG = "1";
} }

View file

@ -1,4 +1,7 @@
{ pkgs, ... }: { { 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 = { programs.nix-ld = {
enable = true; enable = true;
package = pkgs.nix-ld; package = pkgs.nix-ld;

View file

@ -1,6 +1,8 @@
{ const, ... }: { { const, ... }: {
time.timeZone = const.timeZone; time.timeZone = const.timeZone;
i18n.defaultLocale = "en_US.UTF-8"; i18n.defaultLocale = "en_US.UTF-8";
# You can customize your Locale in detail like that.
# i18n.extraLocaleSettings = { # i18n.extraLocaleSettings = {
# LC_ADDRESS = "ru_RU.UTF-8"; # LC_ADDRESS = "ru_RU.UTF-8";
# LC_IDENTIFICATION = "ru_RU.UTF-8"; # LC_IDENTIFICATION = "ru_RU.UTF-8";

View file

@ -1,10 +1,23 @@
{ pkgs, ... }: { { pkgs, ... }: {
environment.variables = { environment.variables = {
# Allow running of proprietary software.
NIXPKGS_ALLOW_UNFREE = "1"; NIXPKGS_ALLOW_UNFREE = "1";
# I use this env variable to get currently running architecture.
NIX_CURRENT_SYSTEM = "${pkgs.stdenv.system}"; NIX_CURRENT_SYSTEM = "${pkgs.stdenv.system}";
}; };
# Allow installation of proprietary software.
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
# Deduplicate store automatically. Slows down switches a bit, but saves space.
nix.settings.auto-optimise-store = true; 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 = '' nix.extraOptions = ''
experimental-features = nix-command flakes experimental-features = nix-command flakes
keep-derivations = true keep-derivations = true
@ -12,7 +25,11 @@
min-free = ${toString(50 * 1000 * 1000 * 1000)} 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 = { # nix.gc = {
# automatic = true; # automatic = true;
# dates = "weekly"; # dates = "weekly";

View file

@ -3,19 +3,16 @@
in { in {
environment = { environment = {
variables = { variables = {
EDITOR = "nvim"; EDITOR = "nvim"; # Use Nvim as a default editor.
MANPAGER = "nvim +Man!"; MANPAGER = "nvim +Man!"; # Use Nvim to read man pages.
}; };
systemPackages = with pkgs; [ systemPackages = with pkgs; [
gcc gcc # Required for Treesitter parsers.
]; ];
}; };
programs.neovim = { programs.neovim = {
enable = true; enable = true;
viAlias = true; configure.customRC = nvim.config;
vimAlias = true;
configure = {
customRC = nvim.config;
};
}; };
} }

View file

@ -1,41 +1,40 @@
{ pkgs, ... }: { { pkgs, ... }: {
# List of common packages I use.
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
binwalk binwalk # Can analyze files for other files inside them.
btop htop btop htop # System monitors.
coreutils coreutils usbutils # Common utilities.
cryptsetup cryptsetup # Filesystem encryption (LUKS).
curl curl # CLI http client.
ddrescue testdisk ddrescue testdisk # Apps to recover data from drives.
ffmpeg fastfetch # Systeminfo summary.
file ffmpeg # Video/audio converter.
gcc file # Get general info about a file.
gdu gcc # C compiler.
gnumake gdu # TUI storage analyzer.
gnused gnumake gnused # GNU utils.
gparted gparted parted # GUI/CLI disk partition tool.
imagemagick imagemagick # Image converter and transformation tool.
jdk jdk11 jdk19 jdk20 jdk # Java.
jq jq # Json parser.
lm_sensors lm_sensors # Hardware sensors, like temperature and fan speeds.
lshw lshw # Detailed hardware info tool.
lsof lsof # Find current file users.
ltex-ls ltex-ls # Latex LSP for neovim spellcheck.
neofetch nixd # Nix LSP.
nixd nmap # Network analyzer.
nmap parallel # Run programs in parallel.
parallel pv # IO progress bar.
parted ripgrep # Grep for file search.
pv scanmem # Memory edit tool.
ripgrep smartmontools # S.M.A.R.T. tools.
scanmem sqlite # Serverless file-based database engine.
smartmontools tree # Show directory stricture as a tree.
sqlite ventoy # Boot multiple ISO/images from a single USB stick.
tree wget # CLI http download tool.
universal-android-debloater zip unzip # Zip archive/unarchive tools.
usbutils
ventoy universal-android-debloater # Debloat Android devices.
wget
zip unzip
]; ];
# Special packages. # Special packages.

14
module/common/Podman.nix Normal file
View file

@ -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;
};
};
}

View file

@ -1,6 +1,8 @@
{ pkgs, util, ... } @args: let { pkgs, util, ... } @args: let
ssh = import ./ssh args; ssh = import ./ssh args;
in { in {
environment.systemPackages = with pkgs; [ sshfs ];
programs.ssh.extraConfig = ssh.config; programs.ssh.extraConfig = ssh.config;
# Add SSHFS to mount remote filesystems over SSH.
environment.systemPackages = with pkgs; [ sshfs ];
} }

View file

@ -1,5 +1,6 @@
{ secret, ... }: { { secret, ... }: {
users.users.root.openssh.authorizedKeys.keys = secret.ssh.trustedKeys; users.users.root.openssh.authorizedKeys.keys = secret.ssh.trustedKeys;
services.openssh = { services.openssh = {
enable = true; enable = true;
allowSFTP = true; allowSFTP = true;

View file

@ -1,7 +1,11 @@
{ pkgs, config, wallpaper, ... }: let { 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; forceWhiteText = false;
in { in {
# Add a permanent link for the wallpaper to /etc/wallpaper.
environment.etc.wallpaper.source = wallpaper.path; environment.etc.wallpaper.source = wallpaper.path;
stylix = { stylix = {
image = wallpaper.path; image = wallpaper.path;
autoEnable = true; autoEnable = true;

View file

@ -1,4 +1,3 @@
{ ... }: { { ... }: {
zramSwap.enable = true; zramSwap.enable = true;
swapDevices = [ ];
} }

View file

@ -1,4 +1,7 @@
{ ... }: { { ... }: {
# Default UMASK.
security.loginDefs.settings.UMASK = "077"; security.loginDefs.settings.UMASK = "077";
# Disallow users modification outside of this config.
users.mutableUsers = false; users.mutableUsers = false;
} }

View file

@ -1,4 +1,6 @@
{ pkgs, ... }: { { pkgs, ... }: {
# Instead of overlaying and rebuilding YtDlp I download the release from
# GitHub and patch it for Nix.
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
(pkgs.callPackage ./ytdlp {}) (pkgs.callPackage ./ytdlp {})
]; ];

View file

@ -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 { lib, stdenv, fetchurl, p7zip }: let
pro = fetchurl { pro = fetchurl {
url = "https://devimages-cdn.apple.com/design/resources/download/SF-Pro.dmg"; url = "https://devimages-cdn.apple.com/design/resources/download/SF-Pro.dmg";

View file

@ -4,12 +4,7 @@
in { in {
inherit modules; inherit modules;
config = util.trimTabs ('' config = modules + util.trimTabs (''
# If not running interactively, don't do anything.
# [[ "$-" != *i* ]] && return
'') + modules + util.trimTabs (''
# Find all functions. # Find all functions.
function find_function() { function find_function() {
/usr/bin/env cat ${modulesFile} | /usr/bin/env grep "^function.*()" | /usr/bin/env sed -e "s/^function //" -e "s/().*//" /usr/bin/env cat ${modulesFile} | /usr/bin/env grep "^function.*()" | /usr/bin/env sed -e "s/^function //" -e "s/().*//"

View file

@ -1,17 +1,19 @@
{ inputs, pkgs, util, key, ... } @args: let { inputs, pkgs, util, key, ... } @args: let
nvimRc = { runtimes, cfgs }: let # Create Neovim configuration.
runtimeRc = builtins.foldl' (acc: r: nvimRc = { runtimes, configs }: let
# Plugin paths to install.
runtimeRc = util.trimTabs (builtins.foldl' (acc: r:
acc + "set runtimepath+=${r}\n" acc + "set runtimepath+=${r}\n"
) "" runtimes; ) "" runtimes);
config = pkgs.writeText "nvimRc" (builtins.foldl' (acc: cfg: # My configuration files combined into one big file.
acc + (import cfg args).text config = pkgs.writeText "nvimRc" (util.catText configs args);
) "" cfgs);
cfgRc = "lua dofile(\"${config}\")"; # Tell Neovim to load this file.
in runtimeRc + cfgRc; configRc = "lua dofile(\"${config}\")";
in runtimeRc + configRc;
in { in {
config = util.trimTabs (nvimRc { config = nvimRc {
runtimes = [ runtimes = [
"~/.cache/nvim" "~/.cache/nvim"
"~/.cache/nvim/treesitter" "~/.cache/nvim/treesitter"
@ -36,7 +38,8 @@ in {
"${inputs.nvimTrouble}" "${inputs.nvimTrouble}"
"${inputs.nvimWhichKey}" "${inputs.nvimWhichKey}"
]; ];
cfgs = [
configs = [
./module/key/Rekey.nix ./module/key/Rekey.nix
./module/key/Leader.nix ./module/key/Leader.nix
./module/config/Autoread.nix ./module/config/Autoread.nix
@ -79,5 +82,5 @@ in {
./module/key/Trouble.nix ./module/key/Trouble.nix
./module/key/Whichkey.nix ./module/key/Whichkey.nix
]; ];
}); };
} }

View file

@ -1,3 +1,4 @@
# SSH client configuration.
{ util, ... }: { { util, ... }: {
config = util.trimTabs '' config = util.trimTabs ''
Host dasha Host dasha

View file

@ -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.

View file

@ -2,6 +2,7 @@
mod = key.tmux.mod; mod = key.tmux.mod;
in { in {
text = '' text = ''
unbind-key C-b
bind -n ${mod}-${key.tmux.reload} source-file /etc/tmux.conf bind -n ${mod}-${key.tmux.reload} source-file /etc/tmux.conf
''; '';
} }

View file

@ -30,21 +30,28 @@ in {
environment = { environment = {
systemPackages = with pkgs; [ systemPackages = with pkgs; [
android-studio jetbrains.idea-community adwsteamgtk # Steam GTK theme. Need to run the app to apply.
appimage-run appimage-run # Tool to run .AppImage files in NixOS.
aseprite aseprite # Pixel Art draw app. WARNING: Always builds from source.
blender-hip blender-hip # Blender with HiP support.
bottles dxvk gamescope pkgs.mangohud vkd3d wine64 calibre # Book library manager.
calibre evince # Document viewer.
gimp gimp # Image manipulation program.
godot_4 gnome.adwaita-icon-theme # GTK icons.
jellyfin-media-player gnome.gnome-calculator # Calculator.
(mpv.override {scripts = [mpvScripts.mpris];}) gnome.gnome-font-viewer # Font viewer.
obs-studio gnome.nautilus # File manager.
onlyoffice-bin godot_4 # Game development engine.
scanmem jellyfin-media-player # Jellyfin client (self-hosted Netflix).
steam-run loupe # Image viewer.
tor-browser 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 = { 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. # Special packages.
programs.steam.enable = true; programs.steam.enable = true;
} }

View file

@ -1,335 +1,10 @@
{ lib, key, ... }: let { util, ... } @args: let
mod = key.gnome.mod; settings = util.catSet (util.ls ./dconf) args;
in { in {
# Gnome DE and GTK apps configuration.
programs.dconf.enable = true; programs.dconf.enable = true;
programs.dconf.profiles.user = { programs.dconf.profiles.user = {
enableUserDb = true; # Delete `~/.config/dconf/user` to reset user settings. enableUserDb = true; # Delete `~/.config/dconf/user` to reset user settings.
databases = [{ databases = [{ inherit settings; }];
settings = with lib.gvariant; {
"org/gnome/desktop/a11y" = {
always-show-universal-access-status = true;
};
# "org/gnome/desktop/background" = {
# color-shading-type = "solid";
# picture-options = "none";
# primary-color = "#000000000000";
# secondary-color = "#000000000000";
# };
"org/gnome/desktop/input-sources" = {
current = mkUint32 0;
mru-sources = [ (mkTuple [ "xkb" "us" ]) (mkTuple [ "xkb" "ru" ]) ];
per-window = false;
show-all-sources = true;
sources = [ (mkTuple [ "xkb" "us" ]) (mkTuple [ "xkb" "ru" ]) ];
xkb-options = [ "grp:caps_toggle" ];
};
"org/gnome/desktop/interface" = {
clock-show-date = true;
clock-show-weekday = true;
color-scheme = "prefer-dark";
# cursor-blink = false;
# cursor-size = "24";
# cursor-theme = "Adwaita";
# document-font-name = "SF Pro Text 11";
enable-animations = false;
enable-hot-corners = false;
# font-antialiasing = "rgba";
# font-hinting = "full";
# font-name = "SF Pro Display 10";
gtk-enable-primary-paste = false;
# gtk-theme = "Adwaita";
# icon-theme = "Adwaita";
# monospace-font-name = "Terminess Nerd Font Mono Medium 12";
show-battery-percentage = false;
# toolbar-style = "text";
# toolkit-accessibility = false;
};
"org/gnome/desktop/media-handling" = {
automount = false;
automount-open = false;
autorun-never = true;
};
"org/gnome/desktop/peripherals/mouse" = {
accel-profile = "flat";
natural-scroll = true;
speed = "0.0";
};
"org/gnome/desktop/peripherals/touchpad" = {
tap-to-click = true;
two-finger-scrolling-enabled = true;
};
"org/gnome/desktop/privacy" = {
disable-camera = false;
disable-microphone = false;
old-files-age = mkUint32 30;
recent-files-max-age = mkUint32 30;
remove-old-temp-files = true;
remove-old-trash-files = true;
report-technical-problems = true;
};
# "org/gnome/desktop/remote-desktop/rdp" = {
# enable = false;
# tls-cert = "/home/voronind/.local/share/gnome-remote-desktop/tls.crt";
# tls-key = "/home/voronind/.local/share/gnome-remote-desktop/tls.key";
# view-only = true;
# };
# "org/gnome/desktop/screensaver" = {
# color-shading-type = "solid";
# idle-activation-enabled = false;
# lock-delay = mkUint32 0;
# picture-options = "zoom";
# picture-uri = "file:///etc/wallpaper/Forest.jpg";
# primary-color = "#000000000000";
# secondary-color = "#000000000000";
# };
"org/gnome/desktop/sound" = {
allow-volume-above-100-percent = false;
event-sounds = false;
# theme-name = "freedesktop";
};
"org/gnome/desktop/wm/keybindings" = {
activate-window-menu = [ "" ];
begin-move = [ "" ];
begin-resize = [ "${mod}${key.action.resize.begin}" ];
close = [ "${mod}${key.action.close}" ];
cycle-group = [ "" ];
cycle-group-backward = [ "" ];
cycle-panels = [ "" ];
cycle-panels-backward = [ "" ];
cycle-windows = [ "" ];
cycle-windows-backward = [ "" ];
maximize = [ "" ];
maximize-horizontally = [ "" ];
minimize = [ "${mod}${key.navigation.go.down}" ];
move-to-monitor-down = [ "" ];
move-to-monitor-left = [ "" ];
move-to-monitor-right = [ "" ];
move-to-monitor-up = [ "" ];
move-to-workspace-1 = [ "" ];
move-to-workspace-2 = [ "" ];
move-to-workspace-3 = [ "" ];
move-to-workspace-4 = [ "" ];
move-to-workspace-last = [ "" ];
move-to-workspace-left = [ "<Shift>${mod}${key.navigation.move.prev}" ];
move-to-workspace-right = [ "<Shift>${mod}${key.navigation.move.next}" ];
panel-run-dialog = [ "${mod}${key.action.launch}" ];
show-desktop = [ "${mod}${key.action.hide}" ];
switch-applications = [ "${mod}${key.gnome.window.switch}" ];
switch-applications-backward = [ "<Shift>${mod}${key.gnome.window.switch}" ];
switch-group = [ "<Alt>${key.gnome.window.switch}" ];
switch-group-backward = [ "<Shift><Alt>${key.gnome.window.switch}" ];
switch-input-source = [ "" ];
switch-input-source-backward = [ "" ];
switch-panels = [ "" ];
switch-panels-backward = [ "" ];
switch-to-workspace-1 = [ "" ];
switch-to-workspace-2 = [ "" ];
switch-to-workspace-3 = [ "" ];
switch-to-workspace-4 = [ "" ];
switch-to-workspace-last = [ "" ];
switch-to-workspace-left = [ "${mod}${key.navigation.go.prev}" ];
switch-to-workspace-right = [ "${mod}${key.navigation.go.next}" ];
switch-windows = [ "" ];
switch-windows-backward = [ "" ];
toggle-fullscreen = [ "${mod}${key.gnome.window.fullscreen}" ];
toggle-maximized = [ "${mod}${key.navigation.go.up}" ];
unmaximize = [ "" ];
};
"org/gnome/desktop/wm/preferences" = {
action-middle-click-titlebar = "minimize";
action-right-click-titlebar = "menu";
focus-mode = "click"; # `click` or `sloppy`.
button-layout = "appmenu:close";
# titlebar-font = "SF Pro Display 11";
};
"org/gnome/desktop/session" = {
idle-delay = mkUint32 0;
};
"org/gnome/mutter" = {
attach-modal-dialogs = true;
center-new-windows = true;
dynamic-workspaces = true;
edge-tiling = true;
workspaces-only-on-primary = true;
};
"org/gnome/mutter/keybindings" = {
toggle-tiled-left = [ "${mod}${key.navigation.go.left}" ];
toggle-tiled-right = [ "${mod}${key.navigation.go.right}" ];
};
"org/gnome/mutter/wayland/keybindings" = {
restore-shortcuts = [ "" ];
};
"org/gnome/nautilus/icon-view" = {
default-zoom-level = "larger";
};
"org/gnome/nautilus/list-view" = {
default-zoom-level = "small";
use-tree-view = false;
};
"org/gnome/nautilus/preferences" = {
click-policy = "single";
default-folder-viewer = "list-view";
default-sort-in-reverse-order = false;
default-sort-order = "name";
migrated-gtk-settings = true;
search-filter-time-type = "last_modified";
search-view = "list-view";
show-image-thumbnails = "local-only";
};
"org/gnome/settings-daemon/plugins/color" = {
night-light-enabled = false;
night-light-schedule-automatic = false;
night-light-schedule-from = "0.0";
night-light-schedule-to = "0.0";
night-light-temperature = mkUint32 3700;
};
"org/gnome/settings-daemon/plugins/media-keys" = {
custom-keybindings = [
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/"
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/"
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2/"
];
magnifier = [ "" ];
magnifier-zoom-in = [ "" ];
magnifier-zoom-out = [ "" ];
screenreader = [ "" ];
screensaver = [ "${mod}${key.action.wait}" ];
};
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
binding = "${mod}${key.gnome.launch.terminal}";
command = "kgx -e bash -c 'tmux new-session -A -s main; bash'";
name = "gnome-terminal";
};
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1" = {
binding = "<Shift>${mod}${key.action.exit}";
command = "gnome-session-quit --power-off";
name = "gnome-poweroff";
};
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2" = {
binding = "<Primary>${key.gnome.launch.terminal}";
command = "kgx -- btop";
name = "System Monitor";
};
"org/gnome/settings-daemon/plugins/power" = {
ambient-enabled = false;
idle-dim = false;
power-button-action = "nothing";
sleep-inactive-ac-timeout = "0";
sleep-inactive-ac-type = "nothing";
sleep-inactive-battery-type = "nothing";
};
"org/gnome/shell" = {
disable-extension-version-validation = true;
disable-user-extensions = false;
favorite-apps = [ "" ];
had-bluetooth-devices-setup = true;
last-selected-power-profile = "power-saver";
remember-mount-password = false;
};
"org/gnome/shell/app-switcher" = {
current-workspace-only = true;
};
"org/gnome/shell/keybindings" = {
focus-active-notification = [ "" ];
open-application-menu = [ "" ];
show-screenshot-ui = [ "${mod}${key.gnome.screenshot}" ];
switch-to-application-1 = [ "" ];
switch-to-application-2 = [ "" ];
switch-to-application-3 = [ "" ];
switch-to-application-4 = [ "" ];
switch-to-application-5 = [ "" ];
switch-to-application-6 = [ "" ];
switch-to-application-7 = [ "" ];
switch-to-application-8 = [ "" ];
switch-to-application-9 = [ "" ];
toggle-application-view = [ "" ];
toggle-message-tray = [ "" ];
toggle-overview = [ "" ];
toggle-quick-settings = [ "" ];
};
"org/gnome/shell/overrides" = {
edge-tiling = false;
};
"org/gnome/software" = {
download-updates = false;
download-updates-notify = false;
first-run = false;
show-nonfree-prompt = false;
};
"org/gnome/system/location" = {
enabled = false;
};
"org/gtk/gtk4/settings/file-chooser" = {
date-format = "regular";
location-mode = "path-bar";
show-hidden = false;
show-size-column = true;
show-type-column = true;
sidebar-width = "166";
sort-column = "modified";
sort-directories-first = true;
sort-order = "descending";
type-format = "category";
view-type = "list";
};
"org/gtk/settings/file-chooser" = {
date-format = "regular";
location-mode = "path-bar";
show-hidden = false;
show-size-column = true;
show-type-column = true;
sort-column = "modified";
sort-directories-first = true;
sort-order = "descending";
type-format = "category";
};
"system/locale" = {
region = "ru_RU.UTF-8";
};
"system/proxy" = {
mode = "none";
};
"org/virt-manager/virt-manager/connections" = {
autoconnect = ["qemu:///system"];
uris = ["qemu:///system"];
};
};
}];
}; };
} }

View file

@ -1,9 +1,9 @@
{ ... }: { { setting, ... }: {
services.xserver.enable = true; services.xserver.enable = true;
services.xserver.displayManager.gdm.enable = true; services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true; services.xserver.desktopManager.gnome.enable = true;
services.xserver.xkb = { services.xserver.xkb = {
layout = "us,ru"; layout = setting.keyboard.layouts;
options = "grp:caps_toggle,lv3:ralt_switch"; options = setting.keyboard.options;
}; };
} }

View file

@ -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;
}

View file

@ -1,3 +1,4 @@
# Polkit agent is used by apps to ask for Root password with a popup.
{ pkgs, lib, ... }: { { pkgs, lib, ... }: {
security.polkit.enable = true; security.polkit.enable = true;
systemd = { systemd = {

View file

@ -1,3 +1,4 @@
# Portals are needed for Wayland apps to select files, screen shares etc.
{ pkgs, ... }: { { pkgs, ... }: {
xdg.portal = { xdg.portal = {
enable = true; enable = true;

View file

@ -1,3 +1,4 @@
# Improve DE performance.
{ ... }: { { ... }: {
security.pam.loginLimits = [ security.pam.loginLimits = [
{ domain = "@users"; item = "rtprio"; type = "-"; value = 1; } { domain = "@users"; item = "rtprio"; type = "-"; value = 1; }

View file

@ -1,4 +1,5 @@
{ ... }: { { ... }: {
# Systemd custom target for Sway.
systemd.user.targets.gui-session = { systemd.user.targets.gui-session = {
after = [ "graphical-session-pre.target" ]; after = [ "graphical-session-pre.target" ];
bindsTo = [ "graphical-session.target" ]; bindsTo = [ "graphical-session.target" ];

View file

@ -2,6 +2,9 @@
waybar = import ./waybar args; waybar = import ./waybar args;
in { in {
programs.waybar.enable = true; 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;
};
} }

View file

@ -0,0 +1,5 @@
{ pkgs, ... }: {
environment.systemPackages = with pkgs; [
wl-clipboard
];
}

View file

@ -0,0 +1,5 @@
{ ... }: {
"org/gnome/desktop/a11y" = {
always-show-universal-access-status = true;
};
}

View file

@ -0,0 +1,27 @@
{ ... }: {
"org/gtk/gtk4/settings/file-chooser" = {
date-format = "regular";
location-mode = "path-bar";
show-hidden = false;
show-size-column = true;
show-type-column = true;
sidebar-width = "166";
sort-column = "modified";
sort-directories-first = true;
sort-order = "descending";
type-format = "category";
view-type = "list";
};
"org/gtk/settings/file-chooser" = {
date-format = "regular";
location-mode = "path-bar";
show-hidden = false;
show-size-column = true;
show-type-column = true;
sort-column = "modified";
sort-directories-first = true;
sort-order = "descending";
type-format = "category";
};
}

View file

@ -0,0 +1,21 @@
{ lib, setting, ... }: {
"org/gnome/desktop/input-sources" = with lib.gvariant; {
current = mkUint32 0;
mru-sources = [ (mkTuple [ "xkb" "us" ]) (mkTuple [ "xkb" "ru" ]) ];
per-window = false;
show-all-sources = true;
sources = [ (mkTuple [ "xkb" "us" ]) (mkTuple [ "xkb" "ru" ]) ];
xkb-options = [ setting.keyboard.options ];
};
"org/gnome/desktop/peripherals/mouse" = {
accel-profile = "flat";
natural-scroll = true;
speed = "0.0";
};
"org/gnome/desktop/peripherals/touchpad" = {
tap-to-click = true;
two-finger-scrolling-enabled = true;
};
}

View file

@ -0,0 +1,11 @@
{ ... }: {
"org/gnome/desktop/interface" = {
clock-show-date = true;
clock-show-weekday = true;
color-scheme = "prefer-dark";
enable-animations = false;
enable-hot-corners = false;
gtk-enable-primary-paste = false;
show-battery-percentage = false;
};
}

View file

@ -0,0 +1,111 @@
{ key, ... }: let
mod = key.gnome.mod;
in {
"org/gnome/desktop/wm/keybindings" = {
activate-window-menu = [ "" ];
begin-move = [ "" ];
begin-resize = [ "${mod}${key.action.resize.begin}" ];
close = [ "${mod}${key.action.close}" ];
cycle-group = [ "" ];
cycle-group-backward = [ "" ];
cycle-panels = [ "" ];
cycle-panels-backward = [ "" ];
cycle-windows = [ "" ];
cycle-windows-backward = [ "" ];
maximize = [ "" ];
maximize-horizontally = [ "" ];
minimize = [ "${mod}${key.navigation.go.down}" ];
move-to-monitor-down = [ "" ];
move-to-monitor-left = [ "" ];
move-to-monitor-right = [ "" ];
move-to-monitor-up = [ "" ];
move-to-workspace-1 = [ "" ];
move-to-workspace-2 = [ "" ];
move-to-workspace-3 = [ "" ];
move-to-workspace-4 = [ "" ];
move-to-workspace-last = [ "" ];
move-to-workspace-left = [ "<Shift>${mod}${key.navigation.move.prev}" ];
move-to-workspace-right = [ "<Shift>${mod}${key.navigation.move.next}" ];
panel-run-dialog = [ "${mod}${key.action.launch}" ];
show-desktop = [ "${mod}${key.action.hide}" ];
switch-applications = [ "${mod}${key.gnome.window.switch}" ];
switch-applications-backward = [ "<Shift>${mod}${key.gnome.window.switch}" ];
switch-group = [ "<Alt>${key.gnome.window.switch}" ];
switch-group-backward = [ "<Shift><Alt>${key.gnome.window.switch}" ];
switch-input-source = [ "" ];
switch-input-source-backward = [ "" ];
switch-panels = [ "" ];
switch-panels-backward = [ "" ];
switch-to-workspace-1 = [ "" ];
switch-to-workspace-2 = [ "" ];
switch-to-workspace-3 = [ "" ];
switch-to-workspace-4 = [ "" ];
switch-to-workspace-last = [ "" ];
switch-to-workspace-left = [ "${mod}${key.navigation.go.prev}" ];
switch-to-workspace-right = [ "${mod}${key.navigation.go.next}" ];
switch-windows = [ "" ];
switch-windows-backward = [ "" ];
toggle-fullscreen = [ "${mod}${key.gnome.window.fullscreen}" ];
toggle-maximized = [ "${mod}${key.navigation.go.up}" ];
unmaximize = [ "" ];
};
"org/gnome/mutter/keybindings" = {
toggle-tiled-left = [ "${mod}${key.navigation.go.left}" ];
toggle-tiled-right = [ "${mod}${key.navigation.go.right}" ];
};
"org/gnome/mutter/wayland/keybindings" = {
restore-shortcuts = [ "" ];
};
"org/gnome/settings-daemon/plugins/media-keys" = {
custom-keybindings = [
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/"
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/"
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2/"
];
magnifier = [ "" ];
magnifier-zoom-in = [ "" ];
magnifier-zoom-out = [ "" ];
screenreader = [ "" ];
screensaver = [ "${mod}${key.action.wait}" ];
};
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
binding = "${mod}${key.gnome.launch.terminal}";
command = "kgx -e bash -c 'tmux new-session -A -s main; bash'";
name = "gnome-terminal";
};
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1" = {
binding = "<Shift>${mod}${key.action.exit}";
command = "gnome-session-quit --power-off";
name = "gnome-poweroff";
};
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2" = {
binding = "<Primary>${key.gnome.launch.terminal}";
command = "kgx -- btop";
name = "System Monitor";
};
"org/gnome/shell/keybindings" = {
focus-active-notification = [ "" ];
open-application-menu = [ "" ];
show-screenshot-ui = [ "${mod}${key.gnome.screenshot}" ];
switch-to-application-1 = [ "" ];
switch-to-application-2 = [ "" ];
switch-to-application-3 = [ "" ];
switch-to-application-4 = [ "" ];
switch-to-application-5 = [ "" ];
switch-to-application-6 = [ "" ];
switch-to-application-7 = [ "" ];
switch-to-application-8 = [ "" ];
switch-to-application-9 = [ "" ];
toggle-application-view = [ "" ];
toggle-message-tray = [ "" ];
toggle-overview = [ "" ];
toggle-quick-settings = [ "" ];
};
}

View file

@ -0,0 +1,7 @@
{ ... }: {
"org/gnome/desktop/media-handling" = {
automount = false;
automount-open = false;
autorun-never = true;
};
}

View file

@ -0,0 +1,21 @@
{ ... }: {
"org/gnome/nautilus/icon-view" = {
default-zoom-level = "larger";
};
"org/gnome/nautilus/list-view" = {
default-zoom-level = "small";
use-tree-view = false;
};
"org/gnome/nautilus/preferences" = {
click-policy = "single";
default-folder-viewer = "list-view";
default-sort-in-reverse-order = false;
default-sort-order = "name";
migrated-gtk-settings = true;
search-filter-time-type = "last_modified";
search-view = "list-view";
show-image-thumbnails = "local-only";
};
}

View file

@ -0,0 +1,10 @@
{ ... }: {
"org/gnome/settings-daemon/plugins/power" = {
ambient-enabled = false;
idle-dim = false;
power-button-action = "nothing";
sleep-inactive-ac-timeout = "0";
sleep-inactive-ac-type = "nothing";
sleep-inactive-battery-type = "nothing";
};
}

View file

@ -0,0 +1,15 @@
{ lib, ... }: {
"org/gnome/desktop/privacy" = with lib.gvariant; {
disable-camera = false;
disable-microphone = false;
old-files-age = mkUint32 30;
recent-files-max-age = mkUint32 30;
remove-old-temp-files = true;
remove-old-trash-files = true;
report-technical-problems = true;
};
"org/gnome/system/location" = {
enabled = false;
};
}

View file

@ -0,0 +1,5 @@
{ lib, ... }: {
"org/gnome/desktop/session" = with lib.gvariant; {
idle-delay = mkUint32 0;
};
}

View file

@ -0,0 +1,14 @@
{ ... }: {
"org/gnome/shell" = {
disable-extension-version-validation = true;
disable-user-extensions = false;
favorite-apps = [ "" ];
had-bluetooth-devices-setup = true;
last-selected-power-profile = "power-saver";
remember-mount-password = false;
};
"system/proxy" = {
mode = "none";
};
}

View file

@ -0,0 +1,8 @@
{ ... }: {
"org/gnome/software" = {
download-updates = false;
download-updates-notify = false;
first-run = false;
show-nonfree-prompt = false;
};
}

View file

@ -0,0 +1,7 @@
{ ... }: {
"org/gnome/desktop/sound" = {
allow-volume-above-100-percent = false;
event-sounds = false;
theme-name = "freedesktop";
};
}

View file

@ -0,0 +1,32 @@
{ lib, ... }: {
"org/gnome/desktop/wm/preferences" = {
action-middle-click-titlebar = "minimize";
action-right-click-titlebar = "menu";
focus-mode = "click"; # `click` or `sloppy`.
button-layout = "appmenu:close";
};
"org/gnome/mutter" = {
attach-modal-dialogs = true;
center-new-windows = true;
dynamic-workspaces = true;
edge-tiling = true;
workspaces-only-on-primary = true;
};
"org/gnome/settings-daemon/plugins/color" = with lib.gvariant; {
night-light-enabled = false;
night-light-schedule-automatic = false;
night-light-schedule-from = "0.0";
night-light-schedule-to = "0.0";
night-light-temperature = mkUint32 3700;
};
"org/gnome/shell/app-switcher" = {
current-workspace-only = true;
};
"org/gnome/shell/overrides" = {
edge-tiling = false;
};
}

View file

@ -6,7 +6,7 @@
install_url = url; install_url = url;
}; };
mkBookmark = name: url: { inherit name; inherit url; }; mkBookmark = name: url: { inherit name url; };
in { in {
# Disable profile switching on rebuild. # Disable profile switching on rebuild.
environment.variables = { environment.variables = {
@ -35,6 +35,7 @@ in {
]; ];
ExtensionUpdate = true; ExtensionUpdate = true;
ExtensionSettings = { ExtensionSettings = {
# Block extension installation outside of this config.
"*" = { "*" = {
install_sources = [ "*" ]; install_sources = [ "*" ];
installation_mode = "blocked"; 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"; "{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"; "{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"; "{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"; # "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 = { SearchEngines = {
Default = "Whoogle"; Default = "Whoogle";
Add = [ Add = [

View file

@ -1,4 +1,5 @@
{ pkgs, wallpaper, style, util, setting, ... } @args: let { pkgs, wallpaper, style, util, setting, ... } @args: let
# Order is required for Sway configuration.
swayRc = util.catText [ swayRc = util.catText [
./module/Style.nix ./module/Style.nix
./module/Display.nix ./module/Display.nix
@ -20,6 +21,7 @@
./module/Session.nix ./module/Session.nix
./module/Keyd.nix ./module/Keyd.nix
./module/Waybar.nix ./module/Waybar.nix
./module/Control.nix
] args; ] args;
in { in {
config = (util.trimTabs '' config = (util.trimTabs ''

Some files were not shown because too many files have changed in this diff Show more