1
1
Fork 0

git: migrate to forgejo

Squashes 1,331 commits

Signed-off-by: Myned <dev@bjork.tech>
This commit is contained in:
Myned 2024-09-08 19:22:14 -05:00
parent 6757f52cf7
commit 53c8575116
Signed by: myned
GPG key ID: C7224454F7881A34
250 changed files with 14748 additions and 6 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@
result result
result-* result-*
install.log

20
LICENSE
View file

@ -1,9 +1,21 @@
MIT License MIT License
Copyright (c) 2024 myned Copyright (c) 2023 Myned
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

115
README.md
View file

@ -1,3 +1,114 @@
# nixos # Install
NixOS Configuration ## Remote (with NixOS Anywhere)
1. Clone this repository
```sh
git clone https://github.com/Myned/nixos
```
2. Enable [Flakes](https://wiki.nixos.org/wiki/Flakes)
3. Boot from NixOS [minimal installer](https://nixos.org/download.html#nixos-iso)
4. Create machine-specific modules in `machines/MACHINE/`
a. If [Home Manager](https://github.com/nix-community/home-manager), home configuration in `home.nix`
b. System configuration and hostname in `system.nix`
```nix
{ networking.hostName = "MACHINE"; }
```
c. [Disko](https://github.com/nix-community/disko) layout in `disko.nix`
```sh
# Verify /dev identifier on machine
lsblk
# Verify EFI/BIOS firmware on machine
[ -d /sys/firmware/efi/efivars ] && echo "UEFI" || echo "BIOS"
```
d. Generated hardware configuration in `hardware-configuration.nix`
```sh
nixos-generate-config --show-hardware-config --no-filesystems --root /mnt
```
e. Import modules in `default.nix`
5. Choose profile and add machine-specific modules to `flake.in.nix`
```nix
MACHINE = linux [ ./profiles/PROFILE ./machines/MACHINE ];
```
6. Generate `flake.nix` with [flakegen](https://github.com/jorsn/flakegen)
```sh
git add .
nix run .#genflake flake.nix
nix flake lock
```
7. Copy host public SSH key to root on machine
```sh
# On machine
sudo passwd root
```
```sh
# On host
ssh-copy-id root@MACHINE
```
8. Test and execute [NixOS Anywhere](https://github.com/nix-community/nixos-anywhere)
```sh
nixos-anywhere --vm-test -f .#MACHINE root@IP
nixos-anywhere -f .#MACHINE root@IP
```
9. Shutdown, detach ISO, and reboot
## Local (with script)
1. Clone repository using personal access token
```sh
git clone https://TOKEN@github.com/Myned/nixos /tmp/nixos
```
2. Go to repository directory
```sh
cd /tmp/nixos
```
3. Check disk layout
```sh
lsblk
```
4. Modify disko layout to match hardware
```sh
nano machine/MACHINE/disko.nix
```
5. Execute install script
```sh
sudo nix --experimental-features 'nix-command flakes' run nixpkgs#fish -- install.fish
```
6. Optionally shred personal access token
```sh
shred -zu github.token
```

192
configuration.nix Normal file
View file

@ -0,0 +1,192 @@
{
config,
inputs,
lib,
...
}:
{
age.secrets =
let
secret = filename: {
file = "${inputs.self}/secrets/${filename}";
};
in
{
"common/nix/access-tokens.conf" = secret "common/nix/access-tokens.conf";
};
### NixOS
nixpkgs =
let
config = {
allowUnfree = true;
allowInsecurePredicate =
pkg:
let
name = lib.getName pkg;
in
# HACK: Allow all insecure electron versions
name == "electron"
# HACK: Some Matrix clients rely on libolm, which is deprecated
# https://github.com/NixOS/nixpkgs/pull/334638
|| name == "cinny"
|| name == "cinny-unwrapped"
|| name == "fluffychat-linux"
|| name == "olm"
|| name == "openssl"; # Cisco Packet Tracer
};
in
{
inherit config;
overlays = [
(
final: prev:
let
nixpkgs =
branch:
import inputs."nixpkgs-${branch}" {
inherit config;
system = prev.system;
};
stable = nixpkgs "stable";
unstable = nixpkgs "unstable";
staging-next = nixpkgs "staging-next";
local = nixpkgs "local";
in
{
# Overlay nixpkgs branches
#?? nixpkgs.BRANCH.PACKAGE
inherit stable unstable staging-next;
# Hypr*
hypridle = inputs.hypridle.packages.${prev.system}.default;
hyprland = inputs.hyprland.packages.${prev.system}.default;
hyprlock = inputs.hyprlock.packages.${prev.system}.default;
# TODO: Remove when merged into unstable
# https://github.com/NixOS/nixpkgs/pull/338836
xdg-desktop-portal-hyprland =
inputs.xdg-desktop-portal-hyprland.packages.${prev.system}.xdg-desktop-portal-hyprland;
hyprlandPlugins = {
hyprbars = inputs.hyprland-plugins.packages.${prev.system}.hyprbars;
};
# Development
ciscoPacketTracer8 = local.ciscoPacketTracer8;
}
)
];
};
nix = {
#!! Override upstream nix
# TODO: Try lix v2.92.0
# https://git.lix.systems/lix-project/lix
#// package = pkgs.lix;
# BUG: Absolute paths are forbidden in pure mode
# https://github.com/NixOS/nix/issues/11030
#// package = pkgs.nixVersions.latest;
#// optimise.automatic = true; # Run storage optimizer periodically
# https://nix.dev/manual/nix/latest/command-ref/conf-file.html
# https://nix.dev/manual/nix/2.18/command-ref/conf-file.html for Lix
settings = {
auto-optimise-store = true; # Run optimizer during build
fallback = true; # Build from source if cache timeout reached
log-lines = 1000; # Build failure log length
min-free = 1024 * 1024 * 1024; # Trigger garbage collection at 1 GB space remaining
warn-dirty = false; # Git tree is usually dirty
experimental-features = [
"nix-command"
"flakes"
];
# Binary caches
trusted-users = [
"root"
"@wheel"
];
trusted-substituters = [
"https://anyrun.cachix.org"
"https://attic.kennel.juneis.dog/conduwuit"
"https://ezkea.cachix.org"
"https://hyprland.cachix.org"
"https://nix-community.cachix.org"
];
trusted-public-keys = [
"anyrun.cachix.org-1:pqBobmOjI7nKlsUMV25u9QHa9btJK65/C8vnO3p346s="
"conduwuit:BbycGUgTISsltcmH0qNjFR9dbrQNYgdIAcmViSGoVTE="
"ezkea.cachix.org-1:ioBmUbJTZIKsHmWWXPe1FSFbeVe+afhfgqgTSNd34eI="
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
#!! Handled by programs.nh.clean
# Garbage collection
# gc = {
# automatic = true;
# dates = "weekly";
# options = "--delete-older-than 7d"; # Delete old generations
# };
# API access tokens to increase rate limits
# https://nix.dev/manual/nix/latest/command-ref/conf-file#conf-access-tokens
# https://github.com/NixOS/nix/issues/6536#issuecomment-1254858889
# https://github.com/settings/tokens
extraOptions = "!include ${config.age.secrets."common/nix/access-tokens.conf".path}";
};
system = {
nixos.label = ""; # Partially clean up boot entries
#!! DO NOT MODIFY ###
stateVersion = "23.11";
#!! ############# ###
};
### Home Manager
# https://nix-community.github.io/home-manager/index.xhtml#sec-install-nixos-module
home-manager = {
backupFileExtension = "bak";
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = {
inherit inputs;
};
users.${config.custom.username} = {
programs.home-manager.enable = true;
systemd.user.startServices = "sd-switch"; # Start/stop user services immediately
# Inherit configuration.nix
nixpkgs.config = config.nixpkgs.config;
nix.gc = {
automatic = config.nix.gc.automatic;
frequency = config.nix.gc.dates;
options = config.nix.gc.options;
};
home = {
username = config.custom.username;
homeDirectory = "/home/${config.custom.username}";
#!! DO NOT MODIFY ###
stateVersion = "23.11";
#!! ############# ###
};
};
};
}

193
flake.in.nix Normal file
View file

@ -0,0 +1,193 @@
# !! Generate flake.nix
# https://github.com/jorsn/flakegen
#?? rm flake.nix
#?? nix flake init -t github:jorsn/flakegen
#?? git add .
#?? nix run .#genflake flake.nix
# TODO: Remove flakegen hook when nix expressions are officially implemented
# https://github.com/NixOS/nix/issues/3966
{
# https://wiki.nixos.org/wiki/Flakes
# https://nix.dev/manual/nix/2.18/command-ref/new-cli/nix3-flake.html
inputs =
let
flake = url: { inherit url; };
follows = input: { inputs.${input}.follows = input; };
stable = input: { inputs.${input}.follows = "${input}-stable"; };
unstable = input: { inputs.${input}.follows = "${input}-unstable"; };
source = url: {
inherit url;
flake = false;
};
in
{
#?? branch = "git+https://REPO?ref=BRANCH"
#?? commit = "git+https://REPO?ref=BRANCH&rev=COMMIT"
#?? tag = "git+https://REPO?ref=refs/tags/TAG"
### Standalone
nixos-hardware = flake "github:NixOS/nixos-hardware";
### Stable
nixpkgs-stable = flake "github:NixOS/nixpkgs/nixos-24.05";
# Common flakes
home-manager-stable = flake "github:nix-community/home-manager/release-24.05" // stable "nixpkgs";
nix-index-database-stable = flake "github:nix-community/nix-index-database" // stable "nixpkgs";
# Desktop flakes
aagl-gtk-on-nix-stable = flake "github:ezKEa/aagl-gtk-on-nix/release-24.05" // stable "nixpkgs";
### Unstable
nixpkgs-unstable = flake "github:NixOS/nixpkgs/nixos-unstable";
# Common flakes
agenix = flake "github:ryantm/agenix" // unstable "nixpkgs";
arion = flake "github:hercules-ci/arion" // unstable "nixpkgs";
compose2nix = flake "github:aksiksi/compose2nix" // unstable "nixpkgs";
disko = flake "github:nix-community/disko" // unstable "nixpkgs";
home-manager-unstable = flake "github:nix-community/home-manager" // unstable "nixpkgs";
nix-index-database-unstable = flake "github:nix-community/nix-index-database" // unstable "nixpkgs";
# Console flakes
jovian-nixos = flake "github:Jovian-Experiments/Jovian-NixOS" // unstable "nixpkgs";
# Desktop flakes
aagl-gtk-on-nix-unstable = flake "github:ezKEa/aagl-gtk-on-nix" // unstable "nixpkgs";
ags = flake "github:Aylur/ags" // unstable "nixpkgs";
anyrun = flake "github:Kirottu/anyrun" // unstable "nixpkgs";
bitwarden-menu = flake "github:firecat53/bitwarden-menu" // unstable "nixpkgs";
fw-fanctrl = flake "github:TamtamHero/fw-fanctrl/packaging/nix" // unstable "nixpkgs";
hypridle = flake "github:hyprwm/hypridle" // unstable "nixpkgs";
hyprland = flake "git+https://github.com/hyprwm/Hyprland?submodules=1" // unstable "nixpkgs";
# hyprland =
# flake "git+https://github.com/hyprwm/Hyprland?ref=refs/tags/v0.41.2&submodules=1"
# // unstable "nixpkgs";
# hyprland =
# flake "git+https://github.com/UjinT34/Hyprland?ref=vrr-cursor-fix&submodules=1"
# // unstable "nixpkgs";
hyprland-contrib = flake "github:hyprwm/contrib" // unstable "nixpkgs";
hyprland-plugins =
flake "github:hyprwm/hyprland-plugins" // unstable "nixpkgs" // follows "hyprland";
hyprlock = flake "github:hyprwm/hyprlock" // unstable "nixpkgs";
hyprpaper = flake "github:hyprwm/hyprpaper" // unstable "nixpkgs";
hyprpicker = flake "github:hyprwm/hyprpicker" // unstable "nixpkgs";
nix-flatpak = flake "github:gmodena/nix-flatpak?ref=v0.4.1";
nix-vscode-extensions = flake "github:nix-community/nix-vscode-extensions" // unstable "nixpkgs";
nixd = flake "github:nix-community/nixd" // unstable "nixpkgs";
xdg-desktop-portal-hyprland =
flake "github:hyprwm/xdg-desktop-portal-hyprland"
// unstable "nixpkgs";
# Server flakes
conduwuit = flake "github:Myned/conduwuit" // unstable "nixpkgs";
### Staging
nixpkgs-staging-next = flake "github:NixOS/nixpkgs/staging-next";
### Development
nixpkgs-local = flake "git+file:///home/myned/.dev/nixpkgs?ref=7849cd48822de4dc0515c787b20dc85de30acdca";
#// hyprland = flake "git+file:///home/myned/.dev/Hyprland?submodules=1";
### Source code
firefox-gnome-theme = source "github:rafaelmardojai/firefox-gnome-theme/v128";
lifx-cli = source "github:Rawa/lifx-cli";
steamtinkerlaunch = source "github:sonic2kk/steamtinkerlaunch";
thunderbird-gnome-theme = source "github:rafaelmardojai/thunderbird-gnome-theme";
virtio-win = source "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.262-2/virtio-win.iso";
};
outputs = inputs: {
# TODO: Use forAllSystems
# https://nix.dev/manual/nix/2.18/command-ref/new-cli/nix3-fmt
formatter.x86_64-linux = inputs.nixpkgs-unstable.legacyPackages.x86_64-linux.nixfmt-rfc-style;
nixosConfigurations =
let
# TODO: Use inline modules instead of specialArgs
# https://jade.fyi/blog/flakes-arent-real#nixos-modules
# Boilerplate systems with global imports
#!! There is no default nixpkgs, inputs.<nixpkgs|home-manager>-BRANCH must exist
#?? branch = common "BRANCH" "ARCHITECTURE" [ MODULES ]
common =
branch: arch: modules:
inputs."nixpkgs-${branch}".lib.nixosSystem {
system = arch;
specialArgs = {
inherit inputs;
};
# TODO: Clean up optional attributes with each new release
#!! Options will diverge between branches over time
#?? with lib; optionalAttrs (versionAtLeast version "VERSION") { ... };
modules = modules ++ [
./options
./configuration.nix
#!! Avoid globally importing modules that are not guarded by .enable
# https://github.com/NixOS/nixpkgs/issues/137168
(
{ config, inputs, ... }:
{
imports = [
inputs."aagl-gtk-on-nix-${branch}".nixosModules.default
inputs."home-manager-${branch}".nixosModules.home-manager
inputs."nix-index-database-${branch}".nixosModules.nix-index
inputs.agenix.nixosModules.default
inputs.arion.nixosModules.arion
inputs.disko.nixosModules.disko
inputs.fw-fanctrl.nixosModules.default
inputs.nix-flatpak.nixosModules.nix-flatpak
];
home-manager.users.${config.custom.username}.imports = [
inputs."nix-index-database-${branch}".hmModules.nix-index
];
}
)
];
};
#?? system = branch "ARCHITECTURE" [ MODULES ]
stable = arch: modules: common "stable" "${arch}-linux" modules;
unstable = arch: modules: common "unstable" "${arch}-linux" modules;
in
{
### Stable
myarm = stable "aarch64" [
./profiles/server
./machines/myarm
];
myne = stable "x86_64" [
./profiles/server
./machines/myne
];
mypi3 = stable "aarch64" [
./profiles/sbc
./machines/mypi3
];
### Unstable
myeck = unstable "x86_64" [
./profiles/console
./machines/myeck
];
mynix = unstable "x86_64" [
./profiles/desktop
./machines/mynix
];
myork = unstable "x86_64" [
./profiles/laptop
./machines/myork
];
};
};
}

2611
flake.lock Normal file

File diff suppressed because it is too large Load diff

138
flake.nix Normal file
View file

@ -0,0 +1,138 @@
# Do not modify! This file is generated.
{
inputs = {
aagl-gtk-on-nix-stable = {
inputs.nixpkgs.follows = "nixpkgs-stable";
url = "github:ezKEa/aagl-gtk-on-nix/release-24.05";
};
aagl-gtk-on-nix-unstable = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:ezKEa/aagl-gtk-on-nix";
};
agenix = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:ryantm/agenix";
};
ags = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:Aylur/ags";
};
anyrun = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:Kirottu/anyrun";
};
arion = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:hercules-ci/arion";
};
bitwarden-menu = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:firecat53/bitwarden-menu";
};
compose2nix = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:aksiksi/compose2nix";
};
conduwuit = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:Myned/conduwuit";
};
disko = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:nix-community/disko";
};
firefox-gnome-theme = {
flake = false;
url = "github:rafaelmardojai/firefox-gnome-theme/v128";
};
flakegen.url = "github:jorsn/flakegen";
fw-fanctrl = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:TamtamHero/fw-fanctrl/packaging/nix";
};
home-manager-stable = {
inputs.nixpkgs.follows = "nixpkgs-stable";
url = "github:nix-community/home-manager/release-24.05";
};
home-manager-unstable = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:nix-community/home-manager";
};
hypridle = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:hyprwm/hypridle";
};
hyprland = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "git+https://github.com/hyprwm/Hyprland?submodules=1";
};
hyprland-contrib = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:hyprwm/contrib";
};
hyprland-plugins = {
inputs.hyprland.follows = "hyprland";
url = "github:hyprwm/hyprland-plugins";
};
hyprlock = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:hyprwm/hyprlock";
};
hyprpaper = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:hyprwm/hyprpaper";
};
hyprpicker = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:hyprwm/hyprpicker";
};
jovian-nixos = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:Jovian-Experiments/Jovian-NixOS";
};
lifx-cli = {
flake = false;
url = "github:Rawa/lifx-cli";
};
nix-flatpak.url = "github:gmodena/nix-flatpak?ref=v0.4.1";
nix-index-database-stable = {
inputs.nixpkgs.follows = "nixpkgs-stable";
url = "github:nix-community/nix-index-database";
};
nix-index-database-unstable = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:nix-community/nix-index-database";
};
nix-vscode-extensions = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:nix-community/nix-vscode-extensions";
};
nixd = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:nix-community/nixd";
};
nixos-hardware.url = "github:NixOS/nixos-hardware";
nixpkgs-local.url = "git+file:///home/myned/.dev/nixpkgs?ref=7849cd48822de4dc0515c787b20dc85de30acdca";
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-24.05";
nixpkgs-staging-next.url = "github:NixOS/nixpkgs/staging-next";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
steamtinkerlaunch = {
flake = false;
url = "github:sonic2kk/steamtinkerlaunch";
};
thunderbird-gnome-theme = {
flake = false;
url = "github:rafaelmardojai/thunderbird-gnome-theme";
};
virtio-win = {
flake = false;
url = "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.262-2/virtio-win.iso";
};
xdg-desktop-portal-hyprland = {
inputs.nixpkgs.follows = "nixpkgs-unstable";
url = "github:hyprwm/xdg-desktop-portal-hyprland";
};
};
outputs = inputs: inputs.flakegen ./flake.in.nix inputs;
}

76
install.fish Normal file
View file

@ -0,0 +1,76 @@
#!/usr/bin/env fish
# sudo nix --experimental-features 'nix-command flakes' run nixpkgs#fish -- install.fish
# Wrap command execution in log output with error handling
function execute
if $argv &>>install.log
echo " done."
else
echo " error."
exit 1
end
end
# Alias nix to enable flakes
alias nix "nix --experimental-features 'nix-command flakes'"
# Gather variables
set -l machine (read -P "Enter machine hostname: ")
set -l secret (read -P "Enter encryption secret: ")
# Clear logfile
echo "Logging to install.log..."
rm install.log &>/dev/null
# Create keyfile
echo -n "Creating secret.key..."
execute nix run nixpkgs#fish -- -c "echo -n $secret > /tmp/secret.key"
# Format disks
echo -n "Formatting disks..."
execute nix run disko -- -m disko machines/$machine/disko.nix
# Shred keyfile
echo -n "Shredding secret.key..."
execute shred -zu /tmp/secret.key
# Generate hardware configuration
echo -n "Generating hardware-configuration.nix..."
execute nixos-generate-config --no-filesystems --root /mnt --dir .
# Move hardware configuration
echo -n "Moving hardware-configuration.nix to machines/$machine/..."
execute mv hardware-configuration.nix machines/$machine/
# Stage files in git tree for flake to access
git add .
# Update flake
echo -n "Updating flake.lock..."
execute nix flake update
# Confirm installation of NixOS
while true
switch (read -P "Install NixOS? [Y/N] ")
case Y y
break
case N n
exit
end
end
# Install NixOS
echo -n "Installing..."
execute nixos-install --no-root-password --flake .#$machine
# Update git remote to remove personal access token
echo -n "Updating git remotes..."
git remote rm origin
execute git remote add git@github.com/Myned/nixos.git
# Copy NixOS configuration to system
echo -n "Copying NixOS configuration to /mnt/etc/nixos/..."
execute cp -r . /mnt/etc/nixos/
# Finish
echo "Installation finished. Reboot when ready."

View file

@ -0,0 +1,15 @@
{
imports = [
./disko.nix
./hardware-configuration.nix
];
custom = {
hostname = "myarm";
settings.networking = {
static = true;
ipv6 = "2a01:4f8:c17:321c::1/64";
};
};
}

62
machines/myarm/disko.nix Normal file
View file

@ -0,0 +1,62 @@
{
disko.devices = {
disk = {
master = {
type = "disk";
device = "/dev/sda";
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/swap" = {
mountpoint = "/swap";
swap.swapfile.size = "8G";
};
};
};
};
};
};
};
};
};
}

View file

@ -0,0 +1,32 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.initrd.availableKernelModules = [
"xhci_pci"
"virtio_scsi"
"sr_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
}

View file

@ -0,0 +1,23 @@
{
imports = [
./disko.nix
./hardware-configuration.nix
];
custom.hostname = "myeck";
fileSystems = {
"/mnt/external" = {
device = "/dev/disk/by-label/external";
options = [
"noatime"
"nofail"
"users"
"exec"
"x-gvfs-show"
];
};
};
systemd.tmpfiles.rules = [ "z /mnt/external 0755 myned users" ];
}

62
machines/myeck/disko.nix Normal file
View file

@ -0,0 +1,62 @@
{
disko.devices = {
disk = {
master = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/swap" = {
mountpoint = "/swap";
swap.swapfile.size = "16G";
};
};
};
};
};
};
};
};
};
}

View file

@ -0,0 +1,39 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot.initrd.availableKernelModules = [
"nvme"
"dwc3_pci"
"xhci_pci"
"usbhid"
"usb_storage"
"sd_mod"
"sdhci_pci"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp4s0f3u1u1.useDHCP = lib.mkDefault true;
# networking.interfaces.enp4s0f3u1u2.useDHCP = lib.mkDefault true;
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,8 @@
{
imports = [
./disko.nix
./hardware-configuration.nix
];
custom.hostname = "myne";
}

67
machines/myne/disko.nix Normal file
View file

@ -0,0 +1,67 @@
{
disko.devices = {
disk = {
master = {
type = "disk";
device = "/dev/sda";
content = {
type = "gpt";
partitions = {
BOOT = {
size = "1M";
type = "EF02";
};
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/swap" = {
mountpoint = "/swap";
swap.swapfile.size = "8G";
};
};
};
};
};
};
};
};
};
}

View file

@ -0,0 +1,35 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.initrd.availableKernelModules = [
"ahci"
"xhci_pci"
"virtio_pci"
"virtio_scsi"
"sd_mod"
"sr_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

102
machines/mynix/default.nix Normal file
View file

@ -0,0 +1,102 @@
{
imports = [
./disko.nix
./hardware-configuration.nix
];
custom = {
hostname = "mynix";
width = 3440;
height = 1440;
};
boot.kernelParams = [
# https://gitlab.freedesktop.org/drm/amd/-/issues/2516#note_2119750
#// "gpu_sched.sched_policy=0" # Attempt to fix stutter
];
# _._ _,-'""`-._
# (,-.`._,'( |\`-/|
# `-.-' \ )-`( , o o)
# `- \`_`"'-
#// services.logind.powerKey = "ignore"; # Disable power button
# Mount external drives on boot
fileSystems = {
"/mnt/gayme" = {
device = "/dev/disk/by-label/gayme";
options = [
"noatime"
"nofail"
"users"
"exec"
"x-gvfs-show"
];
};
"/mnt/gaymer" = {
device = "/dev/disk/by-label/gaymer";
options = [
"noatime"
"nofail"
"users"
"exec"
"x-gvfs-show"
];
};
};
# Set mount directory permissions
#?? TYPE PATH MODE USER GROUP AGE ARGUMENT
systemd.tmpfiles.rules = [
"z /mnt/gayme 0755 myned users"
"z /mnt/gaymer 0755 myned users"
];
# Work around performance issues with AMD power scaling
# https://wiki.archlinux.org/title/AMDGPU#Screen_artifacts_and_frequency_problem
# https://wiki.archlinux.org/title/AMDGPU#Power_profiles
#!! cardX must match the correct gpu
#?? lspci
#?? ls -l /dev/dri/by-path/*-card
#?? grep '*' /sys/class/drm/card*/device/pp_power_profile_mode
services.udev.extraRules = ''
KERNEL=="renderD128", SUBSYSTEM=="drm", DRIVERS=="amdgpu", ATTR{device/power_dpm_force_performance_level}="manual", ATTR{device/pp_power_profile_mode}="5"
'';
# https://github.com/Zygo/bees
# Deduplicate entire filesystem
#?? Optimal for ~1TB total disk space
# https://github.com/Zygo/bees/blob/master/docs/config.md#hash-table-sizing
# services.beesd.filesystems.root = {
# spec = "/";
# verbosity = "err";
# extraOptions = [ "--loadavg-target" "5" ]; # Reduce threads on ~5% total processor load
# };
# Periodically upload current wallpaper to remote server
# systemd.user = {
# services."wallpaper" = {
# path = with pkgs; [
# openssh
# rsync
# tailscale
# variety
# ];
# #!! Hostname dependent
# script = ''
# rsync --chown caddy:caddy "$(variety --current)" root@myarm:/srv/static/wallpaper.png
# '';
# };
# timers."wallpaper" = {
# wantedBy = [ "timers.target" ];
# timerConfig = {
# OnBootSec = "1m";
# OnUnitActiveSec = "1m";
# };
# };
# };
}

68
machines/mynix/disko.nix Normal file
View file

@ -0,0 +1,68 @@
{
disko.devices = {
disk = {
master = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
settings.allowDiscards = true;
passwordFile = "/tmp/secret.key";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/swap" = {
mountpoint = "/swap";
swap.swapfile.size = "32G";
};
};
};
};
};
};
};
};
};
};
}

View file

@ -0,0 +1,39 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot.initrd.availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usbhid"
"uas"
"usb_storage"
"sd_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true;
# networking.interfaces.enp5s0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,81 @@
{
config,
inputs,
lib,
pkgs,
...
}:
let
brightnessctl = "${pkgs.brightnessctl}/bin/brightnessctl";
in
{
imports = [
inputs.nixos-hardware.nixosModules.framework-13-7040-amd
./disko.nix
./hardware-configuration.nix
];
custom = {
hostname = "myork";
width = 2256;
height = 1504;
scale = 1.5;
services = {
fw-fanctrl.enable = true;
auto-cpufreq.max = {
battery = 3; # GHz
charger = 3.5; # GHz
};
};
};
home-manager.users.${config.custom.username} = with lib; {
wayland.windowManager.hyprland.settings = {
exec-once = [ "${brightnessctl} set 0%" ];
master = {
mfact = mkForce 0.5;
orientation = mkForce "top";
always_center_master = mkForce false;
};
device = [
{
name = "pixa3854:00-093a:0274-touchpad";
accel_profile = "adaptive";
sensitivity = 0.3;
}
];
};
};
services.keyd.keyboards.default.settings.main.rightcontrol = "layer(altgr)"; # No Ctrl_R
# Enable hibernation with a swapfile on btrfs
# https://wiki.archlinux.org/title/Power_management/Suspend_and_hibernate#Hibernation_into_swap_file
#?? findmnt -no UUID -T /swap/swapfile
#?? sudo btrfs inspect-internal map-swapfile -r /swap/swapfile
boot = {
resumeDevice = "/dev/disk/by-uuid/f9416347-eff5-45d5-8dc3-93414c11ba6f";
kernelParams = [
"resume_offset=533760"
# Fix battery drain with suspend-then-hibernate
# https://wiki.archlinux.org/title/Framework_Laptop_13#Suspend-then-hibernate_on_AMD_version
"rtc_cmos.use_acpi_alarm=1"
# Force disable display power savings
# https://wiki.archlinux.org/title/Framework_Laptop_13#(AMD)_Washed-out_colors_when_using_power-profiles-daemon_in_power-saver_or_balanced_mode
"amdgpu.abmlevel=0"
# Disable AMD scaling driver
# https://wiki.archlinux.org/title/CPU_frequency_scaling#amd_pstate
#// "amd_pstate=disable"
];
};
}

68
machines/myork/disko.nix Normal file
View file

@ -0,0 +1,68 @@
{
disko.devices = {
disk = {
master = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
settings.allowDiscards = true;
passwordFile = "/tmp/secret.key";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"/swap" = {
mountpoint = "/swap";
swap.swapfile.size = "32G";
};
};
};
};
};
};
};
};
};
};
}

View file

@ -0,0 +1,38 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot.initrd.availableKernelModules = [
"nvme"
"xhci_pci"
"thunderbolt"
"usbhid"
"uas"
"sd_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.docker0.useDHCP = lib.mkDefault true;
# networking.interfaces.tailscale0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlan0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,12 @@
{
imports = [ ./hardware-configuration.nix ];
custom.hostname = "mypi3";
swapDevices = [
{
device = "/var/swapfile";
size = 4 * 1024; # GiB * 1024
}
];
}

View file

@ -0,0 +1,36 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot.initrd.availableKernelModules = [ ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888";
fsType = "ext4";
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enu1u1u1.useDHCP = lib.mkDefault true;
# networking.interfaces.wlan0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
}

View file

@ -0,0 +1,38 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom;
in
{
options.custom = {
### Profiles
default = mkOption { default = true; };
full = mkOption { default = false; };
minimal = mkOption { default = cfg.full; };
profile = mkOption { };
### Users
domain = mkOption { default = "bjork.tech"; };
hostname = mkOption { };
realname = mkOption { default = "Myned"; };
username = mkOption { default = "myned"; };
### Hardware
width = mkOption { default = 1920; };
height = mkOption { default = 1080; };
ultrawide = mkOption { default = cfg.width * 9 / 16 > cfg.height; }; # Wider than 16:9
hidpi = mkOption { default = cfg.scale > 1; };
scale = mkOption { default = 1; };
# TODO: Use option for border size
border = mkOption { default = 2; };
gap = mkOption { default = 10; };
padding = mkOption { default = 56; }; # ?? journalctl --user -u waybar.service | grep height:
### Misc
wallpaper = mkOption { default = false; };
};
}

View file

@ -0,0 +1,7 @@
{ config, lib, ... }:
with lib;
{
config.custom.desktops.hyprland.enable = config.custom.full;
}

View file

@ -0,0 +1,35 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.desktops.gnome;
in
{
options.custom.desktops.gnome = {
enable = mkOption { default = false; };
gdm = mkOption { default = true; };
};
config = mkIf cfg.enable {
# FIXME: xdg-desktop-portal-[gnome|gtk] not working through steam
services = {
xserver = {
enable = true;
desktopManager.gnome.enable = true;
displayManager.gdm.enable = cfg.gdm;
};
gnome.gnome-browser-connector.enable = true; # Install extensions from browser
};
# Remove default packages
# https://wiki.nixos.org/wiki/GNOME#Excluding_GNOME_Applications
environment.gnome.excludePackages = [ pkgs.gnome.gnome-shell-extensions ];
};
}

View file

@ -0,0 +1,246 @@
{
config,
inputs,
lib,
pkgs,
...
}:
with lib;
let
clipse = "${pkgs.clipse}/bin/clipse";
codium = "${
config.home-manager.users.${config.custom.username}.programs.vscode.package
}/bin/codium";
firefox-esr = "${
config.home-manager.users.${config.custom.username}.programs.firefox.finalPackage
}/bin/firefox-esr";
gnome-text-editor = "${pkgs.gnome-text-editor}/bin/gnome-text-editor";
hyprctl = "${pkgs.hyprland}/bin/hyprctl";
hyprlock = "${
config.home-manager.users.${config.custom.username}.programs.hyprlock.package
}/bin/hyprlock";
hyprpicker = "${pkgs.hyprpicker}/bin/hyprpicker";
jq = "${pkgs.jq}/bin/jq";
kill = "${pkgs.procps}/bin/kill";
kitty = "${config.home-manager.users.${config.custom.username}.programs.kitty.package}/bin/kitty";
libreoffice = "${config.custom.programs.libreoffice.package}/bin/libreoffice";
loginctl = "${pkgs.systemd}/bin/loginctl";
nautilus = "${pkgs.nautilus}/bin/nautilus";
networkmanager_dmenu = "${pkgs.networkmanager_dmenu}/bin/networkmanager_dmenu";
notify-send = "${pkgs.libnotify}/bin/notify-send";
obsidian = "${pkgs.obsidian}/bin/obsidian";
pkill = "${pkgs.procps}/bin/pkill";
playerctl = "${pkgs.playerctl}/bin/playerctl";
rofi-rbw = "${pkgs.rofi-rbw}/bin/rofi-rbw";
sleep = "${pkgs.coreutils}/bin/sleep";
swayosd-client = "${pkgs.swayosd}/bin/swayosd-client";
systemctl = "${pkgs.systemd}/bin/systemctl";
virt-manager = "${config.programs.virt-manager.package}/bin/virt-manager";
waydroid = "${pkgs.waydroid}/bin/waydroid";
wofi = "${config.home-manager.users.${config.custom.username}.programs.wofi.package}/bin/wofi";
cfg = config.custom.desktops.hyprland.binds;
in
{
options.custom.desktops.hyprland.binds.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
wayland.windowManager.hyprland.settings = {
# https://wiki.hyprland.org/Configuring/Binds
#?? bind = MODS, KEY, DISPATCHER, [PARAMS]
#?? wev
binds = {
allow_workspace_cycles = true;
disable_keybind_grabbing = true;
scroll_event_delay = 0;
};
# Lockscreen binds
bindl = [
### System
"CTRL, Delete, exec, ${hyprctl} reload"
"CTRL+ALT, Delete, exec, ${loginctl} terminate-session ''"
"SUPER, L, exec, ${hyprlock} --immediate & ${sleep} 1 && ${hyprctl} dispatch dpms off"
### Scripts
"SUPER, Delete, exec, inhibit"
];
# Mouse binds
bindm = [
"SUPER, mouse:272, movewindow" # LMB
"SUPER, mouse:273, resizewindow" # RMB
];
# Repeat binds
binde = [
# Media keys
# https://github.com/xkbcommon/libxkbcommon/blob/master/include/xkbcommon/xkbcommon-keysyms.h
", XF86AudioMute, exec, ${swayosd-client} --output-volume mute-toggle"
", XF86AudioLowerVolume, exec, ${swayosd-client} --output-volume lower"
", XF86AudioRaiseVolume, exec, ${swayosd-client} --output-volume raise"
", XF86AudioPlay, exec, ${playerctl} play-pause"
", XF86AudioPrev, exec, ${playerctl} previous"
", XF86AudioNext, exec, ${playerctl} next"
", XF86MonBrightnessDown, exec, ${swayosd-client} --brightness lower"
", XF86MonBrightnessUp, exec, ${swayosd-client} --brightness raise"
# TODO: Unused media key
#// ", XF86AudioMedia, exec, null"
];
# Release binds
bindr = [
### Applications
"SUPER, Super_L, exec, ${pkill} wofi || ${wofi} --show drun"
"SUPER+CTRL, Super_L, exec, ${pkill} wofi || calc"
"SUPER+SHIFT, Super_L, exec, ${pkill} wofi || ${wofi} --show run"
"SUPER+SHIFT+CTRL, Super_L, exec, ${pkill} wofi || ${networkmanager_dmenu}"
"SUPER+ALT, Super_L, exec, ${pkill} wofi || ${rofi-rbw}"
### Layouts
"SUPER+CTRL, Control_L, layoutmsg, swapwithmaster master"
"SUPER+SHIFT+CTRL, Control_L, layoutmsg, addmaster"
"SUPER+SHIFT+CTRL+ALT, Control_L, layoutmsg, removemaster"
### Workspaces
"SUPER+SHIFT, Shift_L, workspace, previous"
# Special workspaces
"SUPER+ALT, Alt_L, togglespecialworkspace, wallpaper"
];
# Regular binds
bind = [
### Scripts
", Print, exec, screenshot"
"SHIFT, Print, exec, screenshot -d"
"SUPER, Print, exec, screenshot -e"
"SUPER+SHIFT, Print, exec, screenshot -ed"
"SUPER+SHIFT, Delete, exec, vrr"
"SUPER, Minus, exec, audio"
"SUPER, Equal, exec, audio Normalizer"
"SUPER+SHIFT, W, exec, vm -x ${if config.custom.hidpi then "/scale:140 +f" else ""}"
"SUPER+SHIFT+CTRL, W, exec, vm ${virt-manager} --connect qemu:///system --show-domain-console myndows"
"SUPER+SHIFT+CTRL, Q, exec, close" # Quit all windows
# BUG: Freezes window when toggled
# https://github.com/hyprwm/Hyprland/issues/7609
"CTRL, Space, exec, toggle dropdown special:dropdown ${kitty} --app-id dropdown --override font_size=12"
"CTRL+SHIFT, Space, exec, toggle pip special:pip"
# TODO: Toggle trackball hand
#// "SUPER, Delete, exec, left"
### Applications
"SUPER, B, exec, [tag +browser] ${firefox-esr}"
"SUPER, C, exec, ${codium}"
"SUPER, E, exec, ${gnome-text-editor}"
"SUPER, F, exec, ${nautilus}"
"SUPER, K, exec, ${obsidian}"
"SUPER, O, exec, ${libreoffice}"
"SUPER, P, exec, ${hyprpicker} --autocopy"
"SUPER+SHIFT, P, exec, ${hyprpicker} --autocopy --format rgb"
"SUPER+SHIFT, T, exec, ${kitty}"
"SUPER, V, exec, ${kitty} --app-id clipboard --override font_size=12 ${clipse}"
"SUPER+SHIFT, V, exec, ${clipse} -clear && ${notify-send} clipse 'Clipboard cleared' --urgency low"
# Kill applications
"SUPER+SHIFT, A, exec, ${waydroid} session stop"
"SUPER+SHIFT, S, exec, ${pkill} steam"
"SUPER+SHIFT+CTRL, G, exec, ${pkill} gamescope"
# LIFX
"SUPER+ALT, Escape, exec, lifx state --color red"
"SUPER+ALT, 1, exec, lifx state --kelvin 1500"
"SUPER+ALT, 2, exec, lifx state --kelvin 2500"
"SUPER+ALT, 3, exec, lifx state --kelvin 3000"
"SUPER+ALT, 4, exec, lifx state --kelvin 4000"
"SUPER+ALT, 5, exec, lifx state --kelvin 5000"
"CTRL+ALT, 1, exec, lifx state --brightness 0.01"
"CTRL+ALT, 2, exec, lifx state --brightness 0.25"
"CTRL+ALT, 3, exec, lifx state --brightness 0.50"
"CTRL+ALT, 4, exec, lifx state --brightness 0.75"
"CTRL+ALT, 5, exec, lifx state --brightness 1.00"
"CTRL+ALT, Space, exec, lifx toggle"
### Windows
"SUPER, Q, killactive"
"SUPER+SHIFT, Q, exec, ${kill} -9 $(${hyprctl} -j activewindow | ${jq} .pid)"
"SUPER, Escape, togglefloating"
"SUPER+SHIFT, Escape, centerwindow"
"SUPER, Return, fullscreen, 1" # Maximize
"SUPER+SHIFT, Return, fullscreen, 0" # Fullscreen
"SUPER, Tab, cyclenext, tiled"
# FIXME: Handle hover focus and zorder
"SUPER+SHIFT, Tab, cyclenext, floating"
"SUPER+SHIFT, Tab, alterzorder, top"
### Groups
"SUPER, Backspace, changegroupactive, f"
"SUPER+SHIFT, Backspace, changegroupactive, b"
"SUPER+CTRL, Backspace, togglegroup"
"SUPER+SHIFT+CTRL, Backspace, lockactivegroup, toggle"
"SUPER, Up, movewindoworgroup, u"
"SUPER, Down, movewindoworgroup, d"
"SUPER, Left, movewindoworgroup, l"
"SUPER, Right, movewindoworgroup, r"
### Layouts
"SUPER, mouse:274, layoutmsg, swapwithmaster master"
"SUPER+SHIFT, mouse:274, layoutmsg, addmaster"
"SUPER+SHIFT+CTRL, mouse:274, layoutmsg, removemaster"
"SUPER, Bracketleft, layoutmsg, orientationprev"
"SUPER, Bracketright, layoutmsg, orientationnext"
"SUPER, Backslash, layoutmsg, orientationcenter"
"SUPER+SHIFT, Backslash, splitratio, exact 0.5" # Reset layout ratio
"SUPER+SHIFT, Bracketleft, splitratio, -0.1"
"SUPER+SHIFT, Bracketright, splitratio, +0.1"
### Workspaces
"SUPER, 1, workspace, 1"
"SUPER+SHIFT, 1, movetoworkspacesilent, 1"
"SUPER, 2, workspace, 2"
"SUPER+SHIFT, 2, movetoworkspacesilent, 2"
"SUPER, 3, workspace, 3"
"SUPER+SHIFT, 3, movetoworkspacesilent, 3"
"SUPER, 4, workspace, 4"
"SUPER+SHIFT, 4, movetoworkspacesilent, 4"
"SUPER, 5, workspace, 5"
"SUPER+SHIFT, 5, movetoworkspacesilent, 5"
"SUPER, 6, workspace, 6"
"SUPER+SHIFT, 6, movetoworkspacesilent, 6"
"SUPER, 7, workspace, 7"
"SUPER+SHIFT, 7, movetoworkspacesilent, 7"
"SUPER, 8, workspace, 8"
"SUPER+SHIFT, 8, movetoworkspacesilent, 8"
"SUPER, 9, workspace, 9"
"SUPER+SHIFT, 9, movetoworkspacesilent, 9"
"SUPER, 0, workspace, 10"
"SUPER+SHIFT, 0, movetoworkspacesilent, 10"
"SUPER, Z, workspace, -1"
"SUPER+SHIFT, Z, movetoworkspacesilent, -1"
"SUPER, X, workspace, +1"
"SUPER+SHIFT, X, movetoworkspacesilent, +1"
# Named workspaces
"SUPER, G, workspace, name:game"
"SUPER+SHIFT, G, movetoworkspacesilent, name:game"
"SUPER+CTRL, G, workspace, name:gamescope"
# Special workspaces
"SUPER, A, togglespecialworkspace, android"
"SUPER, M, togglespecialworkspace, music"
"SUPER, S, togglespecialworkspace, steam"
"SUPER, T, togglespecialworkspace, terminal"
"SUPER, W, togglespecialworkspace, vm"
"SUPER, Space, togglespecialworkspace, scratchpad"
"SUPER+SHIFT, Space, movetoworkspacesilent, special:scratchpad"
];
};
};
}

View file

@ -0,0 +1,32 @@
{
config,
lib,
...
}:
with lib;
let
cfg = config.custom.desktops.hyprland;
in
{
options.custom.desktops.hyprland.enable = mkOption { default = false; };
config = mkIf cfg.enable {
custom.desktops.hyprland = mkIf config.custom.full {
binds.enable = true;
plugins.enable = true;
rules.enable = true;
settings.enable = true;
};
# https://github.com/hyprwm/Hyprland
programs.hyprland.enable = true;
# https://wiki.hyprland.org
home-manager.users.${config.custom.username}.wayland.windowManager.hyprland = {
enable = true;
systemd.variables = [ "--all" ]; # Import some environment variables into session
};
};
}

View file

@ -0,0 +1,63 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
hyprctl = "${pkgs.hyprland}/bin/hyprctl";
cfg = config.custom.desktops.hyprland.plugins;
in
{
options.custom.desktops.hyprland.plugins.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
wayland.windowManager.hyprland = {
# https://github.com/hyprwm/hyprland-plugins/tree/main/hyprbars
# https://wiki.hyprland.org/Plugins/Using-Plugins
plugins = with pkgs.hyprlandPlugins; [ hyprbars ];
settings = {
#!! Static rules
windowrulev2 = [
"plugin:hyprbars:bar_color rgb(073642), focus:0"
"plugin:hyprbars:title_color rgb(586e75), focus:0"
"plugin:hyprbars:nobar, floating:0"
"plugin:hyprbars:nobar, class:^clipboard$"
"plugin:hyprbars:nobar, class:^discord$, title:^Discord Updater$"
"plugin:hyprbars:nobar, class:^dropdown$"
"plugin:hyprbars:nobar, class:^steam_app_.+$"
"plugin:hyprbars:nobar, title:^Picture.in.[Pp]icture$"
];
# Plugin settings
plugin = {
hyprbars = {
bar_button_padding = 10;
bar_color = "rgb(002b36)";
bar_height = 30;
bar_padding = 10;
bar_precedence_over_border = true; # Render borders around hyprbars
bar_text_align = "left";
bar_text_font = "monospace";
bar_text_size = 11;
#// bar_title_enabled = false;
"col.text" = "rgb(93a1a1)";
#?? hyprbars-button = COLOR, SIZE, ICON, EXEC
hyprbars-button = [
"rgb(dc322f), 16,, ${hyprctl} dispatch killactive" # Close
"rgb(d33682), 16,, ${hyprctl} dispatch fullscreen 1" # Maximize
"rgb(6c71c4), 16,, minimize" # Minimize
];
};
};
};
};
};
}

View file

@ -0,0 +1,263 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
gamescope = "${config.programs.gamescope.package}/bin/gamescope";
loupe = "${pkgs.loupe}/bin/loupe";
steam = "${config.programs.steam.package}/bin/steam";
virt-manager = "${pkgs.virt-manager}/bin/virt-manager";
waydroid = "${pkgs.waydroid}/bin/waydroid";
kitty = "${config.home-manager.users.${config.custom.username}.programs.kitty.package}/bin/kitty";
youtube-music = "${pkgs.youtube-music}/bin/youtube-music";
cfg = config.custom.desktops.hyprland.rules;
in
{
options.custom.desktops.hyprland.rules.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
wayland.windowManager.hyprland.settings = {
# https://wiki.hyprland.org/Configuring/Workspace-Rules
#?? workspace = WORKSPACE, RULES
workspace = [
"name:gamescope, on-created-empty:MANGOHUD=0 ${gamescope} --fullscreen --steam ${steam}"
"special:android, on-created-empty:${waydroid} app launch com.YoStarEN.Arknights"
"special:music, on-created-empty:${youtube-music}"
"special:steam, on-created-empty:${steam}"
"special:terminal, on-created-empty:${kitty}"
"special:wallpaper, on-created-empty:[tile] ${loupe} /tmp/wallpaper.png"
];
# https://wiki.hyprland.org/Configuring/Window-Rules
#?? windowrulev2 = RULE, WINDOW
windowrulev2 =
with config.custom;
let
# Return hypr-formatted string, converting booleans into 0/1
format =
field: expr:
"${field}:${
toString (
if expr == true then
1
else if expr == false then
0
else
expr
)
}";
# Generate hypr-formatted window rules
#?? merge <FIELD|{FIELDS}> <EXPRESSION> <RULES>
merge =
field: expr: rules:
map (
rule:
if builtins.isAttrs field then
"${rule}, ${lib.concatStringsSep ", " (lib.mapAttrsToList (f: e: format f e) field)}"
else
"${rule}, ${format field expr}"
) rules;
class = expr: rules: merge "class" "^${expr}$" rules;
floating = expr: rules: merge "floating" expr rules;
fullscreen = expr: rules: merge "fullscreen" expr rules;
pinned = expr: rules: merge "pinned" expr rules;
tag = expr: rules: merge "tag" expr rules;
title = expr: rules: merge "title" "^${expr}$" rules;
fields = fields: rules: merge fields null rules;
### Hardware-dependent rules
# Convert truncated float to string
tr = num: toString (builtins.floor num);
# Bottom center
clipboard = rec {
x = tr (width / scale / 2 - (toInt w) / 2);
y = tr (height / scale - (toInt h) - gap - border - padding);
w = "600";
h = tr (height / scale * 0.5 * scale);
};
# Bottom center
dropdown = rec {
x = tr (width / scale / 2 - (toInt w) / 2);
y = tr (height / scale - (toInt h) - gap - border - padding);
w = tr (width / scale * (if ultrawide then 0.5 else 1) - gap - gap / 2 + 1);
h = tr (height / scale * 0.2 * scale);
};
# Top right
pip = rec {
x = tr (width / scale - (toInt w) - gap - border);
y = tr (gap + border);
w = tr (width / scale * 0.25 - gap - gap + 1);
h = tr ((toInt w) * 9 / 16); # 16:9 aspect ratio
};
in
flatten [
### Defaults
(class ".*" [
"center"
"float"
"suppressevent maximize"
"syncfullscreen"
])
(floating true [ "bordercolor rgb(073642)" ])
(fullscreen true [ "idleinhibit focus" ])
(pinned true [ "bordercolor rgb(073642) rgb(073642)" ])
# TODO: Convert to nix variables instead of tags
### Tags
(tag "android" [
"tile"
"workspace special:android"
])
(tag "browser" [
"group new lock"
"tile"
])
(tag "clipboard" [
"move ${clipboard.x} ${clipboard.y}"
"pin"
"size ${clipboard.w} ${clipboard.h}"
"stayfocused"
])
(tag "dropdown" [
"move ${dropdown.x} ${dropdown.y}"
"pin"
"size ${dropdown.w} ${dropdown.h}"
])
(tag "editor" [
"group invade"
"tile"
])
(tag "files" [
"size 1000 625"
])
(tag "game" [
"group barred"
"idleinhibit always"
"noborder"
"noshadow"
"renderunfocused"
"workspace name:game"
])
(tag "music" [
"tile"
"workspace special:music"
])
(tag "pip" [
"keepaspectratio"
"move ${pip.x} ${pip.y}"
"pin"
"size ${pip.w} ${pip.h}"
])
(tag "social" [
"group"
"tile"
])
(tag "steam" [ "workspace special:steam" ])
(tag "terminal" [ "tile" ])
(tag "vm" [ "workspace special:vm" ])
(tag "wine" [
"noborder"
"noshadow"
])
### Applications
(class ".*\\.(exe|x86_64)" [ "tag +wine" ]) # Wine
(class "(sdl-|wl|x)freerdp" [
"nomaxsize"
"tag +vm"
"tile"
])
(class "cinny" [ "tag +social" ])
(class "clipboard" [ "tag +clipboard" ])
(class "codium-url-handler" [ "tag +editor" ]) # VSCode
(class "discord" [ "tag +social" ])
(class "dropdown" [ "tag +dropdown" ])
(class "Element" [ "tag +social" ])
(class "foot" [ "tag +terminal" ])
(class "kitty" [ "tag +terminal" ])
(class "libreoffice.+" [ "tile" ])
(class "moe\\.launcher\\.the-honkers-railway-launcher" [
"size 1280 730"
"tag +game"
])
(class "obsidian" [
"group barred"
"tag +editor"
])
(class "org\\.gnome\\.Nautilus" [ "tag +files" ])
(class "org\\.telegram\\.desktop" [ "tag +social" ])
(class "org\\.wezfurlong\\.wezterm" [ "tag +terminal" ])
(class "SDL Application" [ "tag +steam" ]) # Steam
(class "Spotify" [ "tag +music" ])
(class "steam_app_1473350" [ "workspace 0" ]) # (the) Gnorp Apologue
(class "steam" [ "tag +steam" ])
(class "steam_app_.+" [ "tag +game" ]) # Proton
(class "Tap Wizard 2.x86_64" [ "workspace 0" ])
(class "virt-manager" [ "tag +vm" ])
(class "waydroid.*" [ "tag +android" ])
(class "YouTube Music" [ "tag +music" ])
(title "Picture.in.[Pp]icture" [ "tag +pip" ])
(title "Spotify Premium" [ "tag +music" ])
### Overrides
#!! Expressions are not wrapped in ^$
(fields
{
class = "^lutris$";
title = "^Lutris$";
}
[
"center"
"size 1000 500"
]
)
(fields {
tag = "steam";
title = "^notificationtoasts$";
} [ "workspace unset" ])
(fields {
tag = "steam";
title = "^Steam$";
} [ "tile" ])
(fields
{
class = "^com\\.github\\.wwmm\\.easyeffects$";
title = "^Easy Effects$";
}
[
"size 50% 50%"
]
)
(fields
{
class = "^discord$";
title = "^Discord Updater$";
}
[
"float"
"nofocus"
]
)
(fields {
class = "^virt-manager$";
title = "^.+on QEMU/KVM$";
} [ "tile" ])
];
};
};
}

View file

@ -0,0 +1,257 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
clipse = "${pkgs.clipse}/bin/clipse";
firefox-esr = "${
config.home-manager.users.${config.custom.username}.programs.firefox.finalPackage
}/bin/firefox-esr";
pkill = "${pkgs.procps}/bin/pkill";
rm = "${pkgs.coreutils}/bin/rm";
sleep = "${pkgs.coreutils}/bin/sleep";
sway-audio-idle-inhibit = "${pkgs.sway-audio-idle-inhibit}/bin/sway-audio-idle-inhibit";
systemctl = "${pkgs.systemd}/bin/systemctl";
waybar = "${
config.home-manager.users.${config.custom.username}.programs.waybar.package
}/bin/waybar";
cfg = config.custom.desktops.hyprland.settings;
in
{
options.custom.desktops.hyprland.settings.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
wayland.windowManager.hyprland.settings = {
# https://wiki.hyprland.org/Configuring/Variables/#debug
debug = {
#// disable_logs = false;
enable_stdout_logs = true; # systemd-cat
#!! May result in resolution oddities
disable_scale_checks = true;
};
# https://wiki.hyprland.org/Configuring/Monitors
#?? monitor = NAME, RESOLUTION, POSITION, SCALE
monitor = [
", highrr, auto, ${toString config.custom.scale}"
# HACK: Ensure the fallback output has a sane resolution
# https://github.com/hyprwm/Hyprland/issues/7276#issuecomment-2323346668
"FALLBACK, ${toString config.custom.width}x${toString config.custom.height}@60, auto, ${toString config.custom.scale}"
];
# https://wiki.hyprland.org/Configuring/Keywords/#setting-the-environment
#?? envd = VARIABLE, VALUE
# HACK: Mapped home-manager variables to envd in lieu of upstream fix
# https://github.com/nix-community/home-manager/issues/2659
envd =
with builtins;
attrValues (
mapAttrs (
name: value: "${name}, ${toString value}"
) config.home-manager.users.${config.custom.username}.home.sessionVariables
)
++ [
"EDITOR, gnome-text-editor"
];
# https://wiki.hyprland.org/Configuring/Keywords/#executing
#// exec = [ ];
# https://wiki.hyprland.org/Configuring/Keywords/#executing
exec-once = [
"${rm} ~/.config/qalculate/qalc.dmenu.history" # Clear calc history
"${clipse} -clear" # Clear clipboard history
"${clipse} -listen" # Monitor clipboard
sway-audio-idle-inhibit # Inhibit idle while audio is playing
# TODO: Remove when systemd service fixed
# https://github.com/Alexays/Waybar/issues/2882
"${sleep} 2 && ${systemctl} --user restart waybar"
"[tag +browser] ${firefox-esr}"
] ++ optionals config.custom.wallpaper [ "wallpaper" ];
# https://wiki.hyprland.org/Configuring/Variables/#xwayland
xwayland = {
force_zero_scaling = true;
};
# https://wiki.hyprland.org/Configuring/Master-Layout
# Optimized for ultrawide use by default
master = {
allow_small_split = true;
always_center_master = true;
mfact = 0.5;
orientation = "center";
};
# https://wiki.hyprland.org/Configuring/Variables/#general
general = {
"col.active_border" = "rgb(93a1a1)";
"col.inactive_border" = "rgba(93a1a140)";
"col.nogroup_border_active" = "rgb(dc322f)";
"col.nogroup_border" = "rgba(dc322f40)";
#// allow_tearing = true;
border_size = config.custom.border;
gaps_in = config.custom.gap / 2;
gaps_out = config.custom.gap;
layout = "master";
#// no_border_on_floating = true;
resize_on_border = true;
};
# https://wiki.hyprland.org/Configuring/Animations
#?? animation = NAME, ONOFF, SPEED, CURVE, [STYLE]
animation = [
"global, 1, 5, default"
"windows, 1, 5, default, slide"
"layers, 1, 5, default, slide"
"specialWorkspace, 1, 5, default, fade"
];
# https://wiki.hyprland.org/Configuring/Variables/#decoration
decoration = {
"col.shadow_inactive" = "rgba(0000001a)";
"col.shadow" = "rgba(00000040)";
blur.enabled = false;
dim_special = 0.5;
rounding = 12;
shadow_range = 50;
shadow_render_power = 4; # Distance falloff
};
# https://wiki.hyprland.org/Configuring/Variables/#group
group = {
"col.border_active" = "rgb(6c71c4)";
"col.border_inactive" = "rgba(6c71c440)";
"col.border_locked_active" = "rgb(d33682)";
"col.border_locked_inactive" = "rgba(d3368240)";
insert_after_current = false;
# https://wiki.hyprland.org/Configuring/Variables/#groupbar
groupbar = {
"col.active" = "rgb(6c71c4)";
"col.inactive" = "rgba(6c71c440)";
"col.locked_active" = "rgb(d33682)";
"col.locked_inactive" = "rgba(d3368240)";
font_size = if config.custom.hidpi then 16 else 10;
height = 5;
render_titles = false;
text_color = "rgb(93a1a1)";
};
};
# https://wiki.hyprland.org/Configuring/Variables/#misc
misc = {
#// animate_manual_resizes = true;
#// animate_mouse_windowdragging = true;
background_color = "rgb(073642)";
disable_hyprland_logo = true;
disable_splash_rendering = true;
focus_on_activate = true;
font_family = "monospace";
force_default_wallpaper = 0;
key_press_enables_dpms = true;
middle_click_paste = false;
# BUG: Possibly still causes hard freezes
vrr = 2; # VRR in fullscreen
};
# https://wiki.hyprland.org/Configuring/Variables/#input
input = {
accel_profile = "flat";
float_switch_override_focus = 0; # Disable float to tile hover focus
follow_mouse = 1; # Hover focus
mouse_refocus = false;
repeat_delay = 400;
repeat_rate = 40;
sensitivity = 0.5;
#// scroll_factor = 0.75;
touchpad = {
clickfinger_behavior = true; # Multi-finger clicks
natural_scroll = true;
scroll_factor = 0.4;
};
};
# https://wiki.hyprland.org/Configuring/Variables/#cursor
cursor = {
hotspot_padding = 10;
min_refresh_rate = 60; # !! Hardware dependent
no_break_fs_vrr = true;
#// no_hardware_cursors = true;
no_warps = true;
zoom_rigid = true;
};
# https://wiki.hyprland.org/Configuring/Variables/#gestures
gestures = {
workspace_swipe = true;
workspace_swipe_cancel_ratio = 0.2;
workspace_swipe_distance = 1000;
workspace_swipe_forever = true;
workspace_swipe_min_speed_to_force = 10;
};
# https://wiki.hyprland.org/Configuring/Keywords/#per-device-input-configs
#?? device = { name = NAME ... }
# TODO: Combine same devices
# FIXME: Hotplugging may result in different id
device = [
{
name = "kensington-orbit-wireless-tb-mouse";
accel_profile = "adaptive";
sensitivity = -0.6;
left_handed = true;
middle_button_emulation = true;
natural_scroll = true;
}
{
name = "orbit-bt5.0-mouse";
accel_profile = "adaptive";
sensitivity = -0.6;
left_handed = true;
middle_button_emulation = true;
natural_scroll = true;
}
{
name = "logitech-m570";
accel_profile = "adaptive";
sensitivity = -0.9;
}
{
name = "nordic-2.4g-wireless-receiver-mouse";
sensitivity = -0.6;
}
{
name = "protoarc-em11-nl-mouse";
sensitivity = -0.6;
}
{
name = "razer-razer-viper-ultimate-dongle";
sensitivity = 0;
}
{
name = "wireless-controller-touchpad";
enabled = false;
}
];
};
};
}

View file

@ -0,0 +1,12 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.desktops.kde;
in
{
options.custom.desktops.kde.enable = mkOption { default = false; };
config = mkIf cfg.enable { services.desktopManager.plasma6.enable = true; };
}

View file

@ -0,0 +1,16 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.files.agenix;
in
{
# https://wiki.nixos.org/wiki/Agenix
# https://github.com/ryantm/agenix
options.custom.files.agenix.enable = mkOption { default = false; };
config = mkIf cfg.enable {
age.identityPaths = [ "/etc/ssh/id_ed25519" ]; # !! Must be set without sshd
};
}

View file

@ -0,0 +1,12 @@
{ config, lib, ... }:
with lib;
{
config.custom.files = mkIf config.custom.default {
agenix.enable = true;
dev.enable = true;
mnt.enable = true;
nixos.enable = true;
};
}

View file

@ -0,0 +1,16 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.files.dev;
in
{
options.custom.files.dev.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# .keep empty file needed to create empty directory
# https://github.com/nix-community/home-manager/issues/2104
home.file.".dev/.keep".text = ""; # Development folder
};
}

View file

@ -0,0 +1,15 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.files.mnt;
in
{
options.custom.files.mnt.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# Set /mnt permissions
systemd.tmpfiles.rules = [ "z /mnt 0755 root root" ];
};
}

View file

@ -0,0 +1,19 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.files.nixos;
in
{
options.custom.files.nixos.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html
# Create NixOS configuration directory and set permissions
systemd.tmpfiles.rules = [
"d /etc/nixos 0755 myned root"
"Z /etc/nixos - myned root" # Recursively set owner
];
};
}

View file

@ -0,0 +1,17 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.adb;
in
{
options.custom.programs.adb.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://wiki.nixos.org/wiki/Android
# https://developer.android.com/tools/adb
programs.adb.enable = true;
users.users.${config.custom.username}.extraGroups = [ "adbusers" ];
};
}

View file

@ -0,0 +1,178 @@
const battery = await Service.import('battery')
const audio = await Service.import('audio')
const hyprland = await Service.import('hyprland')
const mpris = await Service.import('mpris')
const notifications = await Service.import('notifications')
const systemtray = await Service.import('systemtray')
/// WORKSPACES ///
const Workspaces = () => Widget.EventBox({
onScrollDown: () => hyprland.messageAsync(`dispatch workspace -1`),
onScrollUp: () => hyprland.messageAsync(`dispatch workspace +1`),
child: Widget.Box({
spacing: 8,
//?? Increase length if workspaces > 10
children: Array.from({ length: 10 }, (_, i) => i + 1).map(i => Widget.Button({
onClicked: () => hyprland.messageAsync(`dispatch workspace ${i}`),
attribute: i,
label: `${i}`,
})),
// Initial button visibility
setup: self => self.hook(hyprland, () => self.children.forEach(btn => {
btn.visible = hyprland.workspaces.some(ws => ws.id === btn.attribute)
})),
}),
})
/// CLOCK ///
const Clock = () => Widget.Label({
class_name: 'clock',
setup: self => self.poll(1000, self =>
Utils.execAsync(['date', '+%a %b %d %I:%M %p'])
.then(date => self.label = date)),
})
/// NOTIFICATIONS ///
const Notification = () => Widget.Box({
class_name: 'notification',
visible: notifications.bind('popups').transform(p => p.length > 0),
children: [
Widget.Icon({
icon: 'preferences-system-notifications-symbolic',
}),
Widget.Label({
label: notifications.bind('popups').transform(p => p[0]?.summary || ''),
}),
],
})
/// PLAYER ///
const Media = () => Widget.Button({
class_name: 'media',
on_primary_click: () => mpris.getPlayer('')?.playPause(),
on_scroll_up: () => mpris.getPlayer('')?.next(),
on_scroll_down: () => mpris.getPlayer('')?.previous(),
child: Widget.Label('-').hook(mpris, self => {
if (mpris.players[0]) {
const { track_artists, track_title } = mpris.players[0]
self.label = `${track_artists.join(', ')} - ${track_title}`
} else {
self.label = 'Nothing is playing'
}
}, 'player-changed'),
})
/// VOLUME ///
console.log(audio.speaker)
const Volume = () => Widget.Button({
on_clicked: () => audio.speaker.is_muted = !audio.speaker.is_muted,
child: Widget.Icon().hook(audio.speaker, self => {
const icon = [
[101, 'overamplified'],
[67, 'high'],
[34, 'medium'],
[0, 'low'],
].find(([threshold]) => threshold <= audio.speaker.volume * 100)?.[1]
self.icon = `audio-volume-${icon}-symbolic`
self.tooltip_text = `Volume ${Math.floor(audio.speaker.volume * 100)}%`
}),
})
/// BATTERY ///
const Battery = () => Widget.Box({
spacing: 4,
class_name: battery.bind('charging').transform(c => c ? 'charging' : ''),
visible: battery.bind('available'),
children: [
// Battery icon
Widget.Icon({
icon: battery.bind('percent').transform(p => `battery-level-${Math.floor(p / 10) * 10}-symbolic`),
}),
// Battery discharge wattage
Widget.Label({
label: battery.bind('energy-rate').transform(e => `${Math.round(e)}W`),
}),
],
})
/// TRAY ///
const SysTray = () => Widget.Box({
children: systemtray.bind('items').transform(items => {
return items.map(item => Widget.Button({
child: Widget.Icon({ binds: [['icon', item, 'icon']] }),
on_primary_click: (_, event) => item.activate(event),
on_secondary_click: (_, event) => item.openMenu(event),
binds: [['tooltip-markup', item, 'tooltip-markup']],
}))
}),
})
/// LAYOUT ///
const Left = () => Widget.Box({
spacing: 8,
children: [
Workspaces(),
],
})
const Center = () => Widget.Box({
spacing: 8,
children: [
Clock(),
Notification(),
],
})
const Right = () => Widget.Box({
hpack: 'end',
spacing: 8,
children: [
Media(),
SysTray(),
Volume(),
Battery(),
],
})
const Bar = (monitor = 0) => Widget.Window({
monitor,
name: `bar${monitor}`,
class_name: 'bar',
anchor: ['top', 'left', 'right'],
exclusivity: 'exclusive',
child: Widget.EventBox({
on_scroll_up: () => audio['speaker'].volume = audio['speaker'].volume + 1,
on_scroll_down: () => audio['speaker'].volume = audio['speaker'].volume + 1,
child: Widget.CenterBox({
spacing: 8,
start_widget: Left(),
center_widget: Center(),
end_widget: Right(),
}),
})
})
/// EXPORTS ///
export default {
style: './style.css',
windows: [Bar()],
}

View file

@ -0,0 +1,26 @@
{
config,
inputs,
lib,
...
}:
with lib;
let
cfg = config.custom.programs.ags;
in
{
options.custom.programs.ags.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
imports = [ inputs.ags.homeManagerModules.default ];
# https://aylur.github.io/ags-docs
# https://github.com/Aylur/ags
programs.ags = {
enable = true;
configDir = ./.;
};
};
}

View file

@ -0,0 +1,7 @@
/*** AGS
***/
.bar {
font: 18px monospace;
color: #eee8d5;
}

View file

@ -0,0 +1,30 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.alacritty;
in
{
options.custom.programs.alacritty.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/alacritty/alacritty
programs.alacritty = {
enable = true;
# https://alacritty.org/config-alacritty.html
settings = {
font = {
#// builtin_box_drawing = false;
size = 14;
};
window = {
dynamic_padding = true;
resize_increments = true;
};
};
};
};
}

View file

@ -0,0 +1,18 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.anime-game-launcher;
in
{
options.custom.programs.anime-game-launcher.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://github.com/an-anime-team
# https://github.com/ezKEa/aagl-gtk-on-nix
#?? If error on first setup, clone components
#?? git clone https://github.com/an-anime-team/components.git
programs.honkers-railway-launcher.enable = true;
};
}

View file

@ -0,0 +1,67 @@
{
config,
inputs,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.anyrun;
in
{
options.custom.programs.anyrun.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
imports = [ inputs.anyrun.home-managerModules.default ];
# https://github.com/Kirottu/anyrun
programs.anyrun = {
enable = true;
# https://github.com/Kirottu/anyrun/blob/master/nix/hm-module.nix
config = {
plugins = with inputs.anyrun.packages.${pkgs.system}; [
applications
dictionary
#// kidex # File search
#// randr # Hyprland only\{
rink # Calculator
shell
#// stdin # Entries from input, aka dmenu
symbols
translate
websearch
];
closeOnClick = true; # Close when clicking outside the runner
hidePluginInfo = true; # Disable plugin sections
y.fraction = 0.3; # Relative position from the top
};
# https://github.com/Kirottu/anyrun/blob/master/anyrun/res/style.css
extraCss = ''
*:not(separator) {
margin: 2px;
border-radius: 20px;
}
*:focus { outline: none; }
#window {
font: 16px monospace;
background: none;
}
#entry {
margin: 8px;
padding: 4px 12px;
font-size: 24px;
}
'';
};
};
}

View file

@ -0,0 +1,18 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.appimage;
in
{
options.custom.programs.appimage.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://wiki.nixos.org/wiki/Appimage
programs.appimage = {
enable = true;
binfmt = true;
};
};
}

View file

@ -0,0 +1,31 @@
{ config, lib, ... }:
with lib;
let
wofi = "${config.home-manager.users.${config.custom.username}.programs.wofi.package}/bin/wofi";
cfg = config.custom.programs.bitwarden-menu;
in
{
options.custom.programs.bitwarden-menu.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/firecat53/bitwarden-menu
#!! Options not available, files written directly
# https://github.com/firecat53/bitwarden-menu/blob/main/docs/configure.md
home.file.".config/bwm/config.ini".text = ''
[dmenu]
dmenu_command = ${wofi} --dmenu
[dmenu_passphrase]
obscure = True
# FIXME: Login options taking effect
[vault]
server = https://vault.bitwarden.com
twofactor = 0
session_timeout_min = 720
'';
};
}

View file

@ -0,0 +1,35 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.chromium;
in
{
options.custom.programs.chromium.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://wiki.nixos.org/wiki/Chromium
# https://www.chromium.org/chromium-projects
programs.chromium = {
enable = true;
commandLineArgs = [
"--enable-features=OverlayScrollbar,ChromeRefresh2023,TabGroupsSave,TouchpadOverscrollHistoryNavigation"
];
extensions = [
#"ajopnjidmegmdimjlfnijceegpefgped" # BetterTTV
#"nngceckbapebfimnlniiiahkandclblb" # Bitwarden
#"enamippconapkdmgfgjchkhakpfinmaj" # DeArrow
#"fnaicdffflnofjppbagibeoednhnbjhg" # floccus
#"bnomihfieiccainjcjblhegjgglakjdd" # Improve YouTube
#"mnjggcdmjocbbbhaepdhchncahnbgone" # SponsorBlock
#"clngdbkpkpeebahjckkjfobafhncgmne" # Stylus
#"kfidecgcdjjfpeckbblhmfkhmlgecoff" # Svelte DevTools
#"nplimhmoanghlebhdiboeellhgmgommi" # Tab Groups Extension
"ddkjiahejlhfcafbddmgiahcphecmpfh" # uBlock Origin Lite
];
};
};
}

View file

@ -0,0 +1,38 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.clipse;
in
{
options.custom.programs.clipse.enable = mkOption { default = false; };
config = {
# https://github.com/savedra1/clipse
environment.systemPackages = with pkgs; [
clipse
wl-clipboard
xclip
];
home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/savedra1/clipse?tab=readme-ov-file#configuration
home.file.".config/clipse/config.json".text = ''
{
"historyFile": "clipboard_history.json",
"maxHistory": 100,
"allowDuplicates": false,
"themeFile": "custom_theme.json",
"tempDir": "tmp_files",
"logFile": "clipse.log"
}
'';
};
};
}

View file

@ -0,0 +1,15 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.dconf;
in
{
options.custom.programs.dconf.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://gitlab.gnome.org/GNOME/dconf
programs.dconf.enable = true;
};
}

View file

@ -0,0 +1,78 @@
{ config, lib, ... }:
with lib;
{
config.custom.programs = mkMerge [
(mkIf config.custom.default {
direnv.enable = true;
fastfetch.enable = true;
fish.enable = true;
git.enable = true;
htop.enable = true;
man.enable = true;
mosh.enable = true;
nano.enable = true;
nh.enable = true;
nix-index.enable = true;
nushell.enable = true;
ssh.enable = true;
tmux.enable = true;
})
(mkIf config.custom.minimal {
#// alacritty.enable = true;
appimage.enable = true;
chromium.enable = true;
dconf.enable = true;
firefox.enable = true;
#// foot.enable = true;
#// gnome-terminal.enable = true;
kdeconnect.enable = true;
kitty.enable = true;
nautilus.enable = true;
nvtop.enable = true;
#// wezterm.enable = true;
})
(mkIf config.custom.full {
adb.enable = true;
ags.enable = true;
#// anyrun.enable = true;
#// bitwarden-menu.enable = true;
clipse.enable = true;
discord.enable = true;
element-desktop.enable = true;
#// fuzzel.enable = true;
gamemode.enable = true;
gamescope.enable = true;
#// gnome-shell.enable = true;
gpg.enable = true;
hyprlock.enable = true;
libreoffice.enable = true;
#// librewolf.enable = true;
localsend.enable = true;
logseq.enable = true;
mangohud.enable = true;
networkmanager-dmenu.enable = true;
#// nheko.enable = true;
nix-ld.enable = true;
obs-studio.enable = true;
#// onedrive.enable = true;
path-of-building.enable = true;
rbw.enable = true;
rofi-rbw.enable = true;
rofi.enable = true;
seahorse.enable = true;
slurp.enable = true;
steam.enable = true;
#// swaylock.enable = true;
#// thunderbird.enable = true;
tio.enable = true;
vscode.enable = true;
waybar.enable = true;
wofi.enable = true;
#// wpaperd.enable = true;
})
];
}

View file

@ -0,0 +1,19 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.direnv;
in
{
options.custom.programs.direnv.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://github.com/direnv/direnv
programs.direnv = {
enable = true;
loadInNixShell = false; # nix develop
silent = true;
};
};
}

View file

@ -0,0 +1,16 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.discord;
in
{
options.custom.programs.discord.enable = mkOption { default = false; };
config.home-manager.users.myned = mkIf cfg.enable {
home.file.".config/BetterDiscord".source =
config.home-manager.users.${config.custom.username}.lib.file.mkOutOfStoreSymlink
"/home/${config.custom.username}/SYNC/common/config/discord/BetterDiscord";
};
}

View file

@ -0,0 +1,45 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.element-desktop;
in
{
options.custom.programs.element-desktop.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# Element Desktop custom themes
# https://github.com/aaronraimist/element-themes
home.file.".config/Element/config.json".text = ''
{
"show_labs_settings": true,
"setting_defaults": {
"custom_themes": [
{
"name": "Solarized",
"is_dark": true,
"colors": {
"accent-color": "#b58900",
"primary-color": "#268bd2",
"reaction-row-button-selected-bg-color": "#268bd2",
"roomlist-background-color": "#073642",
"roomlist-highlights-color": "#002b36",
"roomlist-text-color": "#93a1a1",
"roomlist-text-secondary-color": "#586e75",
"secondary-content": "#93a1a1",
"sidebar-color": "#002b36",
"tertiary-content": "#586e75",
"timeline-background-color": "#073642",
"timeline-highlights-color": "#002b36",
"timeline-text-color": "#fdf6e3",
"timeline-text-secondary-color": "#93a1a1",
"warning-color": "#dc322f"
}
}
]
}
}
'';
};
}

View file

@ -0,0 +1,58 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
fastfetch = "${pkgs.fastfetch}/bin/fastfetch";
cfg = config.custom.programs.fastfetch;
in
{
options.custom.programs.fastfetch = {
enable = mkOption { default = false; };
greet = mkOption { default = false; };
};
config = mkIf cfg.enable {
# https://github.com/fastfetch-cli/fastfetch
environment.systemPackages = [ pkgs.fastfetch ];
# System info greeting
programs.fish.interactiveShellInit = mkIf cfg.greet ''
# If not root, print greeting
if test (id -u) -ne 0
function fish_greeting
${fastfetch}
end
end
'';
# https://github.com/fastfetch-cli/fastfetch
#!! Option not available, files written directly
home-manager.users.${config.custom.username}.home.file.".config/fastfetch/config.jsonc".text = ''
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"source": "none",
},
"modules": [
"publicip",
"datetime",
"uptime",
"processes",
"cpuusage",
"memory",
"swap",
"disk",
"diskio",
"netio",
]
}
'';
};
}

View file

@ -0,0 +1,590 @@
{
config,
inputs,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.firefox;
in
{
options.custom.programs.firefox.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# TODO: Switch to librewolf when supported by module
# https://github.com/nix-community/home-manager/pull/5128
#!! Creates package derivation
#?? config.home-manager.users.${config.custom.username}.programs.firefox.finalPackage
# https://www.mozilla.org/en-US/firefox/developer
programs.firefox = {
enable = true;
package = pkgs.firefox-esr-128;
# nativeMessagingHosts = with pkgs; [
# firefoxpwa
# gnome-browser-connector
# ];
#!! Prefer policy over profile
#?? about:profiles
profiles.default = {
# Import CSS theme with solarized overrides
# https://github.com/rafaelmardojai/firefox-gnome-theme/blob/master/theme/colors/dark.css
userChrome = ''
@import "firefox-gnome-theme/userChrome.css";
:root {
--gnome-accent: #6c71c4;
--gnome-window-background: #002b36;
--gnome-window-color: #93a1a1;
--gnome-view-background: #073642;
--gnome-sidebar-background: #002b36;
--gnome-secondary-sidebar-background: #002b36;
--gnome-menu-background: #073642;
--gnome-headerbar-background: #002b36;
--gnome-toolbar-icon-fill: #93a1a1;
--gnome-tabbar-tab-hover-background: #073642;
--gnome-tabbar-tab-active-background: #073642;
--gnome-tabbar-tab-active-hover-background: #073642;
}
:root:-moz-window-inactive {
--gnome-inactive-entry-color: #586e75;
--gnome-tabbar-tab-hover-background: #073642;
--gnome-tabbar-tab-active-background: #073642;
}
/* Center bookmarks */
#PlacesToolbarItems {
justify-content: center;
}
/* Disable bookmark folder icons */
.bookmark-item[container] > .toolbarbutton-icon {
display: none;
}
'';
userContent = ''@import "firefox-gnome-theme/userContent.css";'';
settings = {
# https://github.com/rafaelmardojai/firefox-gnome-theme?tab=readme-ov-file#features
"gnomeTheme.bookmarksToolbarUnderTabs" = true;
"gnomeTheme.systemIcons" = true;
"font.default.x-unicode" = "sans-serif";
"font.default.x-western" = "sans-serif";
"font.name-list.emoji" = "emoji"; # System emoji
"font.name.monospace.x-unicode" = "monospace";
"font.name.monospace.x-western" = "monospace";
"font.name.sans-serif.x-unicode" = "sans-serif";
"font.name.sans-serif.x-western" = "sans-serif";
"font.name.serif.x-unicode" = "sans-serif";
"font.name.serif.x-western" = "sans-serif";
"full-screen-api.ignore-widgets" = false; # Fake fullscreen
"full-screen-api.warning.delay" = -1;
"full-screen-api.warning.timeout" = 0;
"middlemouse.paste" = false;
"privacy.donottrackheader.enabled" = true;
"privacy.fingerprintingProtection" = false;
"privacy.globalprivacycontrol.enabled" = true;
"svg.context-properties.content.enabled" = true; # Dark theme icons
};
};
# https://mozilla.github.io/policy-templates
policies = {
CaptivePortal = false;
DisableFirefoxStudies = true;
DisableFormHistory = true;
DisableMasterPasswordCreation = true;
DisablePocket = true;
DisableSetDesktopBackground = true;
DisableTelemetry = true;
DNSOverHTTPS = {
Enabled = false;
Locked = true;
};
DontCheckDefaultBrowser = true;
# https://mozilla.github.io/policy-templates/#extensionsettings
#?? https://addons.mozilla.org/en-US/firefox
#?? about:support#addons
ExtensionSettings =
let
extension = id: {
install_url = "https://addons.mozilla.org/firefox/downloads/latest/${id}/latest.xpi";
installation_mode = "normal_installed";
};
in
mkMerge [
(mkIf config.custom.minimal {
"uBlock0@raymondhill.net" = extension "ublock-origin"; # uBlock Origin
})
(mkIf config.custom.full {
#// "firefox@betterttv.net" = extension "betterttv"; # BetterTTV
"{446900e4-71c2-419f-a6a7-df9c091e268b}" = extension "bitwarden-password-manager"; # Bitwarden
#// "FirefoxColor@mozilla.com" = extension "firefox-color"; # Firefox Color
#// "chrome-gnome-shell@gnome.org" = extension "gnome-shell-integration"; # GNOME Shell Integration
#// "{248e6a49-f636-4c81-9899-a456eb6291a8}" = extension "ground-news-bias-checker"; # Ground News Bias Checker
"{3c6bf0cc-3ae2-42fb-9993-0d33104fdcaf}" = extension "youtube-addon"; # ImprovedTube
"7esoorv3@alefvanoon.anonaddy.me" = extension "libredirect"; # LibRedirect
#// "firefoxpwa@filips.si" = extension "pwas-for-firefox"; # Progressive Web Apps for Firefox
"select-after-closing-current@qw.linux-2g64.local" = extension "select-after-closing-current"; # Select After Closing Current
"simple-tab-groups@drive4ik" = extension "simple-tab-groups"; # Simple Tab Groups
"sponsorBlocker@ajay.app" = extension "sponsorblock"; # SponsorBlock
"{7a7a4a92-a2a0-41d1-9fd7-1e92480d612d}" = extension "styl-us"; # Stylus
#// "{a0370179-acc3-452f-9530-246b6adb2768}" = extension "svelte-devtools"; # Svelte Devtools
"uBlock0@raymondhill.net" = extension "ublock-origin"; # uBlock Origin
"{a6c4a591-f1b2-4f03-b3ff-767e5bedf4e7}" = extension "user-agent-string-switcher"; # User-Agent Switcher and Manager
#// "{c49b13b1-5dee-4345-925e-0c793377e3fa}" = extension "youtube-enhancer-vc"; # YouTube Enhancer
})
];
FirefoxHome = {
Highlights = false;
Pocket = false;
Search = false;
Snippets = false;
SponsoredPocket = false;
SponsoredTopSites = false;
TopSites = false;
Locked = true;
};
FirefoxSuggest = {
ImproveSuggest = false;
SponsoredSuggestions = false;
WebSuggestions = false;
Locked = true;
};
HardwareAcceleration = true;
Homepage = {
StartPage = "previous-session";
Locked = true;
};
NetworkPrediction = false;
NoDefaultBookmarks = true;
OfferToSaveLogins = false;
OverrideFirstRunPage = "";
PasswordManagerEnabled = false;
Permissions = {
Autoplay.Default = "block-audio-video";
Location.BlockNewRequests = true;
};
PictureInPicture = {
Enabled = true;
Locked = true;
};
PopupBlocking.Default = true;
#!! Only certain preferences are supported via policies
# https://mozilla.github.io/policy-templates/#preferences
#?? about:config
Preferences =
let
locked = value: {
Value = value;
Status = "locked";
};
in
{
"accessibility.browsewithcaret" = locked false;
"accessibility.typeaheadfind" = locked false;
"browser.aboutConfig.showWarning" = locked false;
"browser.contentblocking.category" = locked "standard";
"browser.crashReports.unsubmittedCheck.autoSubmit2" = locked false;
"browser.ctrlTab.sortByRecentlyUsed" = locked false;
"browser.download.always_ask_before_handling_new_types" = locked false;
"browser.download.useDownloadDir" = locked true;
"browser.link.open_newwindow" = locked 3; # New tab
"browser.link.open_newwindow.restriction" = locked 0; # Popups in new tab
"browser.newtabpage.enabled" = locked true;
"browser.preferences.defaultPerformanceSettings.enabled" = locked true;
"browser.quitShortcut.disabled" = locked true;
"browser.search.widget.inNavBar" = locked false;
"browser.startup.homepage" = locked "about:home";
"browser.startup.page" = locked 3; # Previous session
"browser.tabs.closeTabByDblclick" = locked true;
"browser.tabs.closeWindowWithLastTab" = locked false;
"browser.tabs.insertAfterCurrent" = locked false;
"browser.tabs.insertRelatedAfterCurrent" = locked false;
"browser.tabs.loadInBackground" = locked true;
"browser.tabs.warnOnClose" = locked false;
"browser.tabs.warnOnCloseOtherTabs" = locked false;
"browser.theme.dark-private-windows" = locked false;
"browser.toolbars.bookmarks.showOtherBookmarks" = locked false;
"browser.uidensity" = locked 0;
"browser.warnOnQuitShortcut" = locked true;
"dom.security.https_only_mode" = locked true;
"extensions.formautofill.addresses.enabled" = locked false;
"extensions.formautofill.creditCards.enabled" = locked false;
"general.autoScroll" = locked false;
"general.smoothScroll" = locked true;
"layers.acceleration.force-enabled" = locked true;
"layout.css.always_underline_links" = locked false;
"layout.css.backdrop-filter.enabled" = locked true;
"layout.spellcheckDefault" = locked 0; # Disabled
"media.eme.enabled" = locked true; # DRM
"media.hardwaremediakeys.enabled" = locked true;
"media.hardware-video-decoding.enabled" = locked false; # !! Disable video acceleration
#// "media.rdd-process.enabled" = locked false; # RDD sandbox #!! Insecure
"toolkit.legacyUserProfileCustomizations.stylesheets" = locked true;
"ui.key.menuAccessKey" = locked 0; # Disable menu key
"widget.gtk.overlay-scrollbars.enabled" = locked true;
"widget.gtk.rounded-bottom-corners.enabled" = locked true;
};
SearchBar = "unified";
# https://mozilla.github.io/policy-templates/#searchengines-this-policy-is-only-available-on-the-esr
SearchEngines = {
Default = "SearXNG";
Add = [
{
Name = "Amazon";
Alias = "a";
IconURL = "https://www.amazon.com/favicon.ico";
URLTemplate = "https://www.amazon.com/s?k={searchTerms}";
}
{
Name = "ArchWiki";
Alias = "aw";
IconURL = "https://wiki.archlinux.org/favicon.ico";
URLTemplate = "https://wiki.archlinux.org/index.php?search={searchTerms}";
}
{
Name = "Brave";
Alias = "b";
IconURL = "https://cdn.search.brave.com/serp/v2/_app/immutable/assets/favicon.c09fe1a1.ico";
URLTemplate = "https://search.brave.com/search?q={searchTerms}";
}
{
Name = "Docker Hub";
Alias = "dh";
IconURL = "https://hub.docker.com/favicon.ico";
URLTemplate = "https://hub.docker.com/search?q={searchTerms}";
}
{
Name = "Duck";
Alias = "d";
IconURL = "https://duckduckgo.com/favicon.ico";
URLTemplate = "https://duckduckgo.com/?q={searchTerms}";
SuggestURLTemplate = "https://duckduckgo.com/ac/?type=list&q={searchTerms}";
}
{
Name = "e621";
Alias = "e";
IconURL = "https://e621.net/favicon.ico";
URLTemplate = "https://e621.net/posts?tags={searchTerms}";
}
{
Name = "Element Issues";
Alias = "ei";
IconURL = "https://github.com/favicon.ico";
URLTemplate = "https://github.com/element-hq/element-web/issues?q=is%3Aissue+is%3Aopen+{searchTerms}";
}
{
Name = "Flathub";
Alias = "fh";
IconURL = "https://flathub.org/favicon.png";
URLTemplate = "https://flathub.org/apps/search?q={searchTerms}";
}
{
Name = "GitHub";
Alias = "gh";
IconURL = "https://github.com/favicon.ico";
URLTemplate = "https://github.com/search?q={searchTerms}";
}
{
Name = "Google";
Alias = "g";
IconURL = "https://www.google.com/favicon.ico";
URLTemplate = "https://www.google.com/search?q={searchTerms}";
}
{
Name = "Home Manager Options";
Alias = "ho";
IconURL = "https://home-manager-options.extranix.com/images/favicon.png";
URLTemplate = "https://home-manager-options.extranix.com/?query={searchTerms}&release=master";
}
{
Name = "Home Manager Issues";
Alias = "hi";
IconURL = "https://github.com/favicon.ico";
URLTemplate = "https://github.com/nix-community/home-manager/issues?q=is%3Aissue+is%3Aopen+{searchTerms}";
}
{
Name = "Hyprland Issues";
Alias = "hyi";
IconURL = "https://github.com/favicon.ico";
URLTemplate = "https://github.com/hyprwm/Hyprland/issues?q=is%3Aissue+is%3Aopen+{searchTerms}";
}
{
Name = "Lix Issues";
Alias = "li";
IconURL = "https://git.lix.systems/assets/img/favicon.png";
URLTemplate = "https://git.lix.systems/lix-project/lix/issues?state=open&q={searchTerms}";
}
{
Name = "i3 Issues";
Alias = "ii";
IconURL = "https://github.com/favicon.ico";
URLTemplate = "https://github.com/i3/i3/issues?q=is%3Aissue+is%3Aopen+{searchTerms}";
}
{
Name = "Lutris";
Alias = "l";
IconURL = "https://lutris.net/favicon.ico";
URLTemplate = "https://lutris.net/games?q={searchTerms}";
}
{
Name = "Mozilla Web Docs";
Alias = "mdn";
IconURL = "https://developer.mozilla.org/favicon-48x48.cbbd161b.png";
URLTemplate = "https://developer.mozilla.org/en-US/search?q={searchTerms}";
}
{
Name = "MyNixOS Options";
Alias = "mno";
IconURL = "https://mynixos.com/favicon.ico";
URLTemplate = "https://mynixos.com/search?q=option+{searchTerms}";
}
{
Name = "Nix Dev";
Alias = "nd";
IconURL = "https://nix.dev/manual/nix/latest/favicon.png";
URLTemplate = "https://nix.dev/manual/nix/latest?search={searchTerms}";
}
{
Name = "Nix Hub";
Alias = "nh";
IconURL = "https://www.nixhub.io/favicon.ico";
URLTemplate = "https://www.nixhub.io/search?q={searchTerms}";
}
{
Name = "Nix PR";
Alias = "npr";
URLTemplate = "https://nixpk.gs/pr-tracker.html?pr={searchTerms}";
}
{
Name = "NixOS Flakes";
Alias = "nf";
IconURL = "https://nixos.org/favicon.png";
URLTemplate = "https://search.nixos.org/flakes?channel=unstable&query={searchTerms}";
}
{
Name = "NixOS Nixpkgs Issues";
Alias = "ni";
IconURL = "https://github.com/favicon.ico";
URLTemplate = "https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+{searchTerms}";
}
{
Name = "NixOS Options";
Alias = "no";
IconURL = "https://nixos.org/favicon.png";
URLTemplate = "https://search.nixos.org/options?channel=unstable&query={searchTerms}";
}
{
Name = "NixOS Packages";
Alias = "np";
IconURL = "https://nixos.org/favicon.png";
URLTemplate = "https://search.nixos.org/packages?channel=unstable&query={searchTerms}";
}
{
Name = "NixOS Wiki";
Alias = "nw";
IconURL = "https://wiki.nixos.org/favicon.ico";
URLTemplate = "https://wiki.nixos.org/w/index.php?search={searchTerms}";
}
{
Name = "Noogle Dev";
Alias = "nod";
IconURL = "https://noogle.dev/favicon.png";
URLTemplate = "https://noogle.dev/q?term={searchTerms}";
}
{
Name = "PCGamingWiki";
Alias = "pc";
IconURL = "https://static.pcgamingwiki.com/favicons/pcgamingwiki.png";
URLTemplate = "https://www.pcgamingwiki.com/w/index.php?search={searchTerms}";
}
{
Name = "Piped";
Alias = "p";
IconURL = "https://piped.bjork.tech/favicon.ico";
URLTemplate = "https://piped.bjork.tech/results?search_query={searchTerms}";
}
{
Name = "ProtonDB";
Alias = "pdb";
IconURL = "https://www.protondb.com/sites/protondb/images/favicon.ico";
URLTemplate = "https://www.protondb.com/search?q={searchTerms}";
}
{
Name = "PyPI";
Alias = "pip";
IconURL = "https://pypi.org/static/images/favicon.35549fe8.ico";
URLTemplate = "https://pypi.org/search/?q={searchTerms}";
}
{
Name = "Reddit";
Alias = "r";
IconURL = "https://www.redditstatic.com/desktop2x/img/favicon/favicon-96x96.png";
URLTemplate = "https://search.bjork.tech/search?q=site%3Areddit.com+{searchTerms}";
}
{
Name = "SearXNG";
Alias = "s";
IconURL = "https://search.bjork.tech/static/themes/simple/img/favicon.png";
URLTemplate = "https://search.bjork.tech/search?q={searchTerms}";
}
{
Name = "Sway Issues";
Alias = "si";
IconURL = "https://github.com/favicon.ico";
URLTemplate = "https://github.com/swaywm/sway/issues?q=is%3Aissue+is%3Aopen+{searchTerms}";
}
{
Name = "Wikipedia";
Alias = "w";
IconURL = "https://en.wikipedia.org/static/favicon/wikipedia.ico";
URLTemplate = "https://en.wikipedia.org/w/index.php?search={searchTerms}";
}
{
Name = "Wolfram Alpha";
Alias = "wa";
IconURL = "https://www.wolframalpha.com/_next/static/images/favicon_1zbE9hjk.ico";
URLTemplate = "https://www.wolframalpha.com/input?i={searchTerms}";
}
{
Name = "YouTube";
Alias = "y";
IconURL = "https://www.youtube.com/s/desktop/f8c8418d/img/favicon.ico";
URLTemplate = "https://www.youtube.com/results?search_query={searchTerms}";
}
];
Remove = [
"Amazon.com"
"Bing"
"DuckDuckGo"
"eBay"
"Google"
"Wikipedia (en)"
];
};
SearchSuggestEnabled = true;
ShowHomeButton = true;
UserMessaging = {
ExtensionRecommendations = false;
FeatureRecommendations = false;
MoreFromMozilla = false;
SkipOnboarding = false;
UrlbarInterventions = false;
WhatsNew = false;
Locked = true;
};
};
};
home.file = {
# TODO: Consider other themes
# https://github.com/soulhotel/FF-ULTIMA
# CSS theme to import into profile
# https://github.com/rafaelmardojai/firefox-gnome-theme
".mozilla/firefox/default/chrome/firefox-gnome-theme".source = inputs.firefox-gnome-theme;
# Imperative symlinks intended to be synced
"Downloads/stg".source = mkIf config.custom.full (
config.home-manager.users.${config.custom.username}.lib.file.mkOutOfStoreSymlink
"/home/myned/SYNC/common/config/extensions/Simple Tab Groups"
);
# Work around icon dissociation due to missing --name flag in actions
# https://github.com/micheleg/dash-to-dock/issues/1968
#!! Keep updated with upstream desktop file
#?? cat /etc/profiles/per-user/myned/share/applications/firefox-esr.desktop
# ".local/share/applications/firefox-esr.desktop".text = ''
# [Desktop Entry]
# Actions=new-private-window;new-window;profile-manager-window
# Categories=Network;WebBrowser
# Exec=firefox --name firefox %U
# GenericName=Web Browser
# Icon=firefox
# MimeType=text/html;text/xml;application/xhtml+xml;application/vnd.mozilla.xul+xml;x-scheme-handler/http;x-scheme-handler/https
# Name=Firefox ESR
# StartupNotify=true
# StartupWMClass=firefox
# Terminal=false
# Type=Application
# Version=1.4
# [Desktop Action new-private-window]
# Exec=firefox --name firefox --private-window %U
# Name=New Private Window
# [Desktop Action new-window]
# Exec=firefox --name firefox --new-window %U
# Name=New Window
# [Desktop Action profile-manager-window]
# Exec=firefox --name firefox --ProfileManager
# Name=Profile Manager
# '';
};
};
}

View file

@ -0,0 +1,161 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.fish;
in
{
options.custom.programs.fish.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://wiki.nixos.org/wiki/Fish
# https://github.com/fish-shell/fish-shell
programs.fish = {
enable = true;
shellAbbrs = {
c = "clear";
e = "exit";
m = "mosh";
s = "ssh";
i = "tailscale ip --4";
"/h" = "cd ~";
"/hd" = "cd ~/.dev";
"/e" = "cd /etc";
"/en" = "cd /etc/nixos";
"/n" = "cd /nix";
"/nv" = "cd /nix/var";
"/nvn" = "cd /nix/var/nix";
"/nvnp" = "cd /nix/var/nix/profiles";
"/nvnps" = "cd /nix/var/nix/profiles/system";
"/r" = "cd /run";
"/rc" = "cd /run/current-system";
f = "flakegen";
r = "rebuild";
rb = "rebuild boot";
rbp = "rebuild boot && poweroff";
rbr = "rebuild boot && reboot";
rs = "rebuild switch";
rt = "rebuild test";
t = "target";
u = "upgrade";
ub = "upgrade boot";
ubp = "upgrade boot && poweroff";
ubr = "upgrade boot && reboot";
nd = "nvd diff /run/current-system /nix/var/nix/profiles/system";
no = "nh os";
nb = "flakegen && nh os boot";
nbr = "flakegen && nh os boot && reboot";
nbp = "flakegen && nh os boot && poweroff";
ns = "flakegen && nh os switch";
nt = "flakegen && nh os test";
jc = "journalctl";
sc = "systemctl";
d = "docker";
dc = "docker compose";
dcd = "docker compose down";
dce = "docker compose exec";
dcl = "docker compose logs";
dcp = "docker compose pull";
dcu = "docker compose up";
dcuf = "docker compose up --force-recreate";
ds = "docker system";
g = "git";
gb = "git bisect";
gbb = "git bisect bad";
gbg = "git bisect good";
gc = "git clone";
gs = "git status";
ta = "tmux attach";
td = "tmux detach";
tk = "tmux kill-session";
tl = "tmux list-sessions";
k = "kitten";
ks = "kitten ssh";
};
interactiveShellInit = ''
# Default is brblack (bright0)
set -g fish_color_autosuggestion brgreen
function exit -d 'Always exit successfully when interactive'
builtin exit 0
end
# TODO: Pass flags properly
# TODO: Convert to bash
function run -d 'Run packages via nixpkg flakes'
for i in (seq (count $argv))
if ! string match -r '^-' -- $argv[$i]
set argv[$i] (string replace -r ^ nixpkgs# $argv[$i])
end
end
nix run $argv
end
function shell -d 'Open packages in new shell via nixpkg flakes'
for i in (seq (count $argv))
if ! string match -r '^-' -- $argv[$i]
set argv[$i] (string replace -r ^ nixpkgs# $argv[$i])
end
end
nix shell $argv
end
function activate -d 'Activate Python venv'
source .venv/bin/activate.fish
end
function arknights -d 'Launch Arknights'
waydroid app launch com.YoStarEN.Arknights
end
'';
promptInit = ''
# Disable greeting
set -g fish_greeting
# Prompt
function fish_prompt --description 'Write out the prompt'
set -l last_status $status
set -l normal (set_color normal)
set -l status_color (set_color brgreen)
set -l cwd_color (set_color $fish_color_cwd)
set -l vcs_color (set_color brpurple)
set -l prompt_status ""
# Since we display the prompt on a new line allow the directory names to be longer.
set -q fish_prompt_pwd_dir_length
or set -lx fish_prompt_pwd_dir_length 0
# Color the prompt differently when we're root
set -l suffix ''
if functions -q fish_is_root_user; and fish_is_root_user
if set -q fish_color_cwd_root
set cwd_color (set_color $fish_color_cwd_root)
end
set suffix '#'
end
# Color the prompt in red on error
if test $last_status -ne 0
set status_color (set_color $fish_color_error)
set prompt_status $status_color "[" $last_status "]" $normal
end
echo -s (prompt_login) ' ' $cwd_color (prompt_pwd) $vcs_color (fish_vcs_prompt) $normal ' ' $prompt_status
echo -n -s $status_color $suffix ' ' $normal
end
'';
};
};
}

View file

@ -0,0 +1,47 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.foot;
in
{
options.custom.programs.foot.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://codeberg.org/dnkl/foot
programs.foot = {
enable = true;
# https://codeberg.org/dnkl/foot/src/branch/master/foot.ini
settings = {
main.font = "monospace:size=12";
scrollback.lines = 10000; # Default 1000
# Solarized Dark
# https://codeberg.org/dnkl/foot/src/branch/master/themes/solarized-dark
# https://fishshell.com/docs/current/cmds/set_color.html
colors = {
background = "002b36";
foreground = "839496";
regular0 = "073642";
regular1 = "dc322f";
regular2 = "859900";
regular3 = "b58900";
regular4 = "268bd2";
regular5 = "d33682";
regular6 = "2aa198";
regular7 = "eee8d5";
bright0 = "002b36";
bright1 = "cb4b16";
bright2 = "586e75";
bright3 = "657b83";
bright4 = "839496";
bright5 = "6c71c4";
bright6 = "93a1a1";
bright7 = "fdf6e3";
};
};
};
};
}

View file

@ -0,0 +1,42 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.fuzzel;
in
{
options.custom.programs.fuzzel.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://codeberg.org/dnkl/fuzzel
programs.fuzzel = {
enable = true;
settings = {
main = {
font = "${config.gtk.font.name}:size=12";
icon-theme = config.gtk.iconTheme.name;
horizontal-pad = 20;
inner-pad = 12;
lines = 5;
line-height = 25;
vertical-pad = 12;
layer = "overlay";
};
colors = {
background = "073642ff";
selection = "002b36ff";
selection-text = "eee8d5ff";
text = "93a1a1ff";
};
border = {
radius = 20;
width = 2;
};
};
};
};
}

View file

@ -0,0 +1,15 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.gamemode;
in
{
options.custom.programs.gamemode.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://github.com/FeralInteractive/gamemode
programs.gamemode.enable = true;
};
}

View file

@ -0,0 +1,28 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.gamescope;
in
{
options.custom.programs.gamescope.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://github.com/ValveSoftware/gamescope
#!! Issues may arise depending on environment
# https://github.com/NixOS/nixpkgs/issues/162562#issuecomment-1523177264
programs.gamescope = {
enable = true;
capSysNice = true; # Allow renice
#!! Align default window size with Steam Deck resolution
# args = [
# "--rt"
# "--output-width 1280"
# "--output-height 800"
# "--nested-refresh 60"
# ];
};
};
}

View file

@ -0,0 +1,38 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.git;
in
{
options.custom.programs.git.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://wiki.archlinux.org/title/Git
# https://git-scm.com
programs.git = {
enable = true;
userName = "Myned";
userEmail = "dev@bjork.tech";
# BUG: GitHub Desktop tries to enable if this is not in gitconfig
lfs.enable = true; # Enable Large File Storage
signing = {
signByDefault = true;
key = "C7224454F7881A34";
};
extraConfig = {
init.defaultBranch = "master";
push.autoSetupRemote = true;
pull.ff = "only";
url."git@github.com:".insteadOf = [
"gh:"
"github:"
];
};
};
};
}

View file

@ -0,0 +1,60 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.gnome-shell;
in
{
options.custom.programs.gnome-shell.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# BUG: programs.gnome-shell.theme option forces installation of gnome-shell-extensions
programs.gnome-shell = {
enable = true;
extensions =
with pkgs.gnomeExtensions;
optionals config.custom.default [
{ package = appindicator; } # https://github.com/ubuntu/gnome-shell-extension-appindicator
]
++ optionals config.custom.minimal [
{ package = caffeine; } # https://github.com/eonpatapon/gnome-shell-extension-caffeine
{ package = dash-to-dock; } # https://github.com/micheleg/dash-to-dock
#// { package = dash2dock-lite; } # https://github.com/icedman/dash2dock-lite
{ package = gsconnect; } # https://github.com/GSConnect/gnome-shell-extension-gsconnect
{ package = just-perfection; } # https://gitlab.gnome.org/jrahmatzadeh/just-perfection
#// { package = user-themes; } # https://gitlab.gnome.org/GNOME/gnome-shell-extensions
]
++ optionals config.custom.full [
#// { package = auto-move-windows; } # https://gitlab.gnome.org/GNOME/gnome-shell-extensions
{ package = clipboard-indicator; } # https://github.com/Tudmotu/gnome-shell-extension-clipboard-indicator
{ package = ddterm; } # https://github.com/ddterm/gnome-shell-extension-ddterm
#// { package = hide-top-bar; } # https://gitlab.gnome.org/tuxor1337/hidetopbar
{ package = media-controls; } # https://github.com/sakithb/media-controls
#// { package = smart-auto-move; } # https://github.com/khimaros/smart-auto-move
{ package = tailscale-qs; } # https://github.com/joaophi/tailscale-gnome-qs
{ package = tiling-assistant; } # https://github.com/Leleat/Tiling-Assistant
];
};
#!! Installed to user directory until packaged into nixpkgs
# https://github.com/flexagoon/rounded-window-corners
# TODO: Use extension store version when published
# https://extensions.gnome.org/review/55303
home.file.".local/share/gnome-shell/extensions/rounded-window-corners@fxgn".source =
mkIf config.custom.full pkgs.fetchzip
{
stripRoot = false;
url = "https://extensions.gnome.org/review/download/55303.shell-extension.zip";
sha256 = "sha256-cg4/Y0irl5X2D2P/ncYJM0fRbeAgRSfBXmdRoVBY7jo=";
};
};
}

View file

@ -0,0 +1,47 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.gnome-terminal;
in
{
options.custom.programs.gnome-terminal.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://gitlab.gnome.org/GNOME/gnome-terminal
programs.gnome-terminal = {
enable = true;
profile."8856406f-96d1-4284-8428-2329d2458b55" = {
default = true;
visibleName = "Master"; # Profile name
scrollOnOutput = false;
showScrollbar = false;
colors = {
foregroundColor = "rgb(131,148,150)";
backgroundColor = "rgb(0,43,54)";
palette = [
"rgb(7,54,66)"
"rgb(220,50,47)"
"rgb(133,153,0)"
"rgb(181,137,0)"
"rgb(38,139,210)"
"rgb(211,54,130)"
"rgb(42,161,152)"
"rgb(238,232,213)"
"rgb(0,43,54)"
"rgb(203,75,22)"
"rgb(88,110,117)"
"rgb(101,123,131)"
"rgb(131,148,150)"
"rgb(108,113,196)"
"rgb(147,161,161)"
"rgb(253,246,227)"
];
};
};
};
};
}

View file

@ -0,0 +1,19 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.gpg;
in
{
options.custom.programs.gpg.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://wiki.archlinux.org/title/GnuPG
# https://gnupg.org
programs.gpg = {
enable = true;
settings.keyserver = "hkp://keyserver.ubuntu.com";
};
};
}

View file

@ -0,0 +1,99 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.htop;
in
{
options.custom.programs.htop.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/htop-dev/htop
programs.htop = {
enable = true;
# https://nix-community.github.io/home-manager/options.xhtml#opt-programs.htop.settings
#!! Not up-to-date, some config is imperative
settings =
{
account_guest_in_cpu_meter = 1;
all_branches_collapsed = 0;
color_scheme = 0;
cpu_count_from_one = 1;
degree_fahrenheit = 0;
delay = 30;
detailed_cpu_time = 0;
enable_mouse = 1;
find_comm_in_cmdline = 0;
header_layout = "two_50_50";
header_margin = 1;
hide_function_bar = 0;
hide_kernel_threads = 1;
hide_running_in_container = 0;
hide_userland_threads = 1;
highlight_base_name = 1;
highlight_changes = 1;
highlight_changes_delay_secs = 3;
highlight_deleted_exe = 1;
highlight_megabytes = 1;
highlight_threads = 1;
screen_tabs = 1;
shadow_distribution_path_prefix = 0;
shadow_other_users = 0;
show_cpu_frequency = 0;
show_cpu_temperature = 0;
show_cpu_usage = 0;
show_merged_command = 0;
show_program_path = 0;
show_thread_names = 0;
sort_direction = -1;
sort_key = 46;
strip_exe_from_cmdline = 0;
tree_sort_direction = 1;
tree_sort_key = 0;
tree_view = 0;
tree_view_always_by_pid = 0;
update_process_names = 1;
#!! Variable max of 120
fields = with config.home-manager.users.${config.custom.username}.lib.htop.fields; [
PID
USER
PROCESSOR
PERCENT_CPU
PERCENT_MEM
IO_READ_RATE
IO_WRITE_RATE
125 # CWD
COMM
];
}
// (
with config.home-manager.users.${config.custom.username}.lib.htop;
leftMeters [
(bar "LeftCPUs4")
(text "Blank")
(bar "CPU")
(bar "MemorySwap")
(text "System")
(text "DateTime")
]
)
// (
with config.home-manager.users.${config.custom.username}.lib.htop;
rightMeters [
(bar "RightCPUs4")
(text "Blank")
(bar "NetworkIO")
(bar "DiskIO")
(text "Hostname")
(text "Uptime")
]
);
};
# https://github.com/nix-community/home-manager/issues/4947
xdg.configFile."htop/htoprc".force = true; # Force overwrite config file
};
}

View file

@ -0,0 +1,65 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.hyprlock;
in
{
options.custom.programs.hyprlock.enable = mkOption { default = false; };
config = mkIf cfg.enable {
programs.hyprlock.enable = true; # Grant PAM access
# https://wiki.hyprland.org/Hypr-Ecosystem/hyprlock
# https://github.com/hyprwm/hyprlock
home-manager.users.${config.custom.username}.programs.hyprlock = {
enable = true;
settings = {
general = {
grace = 5 * 60; # Seconds
hide_cursor = true;
immediate_render = true;
};
background = {
blur_passes = 5;
color = "rgb(073642)";
path = "/tmp/wallpaper.png";
};
input-field = {
capslock_color = "rgb(cb4b16)";
check_color = "rgb(859900)";
fade_timeout = 0;
fail_color = "rgb(dc322f)";
fail_text = "";
font_color = "rgb(fdf6e3)";
inner_color = "rgb(002b36)";
outer_color = "rgb(fdf6e3)";
outline_thickness = 0;
placeholder_text = "";
position = "0, 0";
shadow_passes = 1;
shadow_size = 2;
size = "300, 50";
};
label = {
color = "rgb(fdf6e3)";
font_family = "monospace";
font_size = 48;
halign = "center";
position = "0, 200";
text_align = "center";
valign = "center";
# 12:00 AM
# Sunday, January 01
text = "cmd[update:1000] echo \"<span allow_breaks='true'>$(date +'%I:%M %p<br/><small>%A, %B %d</small>')</span>\"";
};
};
};
};
}

View file

@ -0,0 +1,15 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.kdeconnect;
in
{
options.custom.programs.kdeconnect.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://github.com/KDE/kdeconnect-kde
programs.kdeconnect.enable = true;
};
}

View file

@ -0,0 +1,70 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.kitty;
in
{
options.custom.programs.kitty.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://sw.kovidgoyal.net/kitty/
# https://github.com/kovidgoyal/kitty
programs.kitty = {
enable = true;
font = {
name = "monospace";
size = 14;
};
# https://sw.kovidgoyal.net/kitty/conf/
#?? man kitty
settings = {
active_tab_font_style = "bold";
inactive_tab_font_style = "normal";
confirm_os_window_close = 0;
cursor_blink_interval = 0;
scrollback_lines = -1;
strip_trailing_spaces = "smart";
tab_bar_style = "powerline";
touch_scroll_multiplier = 3;
url_style = "straight";
wayland_enable_ime = "no";
window_padding_width = "0 5 5 5"; # top right bottom left
# Solarized Dark colors
# https://ethanschoonover.com/solarized/
#?? kitten themes
cursor = "none"; # Invert colors
background = "#002b36";
foreground = "#839496";
active_tab_background = "#93a1a1";
active_tab_foreground = "#002b36";
inactive_tab_background = "#586e75";
inactive_tab_foreground = "#002b36";
selection_background = "#073642"; # Affects scrollbar color
selection_foreground = "none";
url_color = "#586e75";
color0 = "#073642";
color1 = "#dc322f";
color2 = "#859900";
color3 = "#b58900";
color4 = "#268bd2";
color5 = "#d33682";
color6 = "#2aa198";
color7 = "#eee8d5";
color8 = "#002b36";
color9 = "#cb4b16";
color10 = "#586e75";
color11 = "#657b83";
color12 = "#839496";
color13 = "#6c71c4";
color14 = "#93a1a1";
color15 = "#fdf6e3";
};
};
};
}

View file

@ -0,0 +1,28 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.libreoffice;
in
{
options.custom.programs.libreoffice = {
enable = mkOption { default = false; };
package = mkOption { default = pkgs.libreoffice-fresh; };
};
config = mkIf cfg.enable {
# https://www.libreoffice.org
environment.systemPackages = [ cfg.package ];
#!! Options not available, files synced
home-manager.users.${config.custom.username}.home.file.".config/libreoffice/4/user".source =
config.home-manager.users.${config.custom.username}.lib.file.mkOutOfStoreSymlink
"/home/${config.custom.username}/SYNC/linux/config/libreoffice/user";
};
}

View file

@ -0,0 +1,17 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.librewolf;
in
{
options.custom.programs.librewolf.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://codeberg.org/librewolf
# TODO: Revisit when extensions can be managed declaratively
# https://github.com/nix-community/home-manager/issues/2803
programs.librewolf.enable = true;
};
}

View file

@ -0,0 +1,22 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.localsend;
in
{
options.custom.programs.localsend.enable = mkOption { default = false; };
config =
if (versionAtLeast version "24.11") then
(mkIf cfg.enable {
# https://github.com/localsend/localsend
programs.localsend = {
enable = true;
openFirewall = true;
};
})
else
{ };
}

View file

@ -0,0 +1,17 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.logseq;
in
{
options.custom.programs.logseq.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
#!! Synced imperative configuration
home.file.".logseq/".source =
config.home-manager.users.${config.custom.username}.lib.file.mkOutOfStoreSymlink
"/home/${config.custom.username}/SYNC/common/config/logseq/";
};
}

View file

@ -0,0 +1,24 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.man;
in
{
options.custom.programs.man.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# Enable as much offline docs as possible
# https://wiki.nixos.org/wiki/Man_pages
documentation = {
dev.enable = true; # Library manpages
man = {
generateCaches = true; # Index manpages for search
man-db.enable = false; # !! Hangs on building man-cache
mandoc.enable = true;
};
};
};
}

View file

@ -0,0 +1,49 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.mangohud;
in
{
options.custom.programs.mangohud.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/flightlessmango/MangoHud
programs.mangohud = {
enable = true;
enableSessionWide = true;
settings = {
core_load = true;
frame_timing = true;
gpu_stats = true;
no_display = true; # Hide by default
ram = true;
vram = true;
background_alpha = 0;
font_size = 24;
fps_limit = "100,75,60"; # !! Monitor dependent
background_color = "002b36";
cpu_color = "268bd2";
device_battery = "gamepad,mouse";
engine_color = "dc322f";
font_file = "${pkgs.nerdfonts}/share/fonts/truetype/NerdFonts/IosevkaNerdFont-Bold.ttf";
fps_limit_method = "early"; # Smoother frametimes compared to late
frametime_color = "859900";
gpu_color = "2aa198";
position = "top-center";
ram_color = "d33682";
text_color = "ffffff";
toggle_fps_limit = "Control_L+period";
toggle_hud = "Control_L+slash";
vram_color = "6c71c4";
};
};
};
}

View file

@ -0,0 +1,17 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.mosh;
in
{
options.custom.programs.mosh.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://wiki.nixos.org/wiki/Mosh
# https://github.com/mobile-shell/mosh
programs.mosh.enable = true; # !! Opens UDP ports 60000-61000
environment.shellAliases.mosh = "mosh --predict-overwrite";
};
}

View file

@ -0,0 +1,29 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.nano;
in
{
options.custom.programs.nano.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://wiki.archlinux.org/title/Nano
# https://www.nano-editor.org
programs.nano = {
enable = true;
# https://www.nano-editor.org/dist/latest/nanorc.5.html
#?? man nanorc
nanorc = ''
set autoindent
set magic
set minibar
set tabsize 2
set tabstospaces
set trimblanks
'';
};
};
}

View file

@ -0,0 +1,33 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.nautilus;
in
{
options.custom.programs.nautilus.enable = mkOption { default = false; };
config = mkIf cfg.enable {
services.gvfs.enable = true; # Trash dependency
# Fix nautilus extension environment
# https://github.com/NixOS/nixpkgs/pull/240780
#?? echo $NAUTILUS_4_EXTENSION_DIR
services.gnome = {
core-utilities.enable = true; # Required to set environment variables
sushi.enable = true; # Quick preview with spacebar
};
environment.systemPackages = with pkgs; [
nautilus
nautilus-open-in-blackbox
nautilus-python
];
};
}

View file

@ -0,0 +1,28 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.networkmanager-dmenu;
in
{
options.custom.programs.networkmanager-dmenu.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/firecat53/networkmanager-dmenu
# https://github.com/firecat53/networkmanager-dmenu/blob/main/config.ini.example
#!! Option not available, files written directly
# FIXME: active_chars does not take effect
home.file.".config/networkmanager-dmenu/config.ini".text =
let
wofi = "${config.home-manager.users.${config.custom.username}.programs.wofi.package}/bin/wofi";
in
''
[dmenu]
dmenu_command = ${wofi} --dmenu --lines 11
active_chars = >
wifi_icons = 󰤯󰤟󰤢󰤥󰤨
format = {icon} {name}
'';
};
}

View file

@ -0,0 +1,23 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.nh;
in
{
options.custom.programs.nh.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://github.com/viperML/nh
programs.nh = {
enable = true;
flake = "/etc/nixos";
clean = {
enable = true;
extraArgs = "--keep-since ${if config.custom.minimal then "7" else "30"}d";
};
};
};
}

View file

@ -0,0 +1,15 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.nheko;
in
{
options.custom.programs.nheko.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/Nheko-Reborn/nheko
programs.nheko.enable = true;
};
}

View file

@ -0,0 +1,23 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.nix-index;
in
{
options.custom.programs.nix-index.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://github.com/nix-community/nix-index
# https://github.com/nix-community/nix-index-database
#?? nix-index
#?? nix-locate -p <package> <pattern>
programs = {
nix-index.enable = true;
command-not-found.enable = false;
};
home-manager.users.${config.custom.username}.programs.nix-index.enable = true;
};
}

View file

@ -0,0 +1,15 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.nix-ld;
in
{
options.custom.programs.nix-ld.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://github.com/nix-community/nix-ld
programs.nix-ld.enable = true;
};
}

View file

@ -0,0 +1,18 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.nushell;
in
{
options.custom.programs.nushell.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# TODO: Create config
# https://github.com/nushell/nushell
programs.nushell = {
enable = true;
};
};
}

View file

@ -0,0 +1,50 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.nvtop;
in
{
options.custom.programs.nvtop.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/Syllo/nvtop
#!! Options not available, config written directly
#?? Imperative config generated by F12
home.file.".config/nvtop/interface.ini".text = ''
[GeneralOption]
UseColor = true
UpdateInterval = 3000
ShowInfoMessages = false
[HeaderOption]
UseFahrenheit = false
EncodeHideTimer = 3.000000e+01
[ChartOption]
ReverseChart = false
[ProcessListOption]
HideNvtopProcess = true
SortOrder = descending
SortBy = gpuRate
DisplayField = pId
DisplayField = gpuId
DisplayField = type
DisplayField = gpuRate
DisplayField = encRate
DisplayField = decRate
DisplayField = memory
DisplayField = cpuUsage
DisplayField = cpuMem
DisplayField = cmdline
[Device]
Pdev = 0000:c1:00.0
Monitor = true
ShownInfo = gpuRate
ShownInfo = gpuMemRate
'';
};
}

View file

@ -0,0 +1,15 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.obs-studio;
in
{
options.custom.programs.obs-studio.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/obsproject/obs-studio
programs.obs-studio.enable = true;
};
}

View file

@ -0,0 +1,32 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.onedrive;
in
{
options.custom.programs.onedrive.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/abraunegg/onedrive
#!! Login is imperative
#?? onedrive
#?? systemctl --user enable --now onedrive@onedrive.service
#!! Option not available, files written directly
home.file = {
# https://github.com/abraunegg/onedrive/blob/master/docs/USAGE.md#configuration
".config/onedrive/config".text = ''
sync_dir = "~/SYNC/edu/hawkeye"
'';
# https://github.com/abraunegg/onedrive/blob/master/docs/USAGE.md#performing-a-selective-sync-via-sync_list-file
".config/onedrive/sync_list".text = ''
!/Apps/
!/Attachments/
/*
'';
};
};
}

View file

@ -0,0 +1,22 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.path-of-building;
in
{
options.custom.programs.path-of-building.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
xdg.desktopEntries.path-of-building = {
name = "Path of Building";
exec = "${pkgs.path-of-building}/bin/pobfrontend";
};
};
}

View file

@ -0,0 +1,31 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.rbw;
in
{
options.custom.programs.rbw.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/doy/rbw
#!! Register with API secrets before using
#?? rbw register
#?? rbw login
programs.rbw = {
enable = true;
# https://github.com/doy/rbw?tab=readme-ov-file#configuration
settings = {
email = "myned@bjork.tech";
pinentry = pkgs.pinentry-gnome3;
};
};
};
}

View file

@ -0,0 +1,21 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.rofi-rbw;
in
{
options.custom.programs.rofi-rbw.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/fdw/rofi-rbw
#!! Options not available, files written directly
# https://github.com/fdw/rofi-rbw?tab=readme-ov-file#configuration
# TODO: Enable input emulation when merged (uinput.enable?)
# https://github.com/NixOS/nixpkgs/pull/303745
home.file.".config/rofi-rbw.rc".text = ''
action=copy
'';
};
}

View file

@ -0,0 +1,186 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.rofi;
in
{
options.custom.programs.rofi.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
#!! Creates package derivation
#?? config.home-manager.users.${config.custom.username}.programs.rofi.finalPackage
# https://github.com/lbonn/rofi
programs.rofi = {
enable = true;
package = pkgs.rofi-wayland; # Wayland fork
# TODO: Look into rofi plugins
plugins = with pkgs; [
rofi-rbw # Bitwarden
rofimoji # Character picker
# TODO: Remove when rofi v1.7.6 released
# Build against rofi-wayland due to ABI incompatibility with upstream
# https://github.com/lbonn/rofi/issues/96
# https://github.com/NixOS/nixpkgs/issues/298539
(rofi-calc.override { rofi-unwrapped = rofi-wayland-unwrapped; }) # Calculator
(rofi-top.override { rofi-unwrapped = rofi-wayland-unwrapped; }) # System monitor
];
#?? rofi-theme-selector
theme = "custom";
font = "monospace 16";
# https://github.com/davatorium/rofi/blob/next/CONFIG.md
extraConfig = {
modi = "drun,run,calc";
matching = "prefix"; # Match beginning of words
drun-display-format = "{name}"; # Display only names
drun-match-fields = "name"; # Disable matching of invisible desktop attributes
};
};
# https://github.com/davatorium/rofi/blob/next/doc/rofi-theme.5.markdown
# https://github.com/davatorium/rofi/blob/next/themes/paper-float.rasi
# TODO: Clean up theme
home.file.".config/rofi/custom.rasi".text = ''
* {
background: #073642ff;
alternate: #002b36ff;
text: #eee8d5ff;
accent: #d33682ff;
spacing: 2;
text-color: @text;
background-color: #00000000;
border-color: @accent;
anchor: north;
location: center;
}
window {
transparency: "real";
background-color: #00000000;
border: 0;
padding: 0% 0% 1em 0%;
x-offset: 0;
y-offset: -10%;
}
mainbox {
padding: 0px;
border: 0;
spacing: 1%;
}
message {
border: 2px;
padding: 1em;
background-color: @background;
text-color: @text;
}
textbox normal {
text-color: @text;
padding: 0;
border: 0;
}
listview {
fixed-height: 1;
border: 2px;
padding: 1em;
reverse: false;
columns: 1;
background-color: @background;
}
element {
border: 0;
padding: 2px;
highlight: bold ;
}
element-text {
background-color: inherit;
text-color: inherit;
}
element normal.normal {
text-color: @text;
background-color: @background;
}
element normal.urgent {
text-color: @text;
background-color: @background;
}
element normal.active {
text-color: @text;
background-color: @background;
}
element selected.normal {
text-color: @text;
background-color: @accent;
}
element selected.urgent {
text-color: @text;
background-color: @accent;
}
element selected.active {
text-color: @text;
background-color: @accent;
}
element alternate.normal {
text-color: @text;
background-color: @alternate;
}
element alternate.urgent {
text-color: @text;
background-color: @alternate;
}
element alternate.active {
text-color: @text;
background-color: @alternate;
}
scrollbar {
border: 0;
padding: 0;
}
inputbar {
spacing: 0;
border: 2px;
padding: 0.5em 1em;
background-color: @background;
index: 0;
}
inputbar normal {
foreground-color: @text;
background-color: @background;
}
mode-switcher {
border: 2px;
padding: 0.5em 1em;
background-color: @background;
index: 10;
}
button selected {
text-color: @accent;
}
inputbar {
children: [ prompt,textbox-prompt-colon,entry,case-indicator ];
}
textbox-prompt-colon {
expand: false;
str: ":";
margin: 0px 0.3em 0em 0em ;
text-color: @text;
}
error-message {
border: 2px;
padding: 1em;
background-color: @background;
text-color: @text;
}
'';
};
}

View file

@ -0,0 +1,15 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.seahorse;
in
{
options.custom.programs.seahorse.enable = mkOption { default = false; };
config = mkIf cfg.enable {
programs.seahorse.enable = true;
services.gnome.gnome-keyring.enable = true;
};
}

View file

@ -0,0 +1,22 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.slurp;
in
{
options.custom.programs.slurp.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://github.com/emersion/slurp
# https://github.com/emersion/slurp/blob/master/slurp.1.scd
home.sessionVariables.SLURP_ARGS = lib.concatStringsSep " " [
"-B 00000000"
"-b 00000000"
"-c d33682"
#// "-s d3368240"
"-w 2"
];
};
}

View file

@ -0,0 +1,18 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.ssh;
in
{
options.custom.programs.ssh.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# Disable prompt for new hosts
# MitM warning is still active
programs.ssh.extraConfig = ''
StrictHostKeyChecking no
'';
};
}

View file

@ -0,0 +1,36 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.steam;
in
{
# https://wiki.nixos.org/wiki/Steam
# https://store.steampowered.com
options.custom.programs.steam = {
enable = mkOption { default = false; };
extest = mkOption { default = false; };
};
config = mkIf cfg.enable {
programs.steam = {
enable = true;
extest.enable = cfg.extest; # Work around invisible cursor on Wayland
extraCompatPackages = [ pkgs.proton-ge-bin ];
gamescopeSession = {
enable = true;
# args = [
# "--backend sdl"
# "--fullscreen"
# ];
};
} // optionalAttrs (versionAtLeast version "24.11") { protontricks.enable = true; };
};
}

View file

@ -0,0 +1,73 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.swaylock;
in
{
options.custom.programs.swaylock.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# Allow swaylock to unlock the session
# https://wiki.nixos.org/wiki/Sway#Swaylock_cannot_be_unlocked_with_the_correct_password
security.pam.services.swaylock = { };
# https://github.com/swaywm/swaylock
home-manager.users.${config.custom.username}.programs.swaylock = {
enable = true;
# https://github.com/jirutka/swaylock-effects
package = pkgs.swaylock-effects;
# https://github.com/swaywm/swaylock/blob/master/swaylock.1.scd
#?? man swaylock
settings = {
daemonize = true;
disable-caps-lock-text = true;
line-uses-inside = true;
indicator-caps-lock = true;
indicator-idle-visible = true;
indicator-radius = 150;
font-size = 48 * config.custom.scale;
font = "monospace";
image = mkIf config.custom.wallpaper "/tmp/altered.png";
bs-hl-color = "93a1a1";
color = "073642";
inside-caps-lock-color = "002b36";
inside-clear-color = "002b36";
inside-color = "002b36";
inside-ver-color = "002b36";
inside-wrong-color = "002b36";
key-hl-color = "6c71c4";
ring-caps-lock-color = "cb4b16";
ring-clear-color = "fdf6e3";
ring-color = "002b36";
ring-ver-color = "268bd2";
ring-wrong-color = "dc322f";
separator-color = "002b36";
text-caps-lock-color = "cb4b16";
text-clear-color = "002b36";
text-color = "93a1a1";
text-ver-color = "002b36";
text-wrong-color = "002b36";
### swaylock-effects
# https://github.com/jirutka/swaylock-effects?tab=readme-ov-file#new-features
clock = true;
#// indicator = true;
effect-blur = mkIf config.custom.wallpaper "50x2";
#// fade-in = 1; # Seconds
# https://strftime.org/
datestr = "%a %b %d";
timestr = "%I:%M %p";
};
};
};
}

View file

@ -0,0 +1,87 @@
{
config,
inputs,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.custom.programs.thunderbird;
in
{
options.custom.programs.thunderbird.enable = mkOption { default = false; };
config.home-manager.users.${config.custom.username} = mkIf cfg.enable {
# https://wiki.nixos.org/wiki/Thunderbird
# https://www.thunderbird.net
programs.thunderbird = {
enable = true;
package = pkgs.thunderbird-115;
profiles.default = {
isDefault = true;
userContent = ''@import "thunderbird-gnome-theme/theme/colors/dark.css";'';
userChrome = ''
@import "thunderbird-gnome-theme/theme/gnome-theme.css";
:root {
--gnome-accent: #6c71c4;
--gnome-window-background: #002b36;
--gnome-window-color: #93a1a1;
--gnome-view-background: #073642;
--gnome-sidebar-background: #002b36;
--gnome-secondary-sidebar-background: #002b36;
--gnome-menu-background: #073642;
--gnome-headerbar-background: #002b36;
--gnome-toolbar-icon-fill: #93a1a1;
--gnome-tabbar-tab-hover-background: #073642;
--gnome-tabbar-tab-active-background: #073642;
--gnome-tabbar-tab-active-hover-background: #073642;
--layout-background-3: #073642 !important;
}
:root:-moz-window-inactive {
--gnome-inactive-entry-color: #586e75;
--gnome-tabbar-tab-hover-background: #073642;
--gnome-tabbar-tab-active-background: #073642;
}
'';
settings = {
# https://github.com/rafaelmardojai/thunderbird-gnome-theme?tab=readme-ov-file#required-thunderbird-preferences
"svg.context-properties.content.enabled" = true;
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"app.donation.eoy.version.viewed" = 5; # Disable donation banner
"browser.display.document_color_use" = 2; # Override colors
"browser.display.use_system_colors" = true;
"mail.pane_config.dynamic" = 1; # Wide view
"mailnews.message_display.disable_remote_image" = false;
# Telemetry
"datareporting.healthreport.uploadEnabled" = false;
"dom.security.unexpected_system_load_telemetry_enabled" = false;
"network.trr.confirmation_telemetry_enabled" = false;
"toolkit.telemetry.archive.enabled" = false;
"toolkit.telemetry.bhrPing.enabled" = false;
"toolkit.telemetry.firstShutdownPing.enabled" = false;
"toolkit.telemetry.newProfilePing.enabled" = false;
"toolkit.telemetry.server" = "localhost";
"toolkit.telemetry.unified" = false;
"toolkit.telemetry.updatePing.enabled" = false;
};
};
};
accounts.email.accounts.${config.custom.username}.thunderbird.enable = true;
# https://github.com/rafaelmardojai/thunderbird-gnome-theme
home.file.".thunderbird/default/chrome/thunderbird-gnome-theme".source =
inputs.thunderbird-gnome-theme;
};
}

View file

@ -0,0 +1,22 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.tio;
in
{
options.custom.programs.tio.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# Allow serial device access
# https://github.com/tio/tio?tab=readme-ov-file#46-known-issues
users.users.${config.custom.username}.extraGroups = [ "dialout" ];
# https://github.com/tio/tio
#!! Options not available, files written directly
home-manager.users.${config.custom.username}.home.file.".config/tio/config".text = ''
baudrate = 9600
'';
};
}

View file

@ -0,0 +1,20 @@
{ config, lib, ... }:
with lib;
let
cfg = config.custom.programs.tmux;
in
{
options.custom.programs.tmux.enable = mkOption { default = false; };
config = mkIf cfg.enable {
# https://wiki.nixos.org/wiki/Tmux
# https://github.com/tmux/tmux
programs.tmux = {
enable = true;
shortcut = "t";
terminal = "tmux-256color";
};
};
}

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