Initial commit
Note: not the actual initial commit. I swear I will stop repeatedly force pushing to this single commit eventually ok.
BIN
assets/CatppuccinQuagsire.png
Normal file
After Width: | Height: | Size: 295 KiB |
BIN
assets/DannyMyBrother.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
assets/DannyMyBrotherNoText.png
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
assets/EmeraldOx.png
Normal file
After Width: | Height: | Size: 4.8 MiB |
BIN
assets/EmeraldOxBlur.png
Normal file
After Width: | Height: | Size: 807 KiB |
BIN
assets/NeonBlack.jpg
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
assets/NeonColors.jpg
Normal file
After Width: | Height: | Size: 696 KiB |
BIN
assets/kevin-laminto-unsplash-catppuccin-edited.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
assets/kevin-laminto-unsplash-catppuccin.png
Normal file
After Width: | Height: | Size: 2.6 MiB |
BIN
assets/nerd.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
assets/pexels-artem-lysenko-catppuccin.jpg
Normal file
After Width: | Height: | Size: 8 MiB |
BIN
assets/pexels-stephan-seeber.jpg
Normal file
After Width: | Height: | Size: 2.6 MiB |
BIN
assets/pointingSoyjaks.png
Normal file
After Width: | Height: | Size: 315 KiB |
BIN
assets/quag-head.png
Normal file
After Width: | Height: | Size: 26 KiB |
1
assets/searxng.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="92mm" height="92mm" viewBox="0 0 92 92"><g transform="translate(-40.921 -17.417)"><circle cx="75.921" cy="53.903" r="30" style="fill:none;fill-opacity:1;stroke:#3050ff;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/><path d="M67.515 37.915a18 18 0 0 1 21.051 3.313 18 18 0 0 1 3.138 21.078" style="fill:none;fill-opacity:1;stroke:#3050ff;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/><rect width="18.846" height="39.963" x="3.706" y="122.09" ry="0" style="opacity:1;fill:#3050ff;fill-opacity:1;stroke:none;stroke-width:8;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="rotate(-46.235)"/></g></svg>
|
After Width: | Height: | Size: 726 B |
BIN
assets/snowyMountain.jpg
Normal file
After Width: | Height: | Size: 530 KiB |
1092
flake.lock
Normal file
80
flake.nix
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
# Nixos System Configuration
|
||||||
|
{
|
||||||
|
description = "Modules and configuration for my NixOS system";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-23.11";
|
||||||
|
my-nix-packages = {
|
||||||
|
url = "github:eriedaberrie/my-nix-packages";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
nix-index-database = {
|
||||||
|
url = "github:nix-community/nix-index-database";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
home-manager = {
|
||||||
|
url = "github:nix-community/home-manager";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
lanzaboote = {
|
||||||
|
url = "github:nix-community/lanzaboote";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
cl-hyprland-ipc = {
|
||||||
|
url = "github:eriedaberrie/cl-hyprland-ipc";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
# nur.url = github:nix-community/NUR;
|
||||||
|
xdph = {
|
||||||
|
url = "github:hyprwm/xdg-desktop-portal-hyprland";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
hyprland = {
|
||||||
|
url = "git+https://github.com/hyprwm/Hyprland?submodules=1";
|
||||||
|
inputs.xdph.follows = "xdph";
|
||||||
|
};
|
||||||
|
hyprlock = {
|
||||||
|
url = "github:hyprwm/hyprlock";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
emacs-overlay = {
|
||||||
|
url = "github:nix-community/emacs-overlay";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
agenix = {
|
||||||
|
url = "github:ryantm/agenix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
grim-hyprland = {
|
||||||
|
url = "github:eriedaberrie/grim-hyprland";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
spicetify-nix = {
|
||||||
|
url = "github:the-argus/spicetify-nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
nix-gaming.url = "github:fufexan/nix-gaming";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = inputs: {
|
||||||
|
nixosConfigurations = import ./hosts inputs;
|
||||||
|
lib = import ./lib inputs;
|
||||||
|
|
||||||
|
homeManagerModules.default = import ./modules/home;
|
||||||
|
nixosModules.default = import ./modules/os;
|
||||||
|
};
|
||||||
|
|
||||||
|
nixConfig = {
|
||||||
|
extra-substituters = [
|
||||||
|
"https://nix-community.cachix.org"
|
||||||
|
"https://hyprland.cachix.org"
|
||||||
|
"https://nix-gaming.cachix.org"
|
||||||
|
];
|
||||||
|
extra-trusted-public-keys = [
|
||||||
|
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||||
|
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
|
||||||
|
"nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
15
hosts/default.nix
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{ self, ... }:
|
||||||
|
|
||||||
|
self.lib.mkSystems {
|
||||||
|
|
||||||
|
msft-laptop = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
module = ./msft-laptop;
|
||||||
|
};
|
||||||
|
|
||||||
|
groceries = {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
module = ./groceries;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
89
hosts/groceries/default.nix
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./services
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
time.timeZone = "America/Los_Angeles";
|
||||||
|
|
||||||
|
my = {
|
||||||
|
user = {
|
||||||
|
username = "serverie";
|
||||||
|
homeModule = ./home;
|
||||||
|
};
|
||||||
|
|
||||||
|
fs.bootPartition = false;
|
||||||
|
|
||||||
|
zram.writebackDevice = "/dev/sdb";
|
||||||
|
|
||||||
|
cli.fish.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
initrd.availableKernelModules = [
|
||||||
|
"virtio_pci"
|
||||||
|
"virtio_scsi"
|
||||||
|
"ahci"
|
||||||
|
"sd_mod"
|
||||||
|
];
|
||||||
|
|
||||||
|
kernelParams = [ "console=ttyS0,19200n8" ];
|
||||||
|
kernelModules = [ "virtio_net" ];
|
||||||
|
|
||||||
|
loader = {
|
||||||
|
timeout = 10;
|
||||||
|
grub = {
|
||||||
|
enable = true;
|
||||||
|
forceInstall = true;
|
||||||
|
device = "nodev";
|
||||||
|
extraConfig = ''
|
||||||
|
serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1;
|
||||||
|
terminal_input serial;
|
||||||
|
terminal_output serial
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
usePredictableInterfaceNames = false;
|
||||||
|
useDHCP = false;
|
||||||
|
interfaces.eth0 = {
|
||||||
|
useDHCP = true;
|
||||||
|
tempAddress = "disabled";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
inetutils
|
||||||
|
mtr
|
||||||
|
sysstat
|
||||||
|
|
||||||
|
nil
|
||||||
|
];
|
||||||
|
|
||||||
|
documentation.enable = false;
|
||||||
|
|
||||||
|
services = {
|
||||||
|
openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
LoginGraceTime = 0;
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
PermitRootLogin = "no";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
users.users.${config.my.user.username} = {
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIElnlmCCIRhwe7z/a4dpwNoPF65II8NsOHUWJIBdr2Rg errie@nix-laptop"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFDWYERkHOqml1ntOUp8iZRTtvuAVUXcT4RRdqYtvxBy u0_a313@localhost"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
system.stateVersion = "23.05";
|
||||||
|
}
|
28
hosts/groceries/hardware-configuration.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# 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 = [ "virtio_pci" "virtio_scsi" "ahci" "sd_mod" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{ device = "/dev/sda";
|
||||||
|
fsType = "ext4";
|
||||||
|
autoResize = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# 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.enp0s5.useDHCP = lib.mkDefault true;
|
||||||
|
}
|
18
hosts/groceries/home/default.nix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
_:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ ./packages.nix ];
|
||||||
|
|
||||||
|
my = {
|
||||||
|
git.enable = true;
|
||||||
|
|
||||||
|
shell = {
|
||||||
|
aliases.enable = true;
|
||||||
|
direnv.enable = true;
|
||||||
|
fish.enable = true;
|
||||||
|
globalNpmPackages.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home.stateVersion = "23.05";
|
||||||
|
}
|
6
hosts/groceries/home/packages.nix
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
];
|
||||||
|
}
|
38
hosts/groceries/services/default.nix
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./forgejo.nix
|
||||||
|
|
||||||
|
./sync
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
"eriedaberrie.me" = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
acmeRoot = null;
|
||||||
|
serverAliases = [ "www.eriedaberrie.me" ];
|
||||||
|
locations."/".proxyPass = "http://127.0.0.1:8080/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
security.acme = {
|
||||||
|
acceptTerms = true;
|
||||||
|
defaults.email = "eriedaberrie@gmail.com";
|
||||||
|
certs = {
|
||||||
|
"eriedaberrie.me" = {
|
||||||
|
dnsProvider = "porkbun";
|
||||||
|
credentialsFile = config.age.secrets.porkbun-auth.path;
|
||||||
|
extraDomainNames = [
|
||||||
|
"www.eriedaberrie.me"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
70
hosts/groceries/services/forgejo.nix
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.forgejo;
|
||||||
|
in {
|
||||||
|
services.forgejo = {
|
||||||
|
enable = true;
|
||||||
|
appName = "Eriedaberrie's Forgejo";
|
||||||
|
lfs.enable = true;
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
PROTOCOL = "http+unix";
|
||||||
|
ROOT_URL = "https://git.eriedaberrie.me/";
|
||||||
|
};
|
||||||
|
service = {
|
||||||
|
COOKIE_SECURE = true;
|
||||||
|
DISABLE_REGISTRATION = true;
|
||||||
|
};
|
||||||
|
ui = {
|
||||||
|
DEFAULT_THEME = "catppuccin-mocha-lavender";
|
||||||
|
THEMES = "catppuccin-mocha-lavender,forgejo-auto,forgejo-light,forgejo-dark,auto,gitea,arc-green";
|
||||||
|
};
|
||||||
|
"highlight.mapping" = {
|
||||||
|
".lock" = "json";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
user = "git";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Because the module only autocreates the user if it's the default name
|
||||||
|
users.users = lib.mkIf (cfg.user != "forgejo") {
|
||||||
|
${cfg.user} = {
|
||||||
|
inherit (cfg) group;
|
||||||
|
description = "Forgejo Service";
|
||||||
|
home = cfg.stateDir;
|
||||||
|
useDefaultShell = true;
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = let
|
||||||
|
inherit (cfg) customDir user group;
|
||||||
|
catppuccinSource = pkgs.fetchzip {
|
||||||
|
url = "https://github.com/catppuccin/gitea/releases/download/v0.4.1/catppuccin-gitea.tar.gz";
|
||||||
|
hash = "sha256-14XqO1ZhhPS7VDBSzqW55kh6n5cFZGZmvRCtMEh8JPI=";
|
||||||
|
stripRoot = false;
|
||||||
|
};
|
||||||
|
fileName = "theme-catppuccin-mocha-lavender.css";
|
||||||
|
in [
|
||||||
|
"d '${customDir}/public' 0750 ${user} ${group} - -"
|
||||||
|
"d '${customDir}/public/assets' 0750 ${user} ${group} - -"
|
||||||
|
"d '${customDir}/public/assets/css' 0750 ${user} ${group} - -"
|
||||||
|
"z '${customDir}/public' 0750 ${user} ${group} - -"
|
||||||
|
"z '${customDir}/public/assets' 0750 ${user} ${group} - -"
|
||||||
|
"z '${customDir}/public/assets/css' 0750 ${user} ${group} - -"
|
||||||
|
"L+ '${customDir}/public/assets/css/${fileName}' - - - - ${catppuccinSource}/${fileName}"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
virtualHosts."git.eriedaberrie.me" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "eriedaberrie.me";
|
||||||
|
locations."/".proxyPass = "http://forgejo/";
|
||||||
|
};
|
||||||
|
|
||||||
|
upstreams.forgejo.servers."unix:${cfg.settings.server.HTTP_ADDR}" = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
security.acme.certs."eriedaberrie.me".extraDomainNames = [ "git.eriedaberrie.me" ];
|
||||||
|
}
|
18
hosts/groceries/services/sync/default.nix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
_:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./syncthing.nix
|
||||||
|
./syncyomi.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
virtualHosts."sync.eriedaberrie.me" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "eriedaberrie.me";
|
||||||
|
locations."/".return = "301 $scheme://eriedaberrie.me$request_uri";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
security.acme.certs."eriedaberrie.me".extraDomainNames = [ "sync.eriedaberrie.me" ];
|
||||||
|
}
|
39
hosts/groceries/services/sync/syncthing.nix
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
sockDir = "/run/syncthing";
|
||||||
|
cfg = config.services.syncthing;
|
||||||
|
in {
|
||||||
|
my.syncthing.enable = true;
|
||||||
|
|
||||||
|
services = {
|
||||||
|
nginx = let
|
||||||
|
upstream = "syncthing";
|
||||||
|
in {
|
||||||
|
virtualHosts."sync.eriedaberrie.me" = {
|
||||||
|
locations."/syncthing/".proxyPass = "http://${upstream}/";
|
||||||
|
};
|
||||||
|
|
||||||
|
upstreams.${upstream}.servers."unix:${cfg.guiAddress}" = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
syncthing = {
|
||||||
|
guiAddress = "${sockDir}/syncthing.sock";
|
||||||
|
settings = {
|
||||||
|
gui = {
|
||||||
|
address = cfg.guiAddress;
|
||||||
|
unixSocketPermissions = "666";
|
||||||
|
user = "serverie";
|
||||||
|
password = "$2a$10$sSOgRCl5kB0ixakiVidWI.IH26tkoNZHqf9eUwoHmHxPEDRdYDZ06";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = let
|
||||||
|
inherit (cfg) user group;
|
||||||
|
in [
|
||||||
|
"d '${sockDir}' 0755 ${user} ${group} - -"
|
||||||
|
"z '${sockDir}' 0755 ${user} ${group} - -"
|
||||||
|
];
|
||||||
|
}
|
21
hosts/groceries/services/sync/syncyomi.nix
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.syncyomi;
|
||||||
|
baseUrl = "/syncyomi/";
|
||||||
|
in {
|
||||||
|
services = {
|
||||||
|
nginx = {
|
||||||
|
virtualHosts."sync.eriedaberrie.me" = {
|
||||||
|
locations.${baseUrl}.proxyPass = "http://127.0.0.1:${builtins.toString cfg.settings.port}/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
syncyomi = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
inherit baseUrl;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
74
hosts/groceries/services/wireguard.nix
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
interface = "wg0";
|
||||||
|
listenPort = 51821;
|
||||||
|
tcpPort = 82;
|
||||||
|
in {
|
||||||
|
systemd.services."udp2raw-${interface}" = {
|
||||||
|
after = [ "network.target" ];
|
||||||
|
before = [ "wg-quick-${interface}.service" ];
|
||||||
|
wantedBy = [ "wg-quick-${interface}.service" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${pkgs.udp2raw}/bin/udp2raw -s -l 0.0.0.0:${builtins.toString tcpPort} -r 127.0.0.1:${builtins.toString listenPort} -a";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.dnsmasq = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
inherit interface;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
nat = {
|
||||||
|
enable = true;
|
||||||
|
externalInterface = "eth0";
|
||||||
|
internalInterfaces = [ interface ];
|
||||||
|
enableIPv6 = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
firewall = {
|
||||||
|
allowedUDPPorts = [ listenPort ];
|
||||||
|
allowedTCPPorts = [ tcpPort ];
|
||||||
|
interfaces.${interface} = {
|
||||||
|
allowedUDPPorts = [ 53 ];
|
||||||
|
allowedTCPPorts = [ 53 ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
wg-quick.interfaces = {
|
||||||
|
${interface} = {
|
||||||
|
address = [ "10.0.0.1/24" "fdc9:281f:04d7:9ee9::1/64" ];
|
||||||
|
inherit listenPort;
|
||||||
|
privateKeyFile = config.age.secrets.wg-groceries.path;
|
||||||
|
|
||||||
|
postUp = ''
|
||||||
|
${pkgs.iptables}/bin/iptables -A FORWARD -i wg0 -j ACCEPT
|
||||||
|
${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.0.0.1/24 -o eth0 -j MASQUERADE
|
||||||
|
${pkgs.iptables}/bin/ip6tables -A FORWARD -i wg0 -j ACCEPT
|
||||||
|
${pkgs.iptables}/bin/ip6tables -t nat -A POSTROUTING -s fdc9:281f:04d7:9ee9::1/64 -o eth0 -j MASQUERADE
|
||||||
|
'';
|
||||||
|
|
||||||
|
preDown = ''
|
||||||
|
${pkgs.iptables}/bin/iptables -D FORWARD -i wg0 -j ACCEPT
|
||||||
|
${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.0.0.1/24 -o eth0 -j MASQUERADE
|
||||||
|
${pkgs.iptables}/bin/ip6tables -D FORWARD -i wg0 -j ACCEPT
|
||||||
|
${pkgs.iptables}/bin/ip6tables -t nat -D POSTROUTING -s fdc9:281f:04d7:9ee9::1/64 -o eth0 -j MASQUERADE
|
||||||
|
'';
|
||||||
|
|
||||||
|
peers = [
|
||||||
|
{
|
||||||
|
publicKey = "mX5cMCXQbnovPOHDFdcV3egG3u9Xd3sci+mqUhFSz1Q=";
|
||||||
|
allowedIPs = [ "10.0.0.2/32" "fdc9:281f:04d7:9ee9::2/128" ];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
publicKey = "Hkk76wQQ3dYY31GYUSHMIOBgiKDPqm00cKBLMzwTO1s=";
|
||||||
|
allowedIPs = [ "10.0.0.3/32" "fdc9:281f:04d7:9ee9::3/128" ];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
22
hosts/groceries/services/wordpress.nix
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
_:
|
||||||
|
|
||||||
|
{
|
||||||
|
services = {
|
||||||
|
wordpress = {
|
||||||
|
sites."iclean.eriedaberrie.me" = {
|
||||||
|
settings = {
|
||||||
|
FORCE_SSL_ADMIN = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
webserver = "nginx";
|
||||||
|
};
|
||||||
|
|
||||||
|
nginx.virtualHosts."iclean.eriedaberrie.me" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "eriedaberrie.me";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
security.acme.certs."eriedaberrie.me".extraDomainNames = [ "iclean.eriedaberrie.me" ];
|
||||||
|
}
|
97
hosts/msft-laptop/default.nix
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
{ pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
time.timeZone = "America/Los_Angeles";
|
||||||
|
|
||||||
|
my = {
|
||||||
|
user = {
|
||||||
|
username = "errie";
|
||||||
|
homeModule = ./home;
|
||||||
|
};
|
||||||
|
|
||||||
|
secure-boot.enable = true;
|
||||||
|
bootloader.type = "systemdBoot";
|
||||||
|
|
||||||
|
fs = {
|
||||||
|
luks.enable = true;
|
||||||
|
ssd.enable = true;
|
||||||
|
bootPartition = true;
|
||||||
|
snapshots = true;
|
||||||
|
type = "btrfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
laptop = {
|
||||||
|
enable = true;
|
||||||
|
amd.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
networkManager.enable = true;
|
||||||
|
eddie = let
|
||||||
|
forwardedPorts = [ 14110 50459 ];
|
||||||
|
in {
|
||||||
|
enable = true;
|
||||||
|
allowedTCPPorts = forwardedPorts;
|
||||||
|
allowedUDPPorts = forwardedPorts;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
bin-compat.enable = true;
|
||||||
|
docker.enable = true;
|
||||||
|
interception.enable = true;
|
||||||
|
location.enable = true;
|
||||||
|
virt-manager.enable = true;
|
||||||
|
wireshark.enable = true;
|
||||||
|
|
||||||
|
syncthing = {
|
||||||
|
enable = true;
|
||||||
|
asUser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
cli = {
|
||||||
|
fish.enable = true;
|
||||||
|
nix-index.enable = true;
|
||||||
|
sudo.insults.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
desktop = {
|
||||||
|
enable = true;
|
||||||
|
audio.enable = true;
|
||||||
|
bluetooth.enable = true;
|
||||||
|
gaming.enable = true;
|
||||||
|
hyprland.enable = true;
|
||||||
|
printing.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
dos2unix
|
||||||
|
amdgpu_top
|
||||||
|
(p7zip.override {enableUnfree = true;})
|
||||||
|
];
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
git.package = pkgs.gitFull;
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.sensor.iio.enable = true;
|
||||||
|
|
||||||
|
services = {
|
||||||
|
fwupd.enable = true;
|
||||||
|
|
||||||
|
flatpak.enable = true;
|
||||||
|
|
||||||
|
openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
system.stateVersion = "23.11";
|
||||||
|
}
|
23
hosts/msft-laptop/hardware-configuration.nix
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# 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" "usb_storage" "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;
|
||||||
|
|
||||||
|
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
}
|
68
hosts/msft-laptop/home/default.nix
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ ./packages.nix ];
|
||||||
|
|
||||||
|
my = {
|
||||||
|
email.enable = true;
|
||||||
|
git.enable = true;
|
||||||
|
|
||||||
|
keepassxc.enable = true;
|
||||||
|
|
||||||
|
cli = {
|
||||||
|
bat.enable = true;
|
||||||
|
btop.enable = true;
|
||||||
|
eza.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch = {
|
||||||
|
fastfetch.enable = true;
|
||||||
|
others.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
graphical = {
|
||||||
|
enable = true;
|
||||||
|
dunst.enable = true;
|
||||||
|
emacs.enable = true;
|
||||||
|
firefox.enable = true;
|
||||||
|
mangohud.enable = true;
|
||||||
|
mpv.enable = true;
|
||||||
|
obs.enable = true;
|
||||||
|
zathura.enable = true;
|
||||||
|
|
||||||
|
wayland = {
|
||||||
|
enable = true;
|
||||||
|
fuzzel.enable = true;
|
||||||
|
hyprland.enable = true;
|
||||||
|
eww.enable = true;
|
||||||
|
foot.enable = true;
|
||||||
|
gammastep.enable = true;
|
||||||
|
hyprlock.enable = true;
|
||||||
|
ydotool.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mpd = {
|
||||||
|
enable = true;
|
||||||
|
ncmpcpp.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
shell = {
|
||||||
|
aliases.enable = true;
|
||||||
|
direnv.enable = true;
|
||||||
|
fish.enable = true;
|
||||||
|
globalNpmPackages.enable = true;
|
||||||
|
starship.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
java.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services = {
|
||||||
|
playerctld.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
home.stateVersion = "23.11";
|
||||||
|
}
|
37
hosts/msft-laptop/home/packages.nix
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{ pkgs, inputs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
home.packages = (with pkgs; [
|
||||||
|
jaq
|
||||||
|
imagemagick
|
||||||
|
ffmpeg-full
|
||||||
|
python3
|
||||||
|
ruby
|
||||||
|
lazygit
|
||||||
|
playerctl
|
||||||
|
cantata
|
||||||
|
socat
|
||||||
|
sway
|
||||||
|
imv
|
||||||
|
gimp
|
||||||
|
inkscape
|
||||||
|
xfce.thunar
|
||||||
|
yt-dlp
|
||||||
|
libqalculate
|
||||||
|
qalculate-gtk
|
||||||
|
libreoffice
|
||||||
|
(hunspellWithDicts [ hunspellDicts.en-us ])
|
||||||
|
zoom-us
|
||||||
|
slack
|
||||||
|
remmina
|
||||||
|
winetricks
|
||||||
|
ripdrag
|
||||||
|
(vesktop.override {withSystemVencord = false;})
|
||||||
|
aseprite
|
||||||
|
qbittorrent
|
||||||
|
nicotine-plus
|
||||||
|
r2modman
|
||||||
|
]) ++ (with inputs.nix-gaming.packages.${pkgs.system}; [
|
||||||
|
wine-ge
|
||||||
|
]);
|
||||||
|
}
|
98
hosts/nix-laptop/default.nix
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
{ pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
./wireguard.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
time.timeZone = "America/Los_Angeles";
|
||||||
|
|
||||||
|
my = {
|
||||||
|
user = {
|
||||||
|
username = "errie";
|
||||||
|
homeModule = ./home;
|
||||||
|
};
|
||||||
|
|
||||||
|
bootloader.type = "systemdBoot";
|
||||||
|
|
||||||
|
fs = {
|
||||||
|
bootPartition = true;
|
||||||
|
snapshots = true;
|
||||||
|
type = "btrfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
networkManager.enable = true;
|
||||||
|
eddie = {
|
||||||
|
enable = true;
|
||||||
|
allowedTCPPorts = [ 50459 ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
bin-compat.enable = true;
|
||||||
|
interception.enable = true;
|
||||||
|
location.enable = true;
|
||||||
|
virt-manager.enable = true;
|
||||||
|
wireshark.enable = true;
|
||||||
|
|
||||||
|
syncthing = {
|
||||||
|
enable = true;
|
||||||
|
asUser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
cli = {
|
||||||
|
fish.enable = true;
|
||||||
|
nix-index.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
desktop = {
|
||||||
|
enable = true;
|
||||||
|
audio.enable = true;
|
||||||
|
bluetooth.enable = true;
|
||||||
|
gaming.enable = true;
|
||||||
|
hyprland.enable = true;
|
||||||
|
printing.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.nginx.wantedBy = lib.mkForce [ ];
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
gcc
|
||||||
|
dos2unix
|
||||||
|
];
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
zsh.enable = true;
|
||||||
|
git.package = pkgs.gitFull;
|
||||||
|
};
|
||||||
|
|
||||||
|
services = {
|
||||||
|
flatpak.enable = true;
|
||||||
|
|
||||||
|
openssh.enable = true;
|
||||||
|
|
||||||
|
mullvad-vpn = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.mullvad-vpn;
|
||||||
|
};
|
||||||
|
|
||||||
|
nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts."127.0.0.1" = {
|
||||||
|
listen = [
|
||||||
|
{
|
||||||
|
addr = "127.0.0.1";
|
||||||
|
port = 80;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:3000/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
system.stateVersion = "22.11";
|
||||||
|
}
|
26
hosts/nix-laptop/hardware-configuration.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# 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" "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.enp1s0.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.wlp2s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||||
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
}
|
68
hosts/nix-laptop/home/default.nix
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ ./packages.nix ];
|
||||||
|
|
||||||
|
my = {
|
||||||
|
email.enable = true;
|
||||||
|
git.enable = true;
|
||||||
|
|
||||||
|
keepassxc.enable = true;
|
||||||
|
|
||||||
|
cli = {
|
||||||
|
bat.enable = true;
|
||||||
|
btop.enable = true;
|
||||||
|
eza.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch = {
|
||||||
|
fastfetch.enable = true;
|
||||||
|
others.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
graphical = {
|
||||||
|
enable = true;
|
||||||
|
dunst.enable = true;
|
||||||
|
emacs.enable = true;
|
||||||
|
firefox.enable = true;
|
||||||
|
mpv.enable = true;
|
||||||
|
obs.enable = true;
|
||||||
|
zathura.enable = true;
|
||||||
|
|
||||||
|
wayland = {
|
||||||
|
enable = true;
|
||||||
|
fuzzel.enable = true;
|
||||||
|
hyprland.enable = true;
|
||||||
|
eww.enable = true;
|
||||||
|
foot.enable = true;
|
||||||
|
gammastep.enable = true;
|
||||||
|
swayidle.enable = true;
|
||||||
|
swaylock.enable = true;
|
||||||
|
ydotool.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
shell = {
|
||||||
|
aliases.enable = true;
|
||||||
|
direnv.enable = true;
|
||||||
|
fish.enable = true;
|
||||||
|
globalNpmPackages.enable = true;
|
||||||
|
starship.enable = true;
|
||||||
|
zsh.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
spotify = {
|
||||||
|
spicetify.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
java.enable = true;
|
||||||
|
neovim = {
|
||||||
|
enable = true;
|
||||||
|
plugins = with pkgs.vimPlugins; [ packer-nvim ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home.stateVersion = "22.11";
|
||||||
|
}
|
45
hosts/nix-laptop/home/packages.nix
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{ pkgs, inputs, self, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
home.packages = (with pkgs; [
|
||||||
|
jaq
|
||||||
|
imagemagick
|
||||||
|
ffmpeg
|
||||||
|
nodejs
|
||||||
|
sbcl
|
||||||
|
racket
|
||||||
|
ghc
|
||||||
|
pyright
|
||||||
|
sumneko-lua-language-server
|
||||||
|
clang-tools
|
||||||
|
bear
|
||||||
|
rust-analyzer
|
||||||
|
cmake
|
||||||
|
meson
|
||||||
|
lazygit
|
||||||
|
fortune
|
||||||
|
neo-cowsay
|
||||||
|
lolcat
|
||||||
|
playerctl
|
||||||
|
socat
|
||||||
|
sway
|
||||||
|
imv
|
||||||
|
gimp
|
||||||
|
inkscape
|
||||||
|
xfce.thunar
|
||||||
|
libqalculate
|
||||||
|
qalculate-gtk
|
||||||
|
libreoffice
|
||||||
|
(hunspellWithDicts [ hunspellDicts.en-us ])
|
||||||
|
zoom-us
|
||||||
|
slack
|
||||||
|
remmina
|
||||||
|
godot_4
|
||||||
|
winetricks
|
||||||
|
ripdrag
|
||||||
|
aseprite
|
||||||
|
qbittorrent
|
||||||
|
]) ++ (with inputs.nix-gaming.packages.${pkgs.system}; [
|
||||||
|
wine-ge
|
||||||
|
]);
|
||||||
|
}
|
72
hosts/nix-laptop/wireguard.nix
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
interface = "wg0";
|
||||||
|
listenPort = 51821;
|
||||||
|
tcpPort = 82;
|
||||||
|
in {
|
||||||
|
systemd.services = {
|
||||||
|
"wg-quick-${interface}".wantedBy = lib.mkForce [ ];
|
||||||
|
|
||||||
|
"udp2raw-${interface}" = {
|
||||||
|
after = [ "network.target" ];
|
||||||
|
before = [ "wg-quick-${interface}.service" ];
|
||||||
|
requires = [ "wg-quick-${interface}.service" ];
|
||||||
|
wantedBy = [ "wg-quick-${interface}.service" ];
|
||||||
|
serviceConfig = let
|
||||||
|
remoteIP = "66.175.222.204";
|
||||||
|
in {
|
||||||
|
ExecStartPre = pkgs.writeShellScript "pre-udp2raw-${interface}" ''
|
||||||
|
eval "$(
|
||||||
|
${pkgs.iproute2}/bin/ip route | ${pkgs.gawk}/bin/awk \
|
||||||
|
'$1=="default" {
|
||||||
|
printf "%s", "${pkgs.iproute2}/bin/ip route add ${remoteIP}"
|
||||||
|
for (i=2; i<=NF; i+=2) {
|
||||||
|
if ($i=="via" || $i=="dev" || $i=="metric") {
|
||||||
|
printf " %s %s", $i, $(i+1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print " proto static"
|
||||||
|
}'
|
||||||
|
)"
|
||||||
|
'';
|
||||||
|
ExecStart = pkgs.writeShellScript "udp2raw-${interface}" ''
|
||||||
|
exec ${pkgs.udp2raw}/bin/udp2raw -c \
|
||||||
|
-l "127.0.0.1:${builtins.toString listenPort}" \
|
||||||
|
-r "${remoteIP}:${builtins.toString tcpPort}" \
|
||||||
|
-a
|
||||||
|
'';
|
||||||
|
ExecStopPost = "${pkgs.iproute2}/bin/ip route flush ${remoteIP} proto static";
|
||||||
|
Restart = "on-failure";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
firewall.checkReversePath = "loose";
|
||||||
|
|
||||||
|
wg-quick.interfaces = {
|
||||||
|
${interface} = let
|
||||||
|
publicKey = "Awb1R2KZ3v4MArN/Lmxr4BTL0rdFm5dJID6ntifr4GQ=";
|
||||||
|
in {
|
||||||
|
address = [ "10.0.0.2/32" "fdc9:281f:04d7:9ee9::2/128" ];
|
||||||
|
dns = [ "10.0.0.1" ];
|
||||||
|
privateKeyFile = config.age.secrets.wg-nix-laptop.path;
|
||||||
|
|
||||||
|
mtu = 1332;
|
||||||
|
|
||||||
|
postUp = [
|
||||||
|
"wg set wg0 peer ${publicKey} persistent-keepalive 25"
|
||||||
|
];
|
||||||
|
|
||||||
|
peers = [
|
||||||
|
{
|
||||||
|
inherit publicKey;
|
||||||
|
allowedIPs = [ "0.0.0.0/0" "::/0" ];
|
||||||
|
endpoint = "127.0.0.1:${builtins.toString listenPort}";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
33
lib/default.nix
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{ nixpkgs, self, ... } @ inputs:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (nixpkgs) lib;
|
||||||
|
in rec {
|
||||||
|
|
||||||
|
mkSystems = builtins.mapAttrs (hostName: cfg: lib.nixosSystem {
|
||||||
|
inherit (cfg) system;
|
||||||
|
specialArgs = {inherit self inputs;};
|
||||||
|
modules = [
|
||||||
|
{
|
||||||
|
networking = {inherit hostName;};
|
||||||
|
nixpkgs.hostPlatform = cfg.system;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.nixosModules.default
|
||||||
|
|
||||||
|
cfg.module
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
recReadDir = startDir: dir: lib.concatMapAttrs (file: type: let
|
||||||
|
fullFile = "${dir}/${file}";
|
||||||
|
in
|
||||||
|
if type == "directory" then recReadDir startDir fullFile
|
||||||
|
else {${fullFile} = "${startDir}/${fullFile}";}
|
||||||
|
) (builtins.readDir "${startDir}/${dir}");
|
||||||
|
|
||||||
|
filterNixReadDir = dir: lib.filterAttrs (name: _:
|
||||||
|
builtins.match ".*\\.nix" name == null
|
||||||
|
) (recReadDir dir ".");
|
||||||
|
|
||||||
|
}
|
67
modules/home/cli.nix
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.cli;
|
||||||
|
in {
|
||||||
|
options.my.cli = {
|
||||||
|
bat.enable = lib.mkEnableOption null;
|
||||||
|
btop.enable = lib.mkEnableOption null;
|
||||||
|
eza.enable = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
ranger.enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkMerge [
|
||||||
|
(lib.mkIf cfg.bat.enable {
|
||||||
|
programs.bat = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
map-syntax = [ "flake.lock:JSON" ];
|
||||||
|
theme = "catppuccinMocha";
|
||||||
|
};
|
||||||
|
themes = {
|
||||||
|
catppuccinMocha = {
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "catppuccin";
|
||||||
|
repo = "bat";
|
||||||
|
rev = "ba4d16880d63e656acced2b7d4e034e4a93f74b1";
|
||||||
|
sha256 = "1g2r6j33f4zys853i1c5gnwcdbwb6xv5w6pazfdslxf69904lrg9";
|
||||||
|
};
|
||||||
|
file = "Catppuccin-mocha.tmTheme";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
xdg.configFile."btop/themes/catppuccin_mocha.theme".source = pkgs.fetchFromGitHub {
|
||||||
|
owner = "catppuccin";
|
||||||
|
repo = "btop";
|
||||||
|
rev = "89ff712eb62747491a76a7902c475007244ff202";
|
||||||
|
hash = "sha256-J3UezOQMDdxpflGax0rGBF/XMiKqdqZXuX4KMVGTxFk=";
|
||||||
|
} + "/themes/catppuccin_mocha.theme";
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.btop.enable {
|
||||||
|
programs.btop = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
vim_keys = true;
|
||||||
|
color_theme = "catppuccin_mocha";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.eza.enable {
|
||||||
|
programs.eza = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.ranger.enable {
|
||||||
|
home.packages = [ pkgs.ranger ];
|
||||||
|
xdg.configFile."ranger/rc.conf".text = ''
|
||||||
|
set preview_images true
|
||||||
|
set preview_images_method kitty
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
28
modules/home/default.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{ lib, osConfig, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
# inputs.nur.hmModules.nur
|
||||||
|
./graphical
|
||||||
|
./themes
|
||||||
|
|
||||||
|
./cli.nix
|
||||||
|
./email.nix
|
||||||
|
./fetch.nix
|
||||||
|
./git.nix
|
||||||
|
./mpd.nix
|
||||||
|
./nix.nix
|
||||||
|
./packages.nix
|
||||||
|
./shell.nix
|
||||||
|
./spotify.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
xdg.enable = true;
|
||||||
|
|
||||||
|
dconf.settings = lib.mkIf osConfig.my.virt-manager.enable {
|
||||||
|
"org/virt-manager/virt-manager/connections" = {
|
||||||
|
autoconnect = [ "qemu:///system" ];
|
||||||
|
uris = [ "qemu:///system" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
114
modules/home/email.nix
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
{ pkgs, config, lib, osConfig, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.email;
|
||||||
|
in {
|
||||||
|
options.my.email = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
git.enable = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
emacs.enable = lib.mkEnableOption null // {
|
||||||
|
default = config.my.git.enable;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable (let
|
||||||
|
emailJson = osConfig.age.secrets.email.path;
|
||||||
|
anyConfigCmd = delim: t: k:
|
||||||
|
"${pkgs.jaq}/bin/jaq -r ${delim}.${t}.${k}${delim} ${emailJson}";
|
||||||
|
in lib.mkMerge [
|
||||||
|
(lib.mkIf cfg.emacs.enable {
|
||||||
|
accounts.email = {
|
||||||
|
maildirBasePath = "Mail";
|
||||||
|
accounts = builtins.mapAttrs (type: address: {
|
||||||
|
inherit address;
|
||||||
|
realName = address;
|
||||||
|
passwordCommand = anyConfigCmd "" type "password";
|
||||||
|
primary = type == "personal";
|
||||||
|
flavor = "gmail.com";
|
||||||
|
smtp.tls.useStartTls = true;
|
||||||
|
mbsync = {
|
||||||
|
enable = true;
|
||||||
|
create = "both";
|
||||||
|
expunge = "both";
|
||||||
|
};
|
||||||
|
mu.enable = true;
|
||||||
|
imapnotify = let
|
||||||
|
mbsync = "${config.programs.mbsync.package}/bin/mbsync";
|
||||||
|
mu = "${pkgs.mu}/bin/mu";
|
||||||
|
in {
|
||||||
|
enable = true;
|
||||||
|
boxes = [ "Inbox" ];
|
||||||
|
onNotify = "${mbsync} ${type} && ${mu} index";
|
||||||
|
onNotifyPost = let
|
||||||
|
notify-send = "${pkgs.libnotify}/bin/notify-send";
|
||||||
|
muFindEscape = f: let
|
||||||
|
sed = "${pkgs.gnused}/bin/sed";
|
||||||
|
in "${mu} find \"l:$FILE\" -f ${f}"
|
||||||
|
+ " | ${sed} 's/</\\</g'"
|
||||||
|
+ " | ${sed} 's/>/\\>/g'";
|
||||||
|
in pkgs.writeScript "inbox-notify-latest-${type}" ''
|
||||||
|
FILE="$(${mu} find "m:/${type}/Inbox" -z -s d -n 1 -f l)"
|
||||||
|
exec ${notify-send} -i mail-unread-new \
|
||||||
|
"[${address}] $(${muFindEscape "s"})" \
|
||||||
|
"from: $(${muFindEscape "f"})"
|
||||||
|
'';
|
||||||
|
extraConfig.wait = 3;
|
||||||
|
};
|
||||||
|
}) {
|
||||||
|
personal = "erlic006@gmail.com";
|
||||||
|
other = "eriedaberrie@gmail.com";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
programs = {
|
||||||
|
mbsync.enable = true;
|
||||||
|
mu.enable = true;
|
||||||
|
};
|
||||||
|
services.imapnotify.enable = true;
|
||||||
|
home.sessionVariables.MAILDIR = config.accounts.email.maildirBasePath;
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.git.enable (let
|
||||||
|
gitSetEmail = pkgs.writeShellScriptBin "git-set-email" (let
|
||||||
|
git = "${config.programs.git.package}/bin/git";
|
||||||
|
gitConfRep = "${git} config --replace-all --local";
|
||||||
|
in ''
|
||||||
|
${git} rev-parse --is-inside-work-tree > /dev/null || exit 1
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
declare -a keys=("user.name"
|
||||||
|
"user.email"
|
||||||
|
"sendemail.from"
|
||||||
|
"sendemail.smtpUser"
|
||||||
|
"sendemail.smtpPass"
|
||||||
|
"sendemail.smtpEncryption"
|
||||||
|
"sendemail.smtpServer"
|
||||||
|
"sendemail.smtpServerPort"
|
||||||
|
"sendemail.smtpSslCertPath")
|
||||||
|
for key in "''${keys[@]}"; do
|
||||||
|
${git} config --unset-all --local "$key"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
[ "$(${pkgs.jaq}/bin/jaq "has(\"$1\")" ${emailJson})" = true ] || exit 1
|
||||||
|
NAME="$(${anyConfigCmd "\"" "$1" "name"})"
|
||||||
|
ADDRESS="$(${anyConfigCmd "\"" "$1" "address"})"
|
||||||
|
${gitConfRep} 'user.name' "$NAME"
|
||||||
|
${gitConfRep} 'user.email' "$ADDRESS"
|
||||||
|
${gitConfRep} 'sendemail.from' "$NAME <$ADDRESS>"
|
||||||
|
${gitConfRep} 'sendemail.smtpPass' "$(${anyConfigCmd "\"" "$1" "password"})"
|
||||||
|
declare -a keys=("smtpEncryption"
|
||||||
|
"smtpServer"
|
||||||
|
"smtpServerPort"
|
||||||
|
"smtpSslCertPath"
|
||||||
|
"smtpUser")
|
||||||
|
for key in "''${keys[@]}"; do
|
||||||
|
${gitConfRep} "sendemail.$key" \
|
||||||
|
"$(${git} config --get --global "sendemail.$1.$key")"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
'');
|
||||||
|
in {
|
||||||
|
home.packages = [ gitSetEmail];
|
||||||
|
}))
|
||||||
|
]);
|
||||||
|
}
|
83
modules/home/fetch.nix
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
{ pkgs, config, lib, inputs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.fetch;
|
||||||
|
in {
|
||||||
|
options.my.fetch = {
|
||||||
|
fastfetch.enable = lib.mkEnableOption null;
|
||||||
|
neofetch.enable = lib.mkEnableOption null;
|
||||||
|
others.enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkMerge [
|
||||||
|
(lib.mkIf cfg.fastfetch.enable {
|
||||||
|
home.packages = [
|
||||||
|
(inputs.my-nix-packages.packages.${pkgs.system}.fastfetch.overrideAttrs {
|
||||||
|
flashfetchModules = [
|
||||||
|
"title"
|
||||||
|
"separator"
|
||||||
|
"os"
|
||||||
|
"kernel"
|
||||||
|
"uptime"
|
||||||
|
"shell"
|
||||||
|
"display"
|
||||||
|
"wm"
|
||||||
|
"theme"
|
||||||
|
"icons"
|
||||||
|
"font"
|
||||||
|
"cursor"
|
||||||
|
"terminal"
|
||||||
|
"terminalFont"
|
||||||
|
"cpu"
|
||||||
|
"gpu"
|
||||||
|
"memory"
|
||||||
|
"disk"
|
||||||
|
"battery"
|
||||||
|
"locale"
|
||||||
|
];
|
||||||
|
})
|
||||||
|
];
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.neofetch.enable {
|
||||||
|
home.packages = [ pkgs.neofetch ];
|
||||||
|
xdg.configFile = {
|
||||||
|
"neofetch/config.conf".text = ''
|
||||||
|
print_info() {
|
||||||
|
info title
|
||||||
|
info underline
|
||||||
|
info "OS" distro
|
||||||
|
info "Host" model
|
||||||
|
info "Kernel" kernel
|
||||||
|
info "Uptime" uptime
|
||||||
|
info "Shell" shell
|
||||||
|
info "Resolution" resolution
|
||||||
|
info "DE" de
|
||||||
|
info "Theme" theme
|
||||||
|
info "Icons" icons
|
||||||
|
info "Terminal" term
|
||||||
|
info "Terminal Font" term_font
|
||||||
|
info "CPU" cpu
|
||||||
|
info "GPU" gpu
|
||||||
|
info "Memory" memory
|
||||||
|
info cols
|
||||||
|
}
|
||||||
|
memory_percent="on"
|
||||||
|
shell_path="on"
|
||||||
|
speed_shorthand="off"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.others.enable {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
nitch
|
||||||
|
(uwufetch.overrideAttrs (old: {
|
||||||
|
preBuild = old.preBuild or "" + ''
|
||||||
|
mkdir -p $out/include
|
||||||
|
'';
|
||||||
|
}))
|
||||||
|
];
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
43
modules/home/git.nix
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
{ pkgs, config, lib, osConfig, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.git;
|
||||||
|
in {
|
||||||
|
options.my.git = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
home = {
|
||||||
|
sessionVariables.FILTER_BRANCH_SQUELCH_WARNING = 1;
|
||||||
|
shellAliases = {
|
||||||
|
g = "git";
|
||||||
|
lg = "lazygit";
|
||||||
|
};
|
||||||
|
packages = with pkgs; [
|
||||||
|
git-absorb
|
||||||
|
];
|
||||||
|
};
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
inherit (osConfig.programs.git) package;
|
||||||
|
userName = "eriedaberrie";
|
||||||
|
userEmail = "eriedaberrie@gmail.com";
|
||||||
|
aliases = {
|
||||||
|
hardfetch = "!git fetch --progress $1 && git reset --hard $1 && :";
|
||||||
|
pushf = "push --force-with-lease";
|
||||||
|
syncdates = "filter-branch --env-filter 'export GIT_COMMITTER_DATE=\"$GIT_AUTHOR_DATE\"'";
|
||||||
|
};
|
||||||
|
extraConfig = {
|
||||||
|
commit.verbose = true;
|
||||||
|
init.defaultBranch = "main";
|
||||||
|
pull.rebase = true;
|
||||||
|
push.autoSetupRemote = true;
|
||||||
|
rebase.autoStash = true;
|
||||||
|
rerere.enabled = true;
|
||||||
|
github.user = "eriedaberrie";
|
||||||
|
gitlab.user = "eriedaberrie";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
88
modules/home/graphical/default.nix
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
{ pkgs, config, lib, osConfig, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./wayland
|
||||||
|
./dunst.nix
|
||||||
|
./emacs.nix
|
||||||
|
./firefox.nix
|
||||||
|
./keepassxc.nix
|
||||||
|
./kitty.nix
|
||||||
|
./mangohud.nix
|
||||||
|
./mpv.nix
|
||||||
|
./obs.nix
|
||||||
|
./qtk.nix
|
||||||
|
./qutebrowser.nix
|
||||||
|
./zathura.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.my.graphical = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
fonts.fontconfig.enable = true;
|
||||||
|
|
||||||
|
xdg = {
|
||||||
|
userDirs = {
|
||||||
|
enable = true;
|
||||||
|
createDirectories = true;
|
||||||
|
};
|
||||||
|
mimeApps = {
|
||||||
|
enable = true;
|
||||||
|
defaultApplications = let
|
||||||
|
editor = "emacsclient.desktop";
|
||||||
|
email = "emacsclient-mail.desktop";
|
||||||
|
pdf = "org.pwmt.zathura.desktop";
|
||||||
|
browser = "firefox.desktop";
|
||||||
|
image = "imv.desktop";
|
||||||
|
video = "mpv.desktop";
|
||||||
|
explorer = "thunar.desktop";
|
||||||
|
in {
|
||||||
|
"application/octet-stream" = editor;
|
||||||
|
"text/plain" = editor;
|
||||||
|
"x-scheme-handler/http" = browser;
|
||||||
|
"x-scheme-handler/https" = browser;
|
||||||
|
"x-scheme-handler/mailto" = email;
|
||||||
|
"application/pdf" = pdf;
|
||||||
|
"image/bmp" = image;
|
||||||
|
"image/jpeg" = image;
|
||||||
|
"image/gif" = image;
|
||||||
|
"image/png" = image;
|
||||||
|
"image/svg+xml" = image;
|
||||||
|
"image/webp" = image;
|
||||||
|
"inode/directory" = explorer;
|
||||||
|
"video/mp4" = video;
|
||||||
|
"video/mpeg" = video;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services = let
|
||||||
|
bluetooth = osConfig.my.desktop.bluetooth.enable;
|
||||||
|
networkManager = osConfig.my.networking.networkManager.enable;
|
||||||
|
in {
|
||||||
|
mpris-proxy.enable = bluetooth;
|
||||||
|
blueman-applet.enable = bluetooth;
|
||||||
|
network-manager-applet.enable = networkManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
home = let
|
||||||
|
cursorSize = 36;
|
||||||
|
in {
|
||||||
|
pointerCursor = {
|
||||||
|
package = pkgs.catppuccin-cursors.mochaDark;
|
||||||
|
name = "catppuccin-mocha-dark-cursors";
|
||||||
|
size = cursorSize;
|
||||||
|
gtk.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
sessionVariables = lib.mkIf config.my.graphical.wayland.hyprland.enable {
|
||||||
|
HYPRCURSOR_THEME = "catppuccin-mocha-dark";
|
||||||
|
HYPRCURSOR_SIZE = cursorSize;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
86
modules/home/graphical/dunst.nix
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
{ pkgs, config, lib, theme, inputs, self, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.dunst;
|
||||||
|
in {
|
||||||
|
options.my.graphical.dunst = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable (let
|
||||||
|
volumeTag = "my-volume";
|
||||||
|
brightnessTag = "my-brightness";
|
||||||
|
dunstify = "${config.services.dunst.package}/bin/dunstify";
|
||||||
|
dunstVolume = let
|
||||||
|
wpctl = "${pkgs.wireplumber}/bin/wpctl";
|
||||||
|
in pkgs.writeShellScriptBin "dunst-volume" ''
|
||||||
|
SINK="''${3:-@DEFAULT_AUDIO_SINK@}"
|
||||||
|
${wpctl} "$1" $SINK "$2"
|
||||||
|
VOLUME_DATA="$(${wpctl} get-volume $SINK)"
|
||||||
|
VOLUME="$(awk '{print 100*$2}' <<< "$VOLUME_DATA")"
|
||||||
|
if grep -q '\[MUTED\]' <<< "$VOLUME_DATA"; then
|
||||||
|
exec ${dunstify} -u low -t 1000 -i audio-volume-muted \
|
||||||
|
-h "string:x-dunst-stack-tag:${volumeTag}" \
|
||||||
|
-h "int:value:$VOLUME" \
|
||||||
|
"Volume: $VOLUME%" "(muted)"
|
||||||
|
else
|
||||||
|
if (( "$VOLUME" >= 75 )); then
|
||||||
|
ICON=high
|
||||||
|
elif (( "$VOLUME" <= 25 )); then
|
||||||
|
ICON=low
|
||||||
|
else
|
||||||
|
ICON=medium
|
||||||
|
fi
|
||||||
|
exec ${dunstify} -u low -t 1000 -i "audio-volume-$ICON" \
|
||||||
|
-h "string:x-dunst-stack-tag:${volumeTag}" \
|
||||||
|
-h "int:value:$VOLUME" \
|
||||||
|
"Volume: $VOLUME%"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
dunstBrightness = let
|
||||||
|
brightnessctl = "${pkgs.brightnessctl}/bin/brightnessctl";
|
||||||
|
in pkgs.writeShellScriptBin "dunst-brightness" ''
|
||||||
|
${brightnessctl} set "$1"
|
||||||
|
BRIGHTNESS="$(awk -F , '{print 100*$3/$5}' <<< "$(${brightnessctl} info -m)")"
|
||||||
|
exec ${dunstify} -u low -t 1000 \
|
||||||
|
-h "string:x-dunst-stack-tag:${brightnessTag}" \
|
||||||
|
-h "int:value:$BRIGHTNESS" \
|
||||||
|
"Brightness: $BRIGHTNESS%"
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
home.packages = [
|
||||||
|
dunstVolume
|
||||||
|
dunstBrightness
|
||||||
|
];
|
||||||
|
services.dunst = {
|
||||||
|
enable = true;
|
||||||
|
iconTheme = {
|
||||||
|
inherit (config.gtk.iconTheme) name package;
|
||||||
|
size = "24x24";
|
||||||
|
};
|
||||||
|
settings = with theme; {
|
||||||
|
global = {
|
||||||
|
background = "#${base}";
|
||||||
|
foreground = "#${text}";
|
||||||
|
highlight = "#${lavender}";
|
||||||
|
frame_color = "#${peach}";
|
||||||
|
separator_color = "frame";
|
||||||
|
corner_radius = 10;
|
||||||
|
offset = "10x50";
|
||||||
|
font = "Inter 11";
|
||||||
|
dmenu = "${pkgs.fuzzel}/bin/fuzzel -d";
|
||||||
|
browser = "${pkgs.xdg-utils}/bin/xdg-open";
|
||||||
|
};
|
||||||
|
volume_tag = {
|
||||||
|
stack_tag = "${volumeTag}";
|
||||||
|
history_ignore = true;
|
||||||
|
};
|
||||||
|
brightness_tag = {
|
||||||
|
stack_tag = "${brightnessTag}";
|
||||||
|
history_ignore = true;
|
||||||
|
};
|
||||||
|
urgency_critical.frame_color = "#${yellow}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
212
modules/home/graphical/emacs.nix
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
{ pkgs, lib, config, inputs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.emacs;
|
||||||
|
in {
|
||||||
|
options.my.graphical.emacs = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable (let
|
||||||
|
inherit (inputs.emacs-overlay.overlays.package null pkgs) emacsPackagesFor;
|
||||||
|
extraEpkgsMap = epkgs: extraEpkgList: map (extraEpkg: extraEpkg epkgs) extraEpkgList;
|
||||||
|
org-modern-indent = epkgs: epkgs.trivialBuild rec {
|
||||||
|
pname = "org-modern-indent";
|
||||||
|
version = "f2b859bc53107b2a1027b76dbf4aaebf14c03433";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "jdtsmith";
|
||||||
|
repo = pname;
|
||||||
|
rev = version;
|
||||||
|
hash = "sha256-vtbaa3MURnAI1ypLueuSfgAno0l51y3Owb7g+jkK6JU=";
|
||||||
|
};
|
||||||
|
propagatedUserEnvPkgs = with epkgs; [ compat ];
|
||||||
|
buildInputs = propagatedUserEnvPkgs;
|
||||||
|
};
|
||||||
|
eglot-booster = epkgs: epkgs.trivialBuild rec {
|
||||||
|
pname = "eglot-booster";
|
||||||
|
version = "e19dd7ea81bada84c66e8bdd121408d9c0761fe6";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "jdtsmith";
|
||||||
|
repo = pname;
|
||||||
|
rev = version;
|
||||||
|
hash = "sha256-vF34ZoUUj8RENyH9OeKGSPk34G6KXZhEZozQKEcRNhs=";
|
||||||
|
};
|
||||||
|
propagatedUserEnvPkgs = [];
|
||||||
|
};
|
||||||
|
extraPackages = epkgs: with epkgs; [
|
||||||
|
f
|
||||||
|
dash
|
||||||
|
dashboard
|
||||||
|
undo-fu
|
||||||
|
god-mode
|
||||||
|
multiple-cursors
|
||||||
|
expand-region
|
||||||
|
avy
|
||||||
|
lispy
|
||||||
|
ace-window
|
||||||
|
goggles
|
||||||
|
dtrt-indent
|
||||||
|
aggressive-indent
|
||||||
|
rainbow-delimiters
|
||||||
|
highlight-indent-guides
|
||||||
|
which-key
|
||||||
|
eglot-java
|
||||||
|
yasnippet
|
||||||
|
yasnippet-snippets
|
||||||
|
consult
|
||||||
|
consult-yasnippet
|
||||||
|
embark
|
||||||
|
embark-consult
|
||||||
|
orderless
|
||||||
|
marginalia
|
||||||
|
vertico
|
||||||
|
corfu
|
||||||
|
cape
|
||||||
|
all-the-icons
|
||||||
|
all-the-icons-completion
|
||||||
|
treemacs
|
||||||
|
treemacs-all-the-icons
|
||||||
|
doom-modeline
|
||||||
|
minions
|
||||||
|
dirvish
|
||||||
|
pdf-tools
|
||||||
|
engrave-faces
|
||||||
|
org-modern
|
||||||
|
djvu
|
||||||
|
nov
|
||||||
|
org-pdftools
|
||||||
|
org-alert
|
||||||
|
editorconfig
|
||||||
|
envrc
|
||||||
|
sly
|
||||||
|
sly-asdf
|
||||||
|
sly-named-readtables
|
||||||
|
racket-mode
|
||||||
|
haskell-mode
|
||||||
|
lua-mode
|
||||||
|
nix-mode
|
||||||
|
gdscript-mode
|
||||||
|
markdown-mode
|
||||||
|
csv-mode
|
||||||
|
meson-mode
|
||||||
|
jinx
|
||||||
|
minimap
|
||||||
|
magit
|
||||||
|
forge
|
||||||
|
eat
|
||||||
|
mpv
|
||||||
|
lingva
|
||||||
|
mastodon
|
||||||
|
circe
|
||||||
|
circe-notifications
|
||||||
|
elfeed
|
||||||
|
xkcd
|
||||||
|
page-break-lines
|
||||||
|
hl-todo
|
||||||
|
ligature
|
||||||
|
gruvbox-theme
|
||||||
|
catppuccin-theme
|
||||||
|
solaire-mode
|
||||||
|
with-editor
|
||||||
|
nyan-mode
|
||||||
|
mu4e
|
||||||
|
org-msg
|
||||||
|
emacs-everywhere
|
||||||
|
treesit-grammars.with-all-grammars
|
||||||
|
] ++ extraEpkgsMap epkgs [
|
||||||
|
eglot-booster
|
||||||
|
org-modern-indent
|
||||||
|
];
|
||||||
|
alternateEmacsclient = pkgs.writeShellScript "alternate-emacsclient" ''
|
||||||
|
${pkgs.systemd}/bin/systemctl --user start emacs.service && \
|
||||||
|
exec ${config.programs.emacs.finalPackage}/bin/emacsclient -c -a "" "$@"
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
programs.emacs = {
|
||||||
|
enable = true;
|
||||||
|
package = (emacsPackagesFor pkgs.emacs29-pgtk).emacsWithPackages extraPackages;
|
||||||
|
};
|
||||||
|
services.emacs = {
|
||||||
|
enable = true;
|
||||||
|
startWithUserSession = "graphical";
|
||||||
|
};
|
||||||
|
home = {
|
||||||
|
sessionVariables.ALTERNATE_EDITOR = alternateEmacsclient;
|
||||||
|
packages = with pkgs; [
|
||||||
|
emacs-lsp-booster
|
||||||
|
emacs-all-the-icons-fonts
|
||||||
|
gdb
|
||||||
|
clang-tools
|
||||||
|
nil
|
||||||
|
nodePackages.typescript-language-server
|
||||||
|
ghc
|
||||||
|
stylish-haskell
|
||||||
|
haskell-language-server
|
||||||
|
hunspellDicts.en-us
|
||||||
|
imagemagick
|
||||||
|
(texlive.combine {
|
||||||
|
inherit (texlive) scheme-basic
|
||||||
|
dvisvgm dvipng # Preview and export as html
|
||||||
|
wrapfig amsmath ulem hyperref capt-of
|
||||||
|
# Export code with engraved backend
|
||||||
|
fvextra etoolbox fancyvrb upquote lineno
|
||||||
|
tcolorbox pgf environ pdfcol
|
||||||
|
xcolor float
|
||||||
|
nopageno;
|
||||||
|
})
|
||||||
|
pandoc
|
||||||
|
];
|
||||||
|
file.".clang-format".text = ''
|
||||||
|
---
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
IndentWidth: 4
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Always
|
||||||
|
...
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
xdg.desktopEntries = let
|
||||||
|
extendDefault = lib.recursiveUpdate {
|
||||||
|
icon = "emacs";
|
||||||
|
terminal = false;
|
||||||
|
type = "Application";
|
||||||
|
settings.Keywords = "emacsclient;";
|
||||||
|
actions = {
|
||||||
|
new-window.name = "New Window";
|
||||||
|
new-instance.name = "New Instance";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
emacsclient = extendDefault rec {
|
||||||
|
name = "Emacs (Client)";
|
||||||
|
exec = "${config.programs.emacs.finalPackage}/bin/emacsclient -a ${alternateEmacsclient} -c %F";
|
||||||
|
genericName = "Text Editor";
|
||||||
|
comment = "Edit text";
|
||||||
|
mimeType = ["text/english" "text/plain" ];
|
||||||
|
categories = [ "Development" "TextEditor" ];
|
||||||
|
startupNotify = true;
|
||||||
|
settings.StartupWMClass = "Emacs";
|
||||||
|
actions = {
|
||||||
|
new-window = {inherit exec;};
|
||||||
|
new-instance.exec = "${config.programs.emacs.finalPackage}/bin/emacs %F";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
emacsclient-mail = extendDefault rec {
|
||||||
|
name = "Emacs (Mail, Client)";
|
||||||
|
exec = (pkgs.writeShellScript "emacsclient-mail" ''
|
||||||
|
u=''${1//\\/\\\\}
|
||||||
|
u=''${u//\"/\\\"}
|
||||||
|
exec ${config.programs.emacs.finalPackage}/bin/emacsclient -a ${alternateEmacsclient} -c \
|
||||||
|
--eval "(message-mailto \"$u\")"
|
||||||
|
'') + " %u";
|
||||||
|
comment = "GNU Emacs is an extensible, customizable text editor - and more";
|
||||||
|
mimeType = [ "x-scheme-handler/mailto" ];
|
||||||
|
noDisplay = true;
|
||||||
|
actions = {
|
||||||
|
new-window = {inherit exec;};
|
||||||
|
new-instance.exec = "${config.programs.emacs.finalPackage}/bin/emacs -f message-mailto %u";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
141
modules/home/graphical/firefox.nix
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
{ pkgs, config, lib, self, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.firefox;
|
||||||
|
in {
|
||||||
|
options.my.graphical.firefox = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs.firefox = {
|
||||||
|
enable = true;
|
||||||
|
policies = {
|
||||||
|
DisableFirefoxStudies = true;
|
||||||
|
DisablePocket = true;
|
||||||
|
DisableFirefoxAccounts = true;
|
||||||
|
DisableProfileImport = true;
|
||||||
|
DisplayBookmarksToolbar = "never";
|
||||||
|
NoDefaultBookmarks = true;
|
||||||
|
OfferToSaveLogins = false;
|
||||||
|
DontCheckDefaultBrowser = true;
|
||||||
|
UserMessaging = {
|
||||||
|
ExtensionRecommendations = false;
|
||||||
|
SkipOnboarding = true;
|
||||||
|
};
|
||||||
|
ExtensionSettings = let
|
||||||
|
mozillaExtensions = {
|
||||||
|
buster-captcha-solver = "{e58d3966-3d76-4cd9-8552-1582fbc800c1}";
|
||||||
|
clearurls = "{74145f27-f039-47ce-a470-a662b129930a}";
|
||||||
|
search_by_image = "{2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c}";
|
||||||
|
styl-us = "{7a7a4a92-a2a0-41d1-9fd7-1e92480d612d}";
|
||||||
|
traduzir-paginas-web = "{036a55b4-5e72-4d05-a06c-cba2dfcc134a}";
|
||||||
|
violentmonkey = "{aecec67f-0d10-4fa7-b7c7-609a2db280cf}";
|
||||||
|
indie-wiki-buddy = "{cb31ec5d-c49a-4e5a-b240-16c767444f62}";
|
||||||
|
sponsorblock = "sponsorBlocker@ajay.app";
|
||||||
|
tabcenter-reborn = "tabcenter-reborn@ariasuni";
|
||||||
|
ublock-origin = "uBlock0@raymondhill.net";
|
||||||
|
firefox-color = "FirefoxColor@mozilla.com";
|
||||||
|
foxyproxy-standard = "foxyproxy@eric.h.jung";
|
||||||
|
} // lib.optionalAttrs config.my.keepassxc.enable {
|
||||||
|
keepassxc-browser = "keepassxc-browser@keepassxc.org";
|
||||||
|
};
|
||||||
|
in builtins.mapAttrs (_: url: {
|
||||||
|
install_url = url;
|
||||||
|
installation_mode = "force_installed";
|
||||||
|
}) (lib.mapAttrs' (name: id:
|
||||||
|
lib.nameValuePair id "https://addons.mozilla.org/firefox/downloads/latest/${name}/latest.xpi"
|
||||||
|
) mozillaExtensions);
|
||||||
|
};
|
||||||
|
profiles.errie = {
|
||||||
|
settings = {
|
||||||
|
"browser.aboutConfig.showWarning" = false;
|
||||||
|
"browser.cache.disk.enable" = false;
|
||||||
|
"browser.cache.memory.capacity" = 2000000;
|
||||||
|
"browser.ctrlTab.sortByRecentlyUsed" = false;
|
||||||
|
"browser.newtabpage.activity-stream.feeds.section.topstories" = false;
|
||||||
|
"browser.newtabpage.activity-stream.feeds.topsites" = false;
|
||||||
|
"browser.newtabpage.pinned" = [];
|
||||||
|
"browser.startup.page" = 3;
|
||||||
|
"cookiebanners.service.mode" = 1;
|
||||||
|
"cookiebanners.service.mode.privateBrowsing" = 1;
|
||||||
|
"devtools.selfxss.count" = 100;
|
||||||
|
"media.ffmpeg.vaapi.enabled" = true;
|
||||||
|
"privacy.webrtc.legacyGlobalIndicator" = false;
|
||||||
|
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
|
||||||
|
"ui.key.menuAccessKeyFocuses" = false;
|
||||||
|
"widget.wayland.fractional-scale.enabled" = true;
|
||||||
|
};
|
||||||
|
search = {
|
||||||
|
default = "DuckDuckGo";
|
||||||
|
force = true;
|
||||||
|
order = [ "DuckDuckGo" "SearXNG" "Google" ];
|
||||||
|
engines = {
|
||||||
|
"SearXNG" = {
|
||||||
|
definedAliases = [ "@searxng" ];
|
||||||
|
icon = "${self}/assets/searxng.svg";
|
||||||
|
urls = [{
|
||||||
|
template = "https://etsi.me/search";
|
||||||
|
params = [{
|
||||||
|
name = "q";
|
||||||
|
value = "{searchTerms}";
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
"Nix Packages" = {
|
||||||
|
definedAliases = [ "@pkgs" "@nixpkgs" ];
|
||||||
|
icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
|
||||||
|
urls = [{
|
||||||
|
template = "https://search.nixos.org/packages";
|
||||||
|
params = [
|
||||||
|
{
|
||||||
|
name = "channel";
|
||||||
|
value = "unstable";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "type";
|
||||||
|
value = "packages";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "query";
|
||||||
|
value = "{searchTerms}";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
"Hoogle" = {
|
||||||
|
definedAliases = [ "@hoogle" ];
|
||||||
|
urls = [{
|
||||||
|
template = "https://hoogle.haskell.org/";
|
||||||
|
params = [{
|
||||||
|
name = "hoogle";
|
||||||
|
value = "{searchTerms}";
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
} // lib.genAttrs [ "Bing" "Amazon.com" "eBay" ] (_: {metaData.hidden = true;});
|
||||||
|
};
|
||||||
|
userChrome = let
|
||||||
|
verticalTabs = pkgs.fetchzip {
|
||||||
|
url = "https://codeberg.org/ranmaru22/firefox-vertical-tabs/archive/v6.5.tar.gz";
|
||||||
|
hash = "sha256-DHI8QFr4z00tlS8SlWrrNymP6pRQ55YHq6ZegDx5iYk=";
|
||||||
|
};
|
||||||
|
in ''
|
||||||
|
@import url("file://${verticalTabs}/userChrome.css");
|
||||||
|
|
||||||
|
/* Hide the close button */
|
||||||
|
.titlebar-buttonbox-container,
|
||||||
|
.titlebar-spacer[type="post-tabs"]
|
||||||
|
{
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove padding on the right */
|
||||||
|
#nav-bar {
|
||||||
|
--uc-navbar-padding: 0;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
29
modules/home/graphical/keepassxc.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.keepassxc;
|
||||||
|
in {
|
||||||
|
options.my.keepassxc = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
home.packages = [ pkgs.keepassxc ];
|
||||||
|
|
||||||
|
systemd.user.services.keepassxc = {
|
||||||
|
Unit = {
|
||||||
|
Description = "KeePassXC password manager";
|
||||||
|
After = [ "graphical-session-pre.target" "tray.target" "eww-bar.service" ];
|
||||||
|
PartOf = [ "graphical-session.target" ];
|
||||||
|
Requires = [ "tray.target" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart = "${pkgs.keepassxc}/bin/keepassxc";
|
||||||
|
Environment = "QT_QPA_PLATFORM=wayland";
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
28
modules/home/graphical/kitty.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.kitty;
|
||||||
|
in {
|
||||||
|
options.my.graphical.kitty = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs.kitty = {
|
||||||
|
enable = true;
|
||||||
|
theme = "Catppuccin-Mocha";
|
||||||
|
font = {
|
||||||
|
name = "JetBrainsMono Nerd Font";
|
||||||
|
size = 11;
|
||||||
|
};
|
||||||
|
keybindings = {
|
||||||
|
"ctrl+backspace" = "send_text all \\x1b\\x7f";
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
window_margin_width = 5;
|
||||||
|
focus_follows_mouse = "yes";
|
||||||
|
shell_integration = "no-cursor";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
23
modules/home/graphical/mangohud.nix
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.mangohud;
|
||||||
|
in {
|
||||||
|
options.my.graphical.mangohud = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs.mangohud = {
|
||||||
|
enable = true;
|
||||||
|
enableSessionWide = true;
|
||||||
|
settings = {
|
||||||
|
no_display = true;
|
||||||
|
vsync = 0;
|
||||||
|
full = true;
|
||||||
|
output_folder = "${config.xdg.cacheHome}/mangohud";
|
||||||
|
toggle_hud = "Shift_R+BackSpace";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
38
modules/home/graphical/mpv.nix
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.mpv;
|
||||||
|
in {
|
||||||
|
options.my.graphical.mpv = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs.mpv = {
|
||||||
|
enable = true;
|
||||||
|
scripts = with pkgs.mpvScripts; [
|
||||||
|
mpris
|
||||||
|
sponsorblock
|
||||||
|
thumbfast
|
||||||
|
uosc
|
||||||
|
];
|
||||||
|
bindings = {
|
||||||
|
tab = "script-binding uosc/flash-ui";
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
ao = "pipewire,";
|
||||||
|
osd-bar = false;
|
||||||
|
border = false;
|
||||||
|
};
|
||||||
|
scriptOpts = {
|
||||||
|
uosc = {
|
||||||
|
top_bar_controls = false;
|
||||||
|
top_bar_title = "\${media-title}";
|
||||||
|
top_bar_alt_title = "\${filename}";
|
||||||
|
top_bar_alt_title_place = "below";
|
||||||
|
};
|
||||||
|
thumbfast.hwdec = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
20
modules/home/graphical/obs.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.obs;
|
||||||
|
in {
|
||||||
|
options.my.graphical.obs = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs.obs-studio = {
|
||||||
|
enable = true;
|
||||||
|
plugins = with pkgs.obs-studio-plugins; [
|
||||||
|
wlrobs
|
||||||
|
obs-vkcapture
|
||||||
|
obs-vaapi
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
67
modules/home/graphical/qtk.nix
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical;
|
||||||
|
in {
|
||||||
|
options.my.graphical = {
|
||||||
|
qt.enable = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
gtk = {
|
||||||
|
enable = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
emacsKeys.enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||||
|
(lib.mkIf cfg.qt.enable {
|
||||||
|
qt = {
|
||||||
|
enable = true;
|
||||||
|
platformTheme.name = "gtk3";
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.gtk.enable {
|
||||||
|
dconf.settings = {
|
||||||
|
"org/gnome/desktop/interface" = {
|
||||||
|
color-scheme = "prefer-dark";
|
||||||
|
gtk-key-theme = lib.mkIf (cfg.gtk.emacsKeys.enable) "Emacs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
gtk = {
|
||||||
|
enable = true;
|
||||||
|
font = {
|
||||||
|
package = pkgs.inter;
|
||||||
|
name = "Inter";
|
||||||
|
size = 11;
|
||||||
|
};
|
||||||
|
iconTheme = {
|
||||||
|
package = pkgs.catppuccin-papirus-folders.override {
|
||||||
|
flavor = "mocha";
|
||||||
|
accent = "lavender";
|
||||||
|
};
|
||||||
|
name = "Papirus-Dark";
|
||||||
|
};
|
||||||
|
theme = {
|
||||||
|
package = pkgs.catppuccin-gtk.override {
|
||||||
|
accents = [ "lavender" ];
|
||||||
|
size = "compact";
|
||||||
|
tweaks = [ "rimless" ];
|
||||||
|
variant = "mocha";
|
||||||
|
};
|
||||||
|
name = "catppuccin-mocha-lavender-compact+rimless";
|
||||||
|
};
|
||||||
|
} // lib.optionalAttrs cfg.gtk.emacsKeys.enable {
|
||||||
|
gtk2.extraConfig = ''
|
||||||
|
gtk-key-theme-name = "Emacs"
|
||||||
|
'';
|
||||||
|
gtk3.extraConfig = {
|
||||||
|
gtk-key-theme-name = "Emacs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}
|
90
modules/home/graphical/qutebrowser.nix
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.qutebrowser;
|
||||||
|
in {
|
||||||
|
options.my.graphical.qutebrowser = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable (let
|
||||||
|
mapLeader = "<Space>";
|
||||||
|
in {
|
||||||
|
programs.qutebrowser = {
|
||||||
|
enable = true;
|
||||||
|
package = (pkgs.qutebrowser.override {enableWideVine = true;}).overrideAttrs (old: {
|
||||||
|
nativeBuildInputs = old.nativeBuildInputs or [] ++ [ pkgs.makeWrapper ];
|
||||||
|
postInstall = old.postInstall or "" + ''
|
||||||
|
wrapProgram $out/bin/qutebrowser \
|
||||||
|
--unset QT_QPA_PLATFORMTHEME
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
aliases = {
|
||||||
|
bN = "tab-prev";
|
||||||
|
bd = "tab-close";
|
||||||
|
bn = "tab-next";
|
||||||
|
bp = "tab-prev";
|
||||||
|
h = "help";
|
||||||
|
q = "close";
|
||||||
|
qa = "quit";
|
||||||
|
w = "session-save";
|
||||||
|
wq = "quit --save";
|
||||||
|
wqa = "quit --save";
|
||||||
|
so = "config-source";
|
||||||
|
"so%" = "config-source";
|
||||||
|
};
|
||||||
|
keyBindings = {
|
||||||
|
normal = {
|
||||||
|
"clc" = "set-cmd-text :open -t https://www.dl.cambridgescp.com/stage/clc/";
|
||||||
|
"<Ctrl+Shift+Tab>" = "tab-focus last";
|
||||||
|
"<Ctrl+Shift+Space>" = "edit-text";
|
||||||
|
"<Ctrl+d>" = "fake-key <PgDown>";
|
||||||
|
"<Ctrl+u>" = "fake-key <PgUp>";
|
||||||
|
"${mapLeader}<Space>" = ''
|
||||||
|
config-cycle statusbar.show in-mode always ;; \
|
||||||
|
config-cycle tabs.show switching always \
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
insert = {
|
||||||
|
"<Ctrl+Shift+Space>" = "edit-text";
|
||||||
|
"<Ctrl+h>" = "fake-key <Backspace>";
|
||||||
|
"<Ctrl+w>" = "fake-key <Ctrl+Backspace>";
|
||||||
|
};
|
||||||
|
command."<Ctrl+w>" = "rl-backward-kill-word";
|
||||||
|
prompt."<Ctrl+w>" = "rl-backward-kill-word";
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
changelog_after_upgrade = "patch";
|
||||||
|
auto_save = {
|
||||||
|
session = true;
|
||||||
|
interval = 15000;
|
||||||
|
};
|
||||||
|
editor = {
|
||||||
|
command = [
|
||||||
|
"/bin/sh" "-c"
|
||||||
|
''
|
||||||
|
emacsclient -e '(require '\"'\"'emacs-everywhere nil :noerror)' && \
|
||||||
|
emacsclient -c '+{line}:{column}' '{file}' \
|
||||||
|
''
|
||||||
|
];
|
||||||
|
remove_file = true;
|
||||||
|
};
|
||||||
|
content.pdfjs = true;
|
||||||
|
scrolling.smooth = true;
|
||||||
|
colors.webpage.preferred_color_scheme = "dark";
|
||||||
|
};
|
||||||
|
extraConfig = ''
|
||||||
|
import catppuccin
|
||||||
|
catppuccin.setup(c, 'mocha')
|
||||||
|
config.unbind('<Ctrl+w>')
|
||||||
|
config.unbind('<Ctrl+Shift+w>')
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
xdg.configFile."qutebrowser/catppuccin".source = pkgs.fetchFromGitHub {
|
||||||
|
owner = "catppuccin";
|
||||||
|
repo = "qutebrowser";
|
||||||
|
rev = "6737f1c36a9d05be05b7961945e7028c0f70831f";
|
||||||
|
sha256 = "0nv214p0k292y2gr5afcjvxnjs1ai78vnxyb7qzj1r4vk7r3nh0k";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
38
modules/home/graphical/wayland/default.nix
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{ pkgs, config, lib, inputs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./eww
|
||||||
|
./hyprland.nix
|
||||||
|
./hyprlock.nix
|
||||||
|
./swaylock.nix
|
||||||
|
./swayidle.nix
|
||||||
|
./gammastep.nix
|
||||||
|
./kanshi.nix
|
||||||
|
./gestures.nix
|
||||||
|
./ydotool.nix
|
||||||
|
./foot.nix
|
||||||
|
./fuzzel.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.my.graphical.wayland = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
home = {
|
||||||
|
packages = (with pkgs; [
|
||||||
|
wl-clipboard
|
||||||
|
grim
|
||||||
|
slurp
|
||||||
|
wev
|
||||||
|
gamescope
|
||||||
|
inputs.my-nix-packages.packages.${system}.geticons
|
||||||
|
]);
|
||||||
|
|
||||||
|
sessionVariables.NIXOS_OZONE_WL = "1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
83
modules/home/graphical/wayland/eww/default.nix
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
{ pkgs, config, lib, self, theme, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland.eww;
|
||||||
|
in {
|
||||||
|
options.my.graphical.wayland.eww = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = let
|
||||||
|
inherit (pkgs) eww;
|
||||||
|
in lib.mkIf cfg.enable {
|
||||||
|
home.packages = [ eww ];
|
||||||
|
|
||||||
|
xdg.configFile = builtins.mapAttrs (name: src: {
|
||||||
|
source = pkgs.substituteAll ({
|
||||||
|
inherit src;
|
||||||
|
acpi = "${pkgs.acpi}/bin/acpi";
|
||||||
|
hyprctl = "${config.wayland.windowManager.hyprland.package}/bin/hyprctl";
|
||||||
|
ruby = "${pkgs.ruby}/bin/ruby";
|
||||||
|
soyjak = "${self}/assets/pointingSoyjaks.png";
|
||||||
|
} // theme);
|
||||||
|
target = "eww/${name}";
|
||||||
|
executable = builtins.match "\\./scripts/.*" name != null;
|
||||||
|
}) (self.lib.filterNixReadDir ./.) // {
|
||||||
|
"eww/_mocha.scss".text = builtins.concatStringsSep "\n"
|
||||||
|
(lib.mapAttrsToList (name: value: "\$${name}: #${value};") theme);
|
||||||
|
};
|
||||||
|
|
||||||
|
wayland.windowManager.hyprland.settings = let
|
||||||
|
inherit (config.my.graphical.wayland.hyprland) mainMod;
|
||||||
|
toggleSoyjaks = pkgs.writeShellScript "toggle-soyjaks" ''
|
||||||
|
if ${eww}/bin/eww active-windows | ${pkgs.gnugrep}/bin/grep -q 'soyjak-layer'; then
|
||||||
|
${eww}/bin/eww close soyjak-layer
|
||||||
|
else
|
||||||
|
${eww}/bin/eww open soyjak-layer
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
bind = [
|
||||||
|
"${mainMod} CTRL, S, exec, ${toggleSoyjaks}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user = {
|
||||||
|
services = {
|
||||||
|
eww = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Eww background daemon";
|
||||||
|
partOf = [ "tray.target" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
Environment = "PATH=${lib.makeBinPath (with pkgs; [ coreutils bash ])}";
|
||||||
|
ExecStart = "${eww}/bin/eww daemon --no-daemonize";
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "tray.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
eww-bar = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Eww bar";
|
||||||
|
After = "eww.service";
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = pkgs.writeShellScript "eww-bar-open" ''
|
||||||
|
# Lack of quotes intentional
|
||||||
|
exec ${eww}/bin/eww open-many \
|
||||||
|
$(${config.wayland.windowManager.hyprland.package}/bin/hyprctl monitors -j | \
|
||||||
|
${pkgs.jaq}/bin/jaq -r '.[] | .id' | \
|
||||||
|
${pkgs.gnused}/bin/sed 's/^/bar/')
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "eww.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
98
modules/home/graphical/wayland/eww/eww.scss
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
@import "mocha";
|
||||||
|
|
||||||
|
button, menubar, menubar > menuitem {
|
||||||
|
all: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-wrap > * {
|
||||||
|
border-radius: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-main {
|
||||||
|
font-family: "Jost";
|
||||||
|
font-size: 16px;
|
||||||
|
background-color: $base;
|
||||||
|
color: $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspaces > button {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 6px 0 0 0;
|
||||||
|
&:hover {
|
||||||
|
background-color: $surface0;
|
||||||
|
}
|
||||||
|
&.nonexistent {
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
&.existing {
|
||||||
|
border-color: $surface1;
|
||||||
|
&:hover {
|
||||||
|
border-color: $overlay1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
border-color: $rosewater;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-end > * {
|
||||||
|
margin-right: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tray > menuitem {
|
||||||
|
margin-right: 15px;
|
||||||
|
& menu {
|
||||||
|
background-color: $mantle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin battery-color($property) {
|
||||||
|
#{$property}: $text;
|
||||||
|
.battery-low & {
|
||||||
|
#{$property}: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.battery-tip {
|
||||||
|
@include battery-color(background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.battery-box {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 2px;
|
||||||
|
@include battery-color(border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.battery-val {
|
||||||
|
margin: 2px;
|
||||||
|
@include battery-color(background-color);
|
||||||
|
.battery-charging & {
|
||||||
|
background-color: $green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.power {
|
||||||
|
font-family: "Jetbrains Mono Nerd Font";
|
||||||
|
font-size: 30px;
|
||||||
|
color: $red;
|
||||||
|
transition: color, background-color 0.15s;
|
||||||
|
&:hover {
|
||||||
|
background-color: $red;
|
||||||
|
color: $base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip {
|
||||||
|
color: $text;
|
||||||
|
background-color: rgba($crust, 1);
|
||||||
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.soyjak-layer {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
149
modules/home/graphical/wayland/eww/eww.yuck
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
;;; Eww config
|
||||||
|
|
||||||
|
(defpoll time
|
||||||
|
:interval "5s"
|
||||||
|
"date '+%l:%M %p'")
|
||||||
|
|
||||||
|
(defpoll date
|
||||||
|
:interval "1m"
|
||||||
|
"date '+%D'")
|
||||||
|
|
||||||
|
(defpoll acpi
|
||||||
|
:interval "20s"
|
||||||
|
:initial ""
|
||||||
|
"@acpi@ -b")
|
||||||
|
|
||||||
|
(deflisten hyprlisten
|
||||||
|
:initial "{
|
||||||
|
\"workspaces\": ${jq(10, `[{active: false, existing: false, id: range(.) + 1}]`)},
|
||||||
|
\"title\": \"\"
|
||||||
|
}"
|
||||||
|
"scripts/hyprlisten.rb")
|
||||||
|
|
||||||
|
(defwindow bar0
|
||||||
|
:monitor 0
|
||||||
|
:geometry (geometry :height "42px"
|
||||||
|
:width "1920px"
|
||||||
|
:anchor "top center")
|
||||||
|
:stacking "fg"
|
||||||
|
(bar))
|
||||||
|
|
||||||
|
(defwindow bar1
|
||||||
|
:monitor 1
|
||||||
|
:geometry (geometry :height "42px"
|
||||||
|
:width "100%"
|
||||||
|
:anchor "top center")
|
||||||
|
:stacking "fg"
|
||||||
|
(bar))
|
||||||
|
|
||||||
|
(defwindow bar2
|
||||||
|
:monitor 2
|
||||||
|
:geometry (geometry :height "42px"
|
||||||
|
:width "100%"
|
||||||
|
:anchor "top center")
|
||||||
|
:stacking "fg"
|
||||||
|
(bar))
|
||||||
|
|
||||||
|
(defwidget bar-wrap []
|
||||||
|
(box :class "bar-wrap"
|
||||||
|
:orientation "h"
|
||||||
|
(bar)))
|
||||||
|
|
||||||
|
(defwidget bar []
|
||||||
|
(box :class "bar-main"
|
||||||
|
:orientation "h"
|
||||||
|
(bar-start)
|
||||||
|
(bar-center)
|
||||||
|
(bar-end)))
|
||||||
|
|
||||||
|
(defwidget bar-start []
|
||||||
|
(box :class "bar-start"
|
||||||
|
:orientation "h"
|
||||||
|
:halign "start"
|
||||||
|
:space-evenly false
|
||||||
|
(workspaces)))
|
||||||
|
|
||||||
|
(defwidget bar-center []
|
||||||
|
(box :class "bar-center"
|
||||||
|
:orientation "h"
|
||||||
|
:halign "center"
|
||||||
|
(title)))
|
||||||
|
|
||||||
|
(defwidget bar-end []
|
||||||
|
(box :class "bar-end"
|
||||||
|
:orientation "h"
|
||||||
|
:halign "end"
|
||||||
|
:space-evenly false
|
||||||
|
(tray)
|
||||||
|
(battery)
|
||||||
|
(time)))
|
||||||
|
|
||||||
|
(defwidget workspaces []
|
||||||
|
(eventbox
|
||||||
|
:onscroll "@hyprctl@ dispatch focusworkspaceoncurrentmonitor e$([ \"{}\" = \"up\" ] && echo '-' || echo '+')1"
|
||||||
|
(box :class "workspaces"
|
||||||
|
:orientation "h"
|
||||||
|
:halign "start"
|
||||||
|
(for workspace in {hyprlisten.workspaces}
|
||||||
|
(button :class "${workspace.active ? 'active' :
|
||||||
|
(workspace.existing ? 'existing' : 'nonexistent')}"
|
||||||
|
:width 42
|
||||||
|
:height 42
|
||||||
|
:tooltip "Switch to Workspace ${workspace.id}"
|
||||||
|
:onclick "@hyprctl@ dispatch focusworkspaceoncurrentmonitor ${workspace.id}"
|
||||||
|
{workspace.id})))))
|
||||||
|
|
||||||
|
(defwidget title []
|
||||||
|
(label :class "title"
|
||||||
|
:limit-width 70
|
||||||
|
:text {hyprlisten.title}))
|
||||||
|
|
||||||
|
(defwidget tray []
|
||||||
|
(systray :class "tray"
|
||||||
|
:icon-size 24
|
||||||
|
:prepend-new true
|
||||||
|
:spacing 6))
|
||||||
|
|
||||||
|
(defwidget battery []
|
||||||
|
(box :class "battery ${EWW_BATTERY.BAT1.status == 'Charging' ? 'battery-charging' :
|
||||||
|
(EWW_BATTERY.BAT1.capacity <= 20 ? 'battery-low' : '')}"
|
||||||
|
:orientation "h"
|
||||||
|
:tooltip acpi
|
||||||
|
(box :class "battery-box"
|
||||||
|
:valign "center"
|
||||||
|
:width 28
|
||||||
|
:height 14
|
||||||
|
(box :class "battery-val"
|
||||||
|
:halign "start"
|
||||||
|
:width {4 + round (EWW_BATTERY.BAT1.capacity / 5 , 0)}))
|
||||||
|
(box :class "battery-tip"
|
||||||
|
:halign "start"
|
||||||
|
:valign "center"
|
||||||
|
:width 3
|
||||||
|
:height 6)))
|
||||||
|
|
||||||
|
(defwidget time []
|
||||||
|
(box :class "time"
|
||||||
|
:tooltip date
|
||||||
|
time))
|
||||||
|
|
||||||
|
(defwidget power []
|
||||||
|
(eventbox :class "power"
|
||||||
|
:width 42
|
||||||
|
:cursor "pointer"
|
||||||
|
:onclick "wlogout -p layer-shell &"
|
||||||
|
:tooltip "Logout options"
|
||||||
|
"襤"))
|
||||||
|
|
||||||
|
(defwindow soyjak-layer
|
||||||
|
:monitor 0
|
||||||
|
:geometry (geometry :width "100%"
|
||||||
|
:height "100%"
|
||||||
|
:anchor "bottom left")
|
||||||
|
:stacking "overlay"
|
||||||
|
(soyjak))
|
||||||
|
|
||||||
|
(defwidget soyjak []
|
||||||
|
(image :path "@soyjak@"
|
||||||
|
:image-width 1920
|
||||||
|
:image-height 1080))
|
75
modules/home/graphical/wayland/eww/scripts/hyprlisten.rb
Executable file
|
@ -0,0 +1,75 @@
|
||||||
|
#!@ruby@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'socket'
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
$stdout.sync = true
|
||||||
|
|
||||||
|
SOCK_DIR = "#{ENV['XDG_RUNTIME_DIR']}/hypr/#{ENV['HYPRLAND_INSTANCE_SIGNATURE']}"
|
||||||
|
SOCK1 = "#{SOCK_DIR}/.socket.sock"
|
||||||
|
SOCK2 = "#{SOCK_DIR}/.socket2.sock"
|
||||||
|
|
||||||
|
def hyprctl(cmd)
|
||||||
|
Socket.unix(SOCK1) do |s|
|
||||||
|
s.print cmd
|
||||||
|
s.read.force_encoding('UTF-8')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Workspaces
|
||||||
|
attr_reader :data
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@active = JSON.parse(hyprctl('j/monitors')).detect { |m| m['focused'] }['activeWorkspace']['id']
|
||||||
|
existing = JSON.parse(hyprctl('j/workspaces')).to_h { |w| [w['id'], true] }
|
||||||
|
@data = (1..9).map { |id| {id: id, active: id == @active, existing: !!existing[id]} }
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_active(workspace)
|
||||||
|
workspace = workspace.to_i
|
||||||
|
update_val(@active, active: false)
|
||||||
|
update_val(workspace, active: true)
|
||||||
|
@active = workspace
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_val(workspace, **kwargs)
|
||||||
|
@data[workspace - 1].merge!(kwargs) if workspace.between?(1, 9)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class State
|
||||||
|
def initialize(**kwargs)
|
||||||
|
@data = kwargs
|
||||||
|
end
|
||||||
|
|
||||||
|
def update(**kwargs)
|
||||||
|
@data.merge!(kwargs)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
JSON.fast_generate(@data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Socket.unix(SOCK2) do |socket|
|
||||||
|
ws = Workspaces.new
|
||||||
|
state = State.new(
|
||||||
|
title: JSON.parse(hyprctl('j/activewindow'))['title'] || '',
|
||||||
|
workspaces: ws.data,
|
||||||
|
)
|
||||||
|
puts state
|
||||||
|
while (line = socket.gets)
|
||||||
|
event, data = line.split('>>', 2)
|
||||||
|
case event
|
||||||
|
when 'activewindow' then state.update(title: data.chomp.split(',', 2).last)
|
||||||
|
when 'closewindow' then state.update(title: '')
|
||||||
|
when 'workspace' then ws.update_active(data.chomp)
|
||||||
|
when 'focusedmon' then ws.update_active(data.chomp.split(',', 2).last)
|
||||||
|
when 'createworkspace' then ws.update_val(data.chomp.to_i, existing: true)
|
||||||
|
when 'destroyworkspace' then ws.update_val(data.chomp.to_i, existing: false)
|
||||||
|
else next
|
||||||
|
end
|
||||||
|
puts state
|
||||||
|
end
|
||||||
|
end
|
51
modules/home/graphical/wayland/foot.nix
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{ config, lib, theme, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland.foot;
|
||||||
|
in {
|
||||||
|
options.my.graphical.wayland.foot = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable (let
|
||||||
|
loweredTheme = builtins.mapAttrs (_: lib.toLower) theme;
|
||||||
|
in {
|
||||||
|
programs.foot = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
main = {
|
||||||
|
font = "JetbrainsMono Nerd Font:size=11";
|
||||||
|
pad = "5x5 center";
|
||||||
|
};
|
||||||
|
scrollback = {
|
||||||
|
indicator-position = "fixed";
|
||||||
|
indicator-format = "percentage";
|
||||||
|
};
|
||||||
|
cursor.color = with loweredTheme; "${base} ${rosewater}";
|
||||||
|
text-bindings = {
|
||||||
|
"\\x1b\\x7f" = "Control+BackSpace";
|
||||||
|
};
|
||||||
|
colors = with loweredTheme; rec {
|
||||||
|
foreground = text;
|
||||||
|
background = base;
|
||||||
|
regular0 = surface1;
|
||||||
|
regular1 = red;
|
||||||
|
regular2 = green;
|
||||||
|
regular3 = yellow;
|
||||||
|
regular4 = blue;
|
||||||
|
regular5 = pink;
|
||||||
|
regular6 = teal;
|
||||||
|
regular7 = subtext1;
|
||||||
|
bright0 = regular0;
|
||||||
|
bright1 = regular1;
|
||||||
|
bright2 = regular2;
|
||||||
|
bright3 = regular3;
|
||||||
|
bright4 = regular4;
|
||||||
|
bright5 = regular5;
|
||||||
|
bright6 = regular6;
|
||||||
|
bright7 = regular7;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
46
modules/home/graphical/wayland/fuzzel.nix
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{ pkgs, config, lib, theme, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland.fuzzel;
|
||||||
|
in {
|
||||||
|
options.my.graphical.wayland.fuzzel = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
home.packages = [ pkgs.fuzzel ];
|
||||||
|
xdg.configFile."fuzzel/fuzzel.ini".text = lib.generators.toINI { } {
|
||||||
|
main = {
|
||||||
|
font = "DejaVu Sans Mono:size=13";
|
||||||
|
icon-theme = "Papirus-Dark";
|
||||||
|
show-actions = true;
|
||||||
|
terminal = "${config.programs.foot.package}/bin/foot -e";
|
||||||
|
width = 80;
|
||||||
|
horizontal-pad = 60;
|
||||||
|
vertical-pad = 30;
|
||||||
|
inner-pad = 20;
|
||||||
|
line-height = 24;
|
||||||
|
};
|
||||||
|
colors = builtins.mapAttrs (_: val: "${val}FF") (with theme; {
|
||||||
|
background = mantle;
|
||||||
|
text = overlay2;
|
||||||
|
match = lavender;
|
||||||
|
selection = surface0;
|
||||||
|
selection-text = text;
|
||||||
|
selection-match = mauve;
|
||||||
|
border = mauve;
|
||||||
|
});
|
||||||
|
key-bindings = {
|
||||||
|
cursor-left = "Left Control+b Mod1+h";
|
||||||
|
cursor-right = "Right Control+f Mod1+l";
|
||||||
|
delete-prev = "BackSpace Control+h";
|
||||||
|
delete-prev-word = "Mod1+BackSpace Control+BackSpace Control+w";
|
||||||
|
prev = "Up Control+p Mod1+k";
|
||||||
|
prev-page = "KP_Prior Mod1+v";
|
||||||
|
next = "Down Control+n Mod1+j";
|
||||||
|
next-page = "KP_Next Control+v";
|
||||||
|
};
|
||||||
|
border.width = 3;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
26
modules/home/graphical/wayland/gammastep.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland.gammastep;
|
||||||
|
in {
|
||||||
|
options.my.graphical.wayland.gammastep = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.gammastep = {
|
||||||
|
enable = true;
|
||||||
|
provider = "geoclue2";
|
||||||
|
temperature = {
|
||||||
|
day = 6500;
|
||||||
|
night = 2750;
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
general = {
|
||||||
|
fade = 1;
|
||||||
|
adjustment-method = "wayland";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
29
modules/home/graphical/wayland/gestures.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland.gestures;
|
||||||
|
in {
|
||||||
|
options.my.graphical.wayland.gestures = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
xdg.configFile = let
|
||||||
|
serviceName = "libinput-gestures.service";
|
||||||
|
service = "${pkgs.libinput-gestures}/share/systemd/user/${serviceName}";
|
||||||
|
in {
|
||||||
|
"systemd/user/${serviceName}".source = service;
|
||||||
|
"systemd/user/hyprland-session.target.wants/${serviceName}".source = service;
|
||||||
|
"libinput-gestures.conf" = {
|
||||||
|
text = let
|
||||||
|
hyprctl = "${config.wayland.windowManager.hyprland.package}/bin/hyprctl";
|
||||||
|
in ''
|
||||||
|
gesture pinch in 4 ${hyprctl} dispatch killactive
|
||||||
|
'';
|
||||||
|
onChange = ''
|
||||||
|
${pkgs.systemd}/bin/systemctl --user restart ${serviceName}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
445
modules/home/graphical/wayland/hyprland.nix
Normal file
|
@ -0,0 +1,445 @@
|
||||||
|
{ pkgs, inputs, config, lib, self, osConfig, theme, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland.hyprland;
|
||||||
|
in {
|
||||||
|
options.my.graphical.wayland.hyprland = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
tearing = lib.mkEnableOption null;
|
||||||
|
mainMod = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "SUPER";
|
||||||
|
};
|
||||||
|
lockBinary = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
wallpaper = {
|
||||||
|
enable = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
backend = lib.mkOption {
|
||||||
|
type = lib.types.enum [ "hyprpaper" "swaybg" ];
|
||||||
|
default = "swaybg";
|
||||||
|
};
|
||||||
|
image = lib.mkOption {
|
||||||
|
type = lib.types.pathInStore;
|
||||||
|
default = "${self}/assets/snowyMountain.jpg";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable (let
|
||||||
|
toggleOption = pkgs.writeShellScriptBin "hypr-toggle-opt" ''
|
||||||
|
hyprctl keyword "$1" "$(hyprctl getoption "$1" -j | ${pkgs.jaq}/bin/jaq '1 - .int')"
|
||||||
|
'';
|
||||||
|
copyOutput = pkgs.writeShellScript "hypr-copy-output" ''
|
||||||
|
MONITOR="$(hyprctl monitors -j | ${pkgs.jaq}/bin/jaq -r '.[] | select(.focused).name')"
|
||||||
|
grim -o "$MONITOR" - | wl-copy -t image/png
|
||||||
|
'';
|
||||||
|
copyWindow = pkgs.writeShellScript "hypr-copy-window" ''
|
||||||
|
WINDOW="$(hyprctl activewindow -j | ${pkgs.jaq}/bin/jaq -r '.address')"
|
||||||
|
grim -w "$WINDOW" - | wl-copy -t image/png
|
||||||
|
'';
|
||||||
|
winShiftS = with pkgs; writeShellScriptBin "win-shift-s" ''
|
||||||
|
FILENAME="/tmp/win-shift-s-$PPID.png"
|
||||||
|
MONITOR="$(hyprctl monitors -j | ${_ jaq} -r '.[] | select(.focused)')"
|
||||||
|
${_ grim} -o "$(${_ jaq} -r '.name' <<< "$MONITOR")" "$FILENAME"
|
||||||
|
${_ imv} -f "$FILENAME" & IMV_PROC=$!
|
||||||
|
DIMENSIONS="$(${_ slurp} -f '%wx%h+%X+%Y')"
|
||||||
|
[ "$?" -eq 0 ] && \
|
||||||
|
${_ imagemagick} "$FILENAME" -crop "$DIMENSIONS" - | \
|
||||||
|
${wl-clipboard}/bin/wl-copy -t image/png
|
||||||
|
kill $IMV_PROC
|
||||||
|
exec rm "$FILENAME"
|
||||||
|
'';
|
||||||
|
timeWindow = let
|
||||||
|
inherit (inputs.cl-hyprland-ipc.packages.${pkgs.system}) cl-hyprland-ipc;
|
||||||
|
inherit (cl-hyprland-ipc) asdfFasl faslExt;
|
||||||
|
sbclWithPackages = pkgs.sbcl.withPackages (_: [ cl-hyprland-ipc ]);
|
||||||
|
in pkgs.runCommand "time-window" { } ''
|
||||||
|
${sbclWithPackages}/bin/sbcl --load ${asdfFasl}/asdf.${faslExt} \
|
||||||
|
--load ${../../scripts/time-window.lisp} \
|
||||||
|
--eval '(setf uiop:*image-entry-point* #'\''\''time-window:main)' \
|
||||||
|
--eval '(uiop:dump-image "time-window" :executable t :compression t)'
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp time-window $out/bin
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
home.packages = [
|
||||||
|
toggleOption
|
||||||
|
timeWindow
|
||||||
|
];
|
||||||
|
|
||||||
|
wayland.windowManager.hyprland = let
|
||||||
|
c = builtins.mapAttrs (_: t: "0xFF${t}") theme;
|
||||||
|
inherit (cfg) mainMod;
|
||||||
|
activeBorder = "${c.peach} ${c.mauve} 45deg";
|
||||||
|
transparent = "0x00000000";
|
||||||
|
in {
|
||||||
|
enable = true;
|
||||||
|
package = osConfig.programs.hyprland.package;
|
||||||
|
settings = {
|
||||||
|
exec-once = lib.optional (!osConfig.my.fs.luks.enable) "${pkgs.writeShellScript "start-hyprland" ''
|
||||||
|
[ -n "$GREETD_SOCK" ] && ${pkgs.swaylock-effects}/bin/swaylock ${
|
||||||
|
lib.optionalString cfg.wallpaper.enable "-i ${cfg.wallpaper.image}"
|
||||||
|
} &
|
||||||
|
''}";
|
||||||
|
|
||||||
|
env = [ ]
|
||||||
|
++ lib.optional config.my.graphical.emacs.enable "VISUAL, emacsclient -c";
|
||||||
|
|
||||||
|
monitor = [
|
||||||
|
"eDP-1, preferred, 0x0, 1.33"
|
||||||
|
", preferred, auto, 1"
|
||||||
|
|
||||||
|
# Manually reserved area for bar
|
||||||
|
", addreserved, 42, 0, 0, 0"
|
||||||
|
];
|
||||||
|
|
||||||
|
input = {
|
||||||
|
kb_layout = "us";
|
||||||
|
repeat_delay = 300;
|
||||||
|
repeat_rate = 20;
|
||||||
|
float_switch_override_focus = 2;
|
||||||
|
|
||||||
|
touchpad = {
|
||||||
|
natural_scroll = true;
|
||||||
|
scroll_factor = 0.3;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
general = {
|
||||||
|
layout = "dwindle";
|
||||||
|
allow_tearing = cfg.tearing;
|
||||||
|
gaps_in = 5;
|
||||||
|
gaps_out = 13;
|
||||||
|
border_size = 3;
|
||||||
|
"col.active_border" = activeBorder;
|
||||||
|
"col.inactive_border" = transparent;
|
||||||
|
};
|
||||||
|
|
||||||
|
dwindle = {
|
||||||
|
force_split = 2;
|
||||||
|
preserve_split = true;
|
||||||
|
no_gaps_when_only = 1;
|
||||||
|
special_scale_factor = 0.9;
|
||||||
|
};
|
||||||
|
|
||||||
|
decoration = {
|
||||||
|
rounding = 11;
|
||||||
|
dim_special = 0;
|
||||||
|
drop_shadow = false;
|
||||||
|
|
||||||
|
blur = {
|
||||||
|
enabled = false;
|
||||||
|
size = 8;
|
||||||
|
passes = 2;
|
||||||
|
|
||||||
|
ignore_opacity = true;
|
||||||
|
xray = true;
|
||||||
|
|
||||||
|
noise = 0;
|
||||||
|
contrast = 1;
|
||||||
|
brightness = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
group = {
|
||||||
|
"col.border_active" = activeBorder;
|
||||||
|
"col.border_inactive" = transparent;
|
||||||
|
"col.border_locked_active" = c.red;
|
||||||
|
"col.border_locked_inactive" = transparent;
|
||||||
|
|
||||||
|
groupbar = {
|
||||||
|
render_titles = false;
|
||||||
|
height = 3;
|
||||||
|
"col.active" = c.green;
|
||||||
|
"col.inactive" = transparent;
|
||||||
|
"col.locked_active" = c.red;
|
||||||
|
"col.locked_inactive" = transparent;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
animations = {
|
||||||
|
enabled = true;
|
||||||
|
|
||||||
|
bezier = [
|
||||||
|
"easeInSine, 0.12, 0, 0.39, 0"
|
||||||
|
"easeOutSine, 0.61, 1, 0.88, 1"
|
||||||
|
];
|
||||||
|
|
||||||
|
animation = [
|
||||||
|
"windowsIn, 1, 3, easeOutSine, slide"
|
||||||
|
"windowsOut, 1, 3, easeInSine, slide"
|
||||||
|
"windowsMove, 1, 2.5, easeOutSine, slide"
|
||||||
|
|
||||||
|
"workspaces, 1, 2.5, easeOutSine, slide"
|
||||||
|
"specialWorkspace, 1, 6, default, slidevert"
|
||||||
|
|
||||||
|
"fade, 0"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
gestures = {
|
||||||
|
workspace_swipe = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
binds = {
|
||||||
|
allow_workspace_cycles = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
xwayland = {
|
||||||
|
use_nearest_neighbor = false;
|
||||||
|
force_zero_scaling = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
misc = {
|
||||||
|
vrr = 1;
|
||||||
|
|
||||||
|
disable_hyprland_logo = true;
|
||||||
|
disable_splash_rendering = true;
|
||||||
|
background_color = c.crust;
|
||||||
|
|
||||||
|
disable_autoreload = true;
|
||||||
|
focus_on_activate = true;
|
||||||
|
animate_manual_resizes = false;
|
||||||
|
animate_mouse_windowdragging = false;
|
||||||
|
new_window_takes_over_fullscreen = 2;
|
||||||
|
|
||||||
|
enable_swallow = false;
|
||||||
|
swallow_regex = "^(foot(client)?|kitty)$";
|
||||||
|
};
|
||||||
|
|
||||||
|
windowrule = [
|
||||||
|
"tile, ^(Aseprite)$"
|
||||||
|
"fullscreen, ^(Baba Is You|ADanceOfFireAndIce)$"
|
||||||
|
"float, ^(EverestSplash-linux)$"
|
||||||
|
"float, title:^(emacs-everywhere)$"
|
||||||
|
] ++ lib.optional cfg.tearing
|
||||||
|
"immediate, ^(ADanceOfFireAndIce|Celeste|hollow_knight\\.x86_64|portal2_linux)$";
|
||||||
|
|
||||||
|
windowrulev2 = [
|
||||||
|
"float, class:^(firefox)$, title:^(Picture-in-Picture)$"
|
||||||
|
"pin, class:^(firefox)$, title:^(Picture-in-Picture)$"
|
||||||
|
|
||||||
|
"tile, class:^(Spotify)$, title:^(?!Ozone X11$).*$"
|
||||||
|
"float, class:^(Spotify)$, title:^$"
|
||||||
|
];
|
||||||
|
|
||||||
|
bind = [
|
||||||
|
"${mainMod}, Return, exec, foot"
|
||||||
|
"${mainMod}, C, killactive,"
|
||||||
|
"${mainMod} SHIFT, C, exec, hyprctl activewindow -j | ${pkgs.jaq}/bin/jaq -r '.pid' | xargs kill -9"
|
||||||
|
"${mainMod}, E, exec, thunar"
|
||||||
|
"${mainMod}, M, exec, emacsclient -c"
|
||||||
|
"${mainMod} SHIFT, M, exec, emacsclient -e '(emacs-everywhere)'"
|
||||||
|
"${mainMod} SHIFT, Return, togglefloating,"
|
||||||
|
|
||||||
|
"${mainMod}, Space, fullscreen, 1"
|
||||||
|
"${mainMod} SHIFT, Space, fullscreen, 0"
|
||||||
|
|
||||||
|
"${mainMod}, I, exec, dunstctl action"
|
||||||
|
"${mainMod} SHIFT, I, exec, dunstctl context"
|
||||||
|
"${mainMod} ALT, I, exec, dunstctl history-pop"
|
||||||
|
"${mainMod} CTRL, I, exec, dunstctl close"
|
||||||
|
|
||||||
|
"${mainMod}, Semicolon, exec, killall fuzzel || fuzzel"
|
||||||
|
|
||||||
|
"${mainMod}, Y, pin,"
|
||||||
|
|
||||||
|
# Groups
|
||||||
|
"${mainMod}, F, changegroupactive, f"
|
||||||
|
"${mainMod} SHIFT, F, togglegroup,"
|
||||||
|
"${mainMod} CTRL, F, lockactivegroup, toggle"
|
||||||
|
|
||||||
|
# Directions
|
||||||
|
"${mainMod}, Period, layoutmsg, preselect r"
|
||||||
|
"${mainMod}, Comma, layoutmsg, preselect d"
|
||||||
|
"${mainMod}, S, layoutmsg, togglesplit"
|
||||||
|
|
||||||
|
# Moving windows (with groups)
|
||||||
|
"${mainMod} SHIFT, left, movewindoworgroup, l"
|
||||||
|
"${mainMod} SHIFT, right, movewindoworgroup, r"
|
||||||
|
"${mainMod} SHIFT, up, movewindoworgroup, u"
|
||||||
|
"${mainMod} SHIFT, down, movewindoworgroup, d"
|
||||||
|
"${mainMod} SHIFT, H, movewindoworgroup, l"
|
||||||
|
"${mainMod} SHIFT, L, movewindoworgroup, r"
|
||||||
|
"${mainMod} SHIFT, K, movewindoworgroup, u"
|
||||||
|
"${mainMod} SHIFT, J, movewindoworgroup, d"
|
||||||
|
|
||||||
|
# Moving windows (without groups)
|
||||||
|
"${mainMod} ALT, left, movewindow, l"
|
||||||
|
"${mainMod} ALT, right, movewindow, r"
|
||||||
|
"${mainMod} ALT, up, movewindow, u"
|
||||||
|
"${mainMod} ALT, down, movewindow, d"
|
||||||
|
"${mainMod} ALT, H, movewindow, l"
|
||||||
|
"${mainMod} ALT, L, movewindow, r"
|
||||||
|
"${mainMod} ALT, K, movewindow, u"
|
||||||
|
"${mainMod} ALT, J, movewindow, d"
|
||||||
|
|
||||||
|
# Workspaces
|
||||||
|
"${mainMod} CTRL, P, focusworkspaceoncurrentmonitor, previous"
|
||||||
|
"${mainMod} CTRL, N, focusworkspaceoncurrentmonitor, empty"
|
||||||
|
"${mainMod} CTRL SHIFT, P, movetoworkspace, previous"
|
||||||
|
"${mainMod} CTRL SHIFT, N, movetoworkspace, empty"
|
||||||
|
|
||||||
|
# Screenshot
|
||||||
|
", Print, exec, ${copyOutput}"
|
||||||
|
"ALT, Print, exec, ${copyWindow}"
|
||||||
|
"${mainMod} SHIFT, S, exec, grim -g \"$(slurp)\" - | wl-copy -t image/png"
|
||||||
|
|
||||||
|
# Move focus
|
||||||
|
"${mainMod}, left, movefocus, l"
|
||||||
|
"${mainMod}, right, movefocus, r"
|
||||||
|
"${mainMod}, up, movefocus, u"
|
||||||
|
"${mainMod}, down, movefocus, d"
|
||||||
|
"${mainMod}, H, movefocus, l"
|
||||||
|
"${mainMod}, L, movefocus, r"
|
||||||
|
"${mainMod}, K, movefocus, u"
|
||||||
|
"${mainMod}, J, movefocus, d"
|
||||||
|
|
||||||
|
# Switch workspaces with mainMod + [1-9]
|
||||||
|
"${mainMod}, 1, focusworkspaceoncurrentmonitor, 1"
|
||||||
|
"${mainMod}, 2, focusworkspaceoncurrentmonitor, 2"
|
||||||
|
"${mainMod}, 3, focusworkspaceoncurrentmonitor, 3"
|
||||||
|
"${mainMod}, 4, focusworkspaceoncurrentmonitor, 4"
|
||||||
|
"${mainMod}, 5, focusworkspaceoncurrentmonitor, 5"
|
||||||
|
"${mainMod}, 6, focusworkspaceoncurrentmonitor, 6"
|
||||||
|
"${mainMod}, 7, focusworkspaceoncurrentmonitor, 7"
|
||||||
|
"${mainMod}, 8, focusworkspaceoncurrentmonitor, 8"
|
||||||
|
"${mainMod}, 9, focusworkspaceoncurrentmonitor, 9"
|
||||||
|
|
||||||
|
# Switch workspaces with mainMod + N/P/O
|
||||||
|
"${mainMod}, N, focusworkspaceoncurrentmonitor, e+1"
|
||||||
|
"${mainMod}, P, focusworkspaceoncurrentmonitor, e-1"
|
||||||
|
"${mainMod} SHIFT, N, movetoworkspace, e+1"
|
||||||
|
"${mainMod} SHIFT, P, movetoworkspace, e-1"
|
||||||
|
|
||||||
|
# Move active window to a workspace with mainMod + SHIFT + [1-9]
|
||||||
|
"${mainMod} SHIFT, 1, movetoworkspace, 1"
|
||||||
|
"${mainMod} SHIFT, 2, movetoworkspace, 2"
|
||||||
|
"${mainMod} SHIFT, 3, movetoworkspace, 3"
|
||||||
|
"${mainMod} SHIFT, 4, movetoworkspace, 4"
|
||||||
|
"${mainMod} SHIFT, 5, movetoworkspace, 5"
|
||||||
|
"${mainMod} SHIFT, 6, movetoworkspace, 6"
|
||||||
|
"${mainMod} SHIFT, 7, movetoworkspace, 7"
|
||||||
|
"${mainMod} SHIFT, 8, movetoworkspace, 8"
|
||||||
|
"${mainMod} SHIFT, 9, movetoworkspace, 9"
|
||||||
|
|
||||||
|
# Scroll through existing workspaces with mainMod + scroll/side buttons
|
||||||
|
"${mainMod}, mouse_down, focusworkspaceoncurrentmonitor, e-1"
|
||||||
|
"${mainMod}, mouse_up, focusworkspaceoncurrentmonitor, e+1"
|
||||||
|
"${mainMod}, mouse:275, focusworkspaceoncurrentmonitor, e-1"
|
||||||
|
"${mainMod}, mouse:276, focusworkspaceoncurrentmonitor, e+1"
|
||||||
|
|
||||||
|
# Scratchpads
|
||||||
|
"${mainMod} SHIFT, 0, movetoworkspace, special:a"
|
||||||
|
"${mainMod}, 0, togglespecialworkspace, a"
|
||||||
|
"${mainMod} SHIFT, minus, movetoworkspace, special:b"
|
||||||
|
"${mainMod}, minus, togglespecialworkspace, b"
|
||||||
|
"${mainMod} SHIFT, equal, movetoworkspace, special:c"
|
||||||
|
"${mainMod}, equal, togglespecialworkspace, c"
|
||||||
|
|
||||||
|
"${mainMod}, T, exec, ${toggleOption}/bin/hypr-toggle-opt input:touchpad:disable_while_typing"
|
||||||
|
];
|
||||||
|
|
||||||
|
bindl = [
|
||||||
|
"${mainMod}, Q, exec, ${cfg.lockBinary}"
|
||||||
|
"${mainMod} ALT, Q, exec, killall ${cfg.lockBinary} .${cfg.lockBinary}-wrapped ; ${cfg.lockBinary}"
|
||||||
|
"${mainMod} SHIFT, Q, exit,"
|
||||||
|
|
||||||
|
", XF86AudioMute, exec, dunst-volume set-mute toggle"
|
||||||
|
];
|
||||||
|
|
||||||
|
binde = [
|
||||||
|
# Resize windows
|
||||||
|
"${mainMod} CTRL ALT, left, resizeactive, -10 0"
|
||||||
|
"${mainMod} CTRL ALT, right, resizeactive, 10 0"
|
||||||
|
"${mainMod} CTRL ALT, up, resizeactive, 0 -10"
|
||||||
|
"${mainMod} CTRL ALT, down, resizeactive, 0 10"
|
||||||
|
"${mainMod} CTRL ALT, H, resizeactive, -10 0"
|
||||||
|
"${mainMod} CTRL ALT, L, resizeactive, 10 0"
|
||||||
|
"${mainMod} CTRL ALT, K, resizeactive, 0 -10"
|
||||||
|
"${mainMod} CTRL ALT, J, resizeactive, 0 10"
|
||||||
|
|
||||||
|
# Move floating windows
|
||||||
|
"${mainMod} CTRL, left, moveactive, -50 0"
|
||||||
|
"${mainMod} CTRL, right, moveactive, 50 0"
|
||||||
|
"${mainMod} CTRL, up, moveactive, 0 -50"
|
||||||
|
"${mainMod} CTRL, down, moveactive, 0 50"
|
||||||
|
"${mainMod} CTRL, H, moveactive, -50 0"
|
||||||
|
"${mainMod} CTRL, L, moveactive, 50 0"
|
||||||
|
"${mainMod} CTRL, K, moveactive, 0 -50"
|
||||||
|
"${mainMod} CTRL, J, moveactive, 0 50"
|
||||||
|
];
|
||||||
|
|
||||||
|
bindm = [
|
||||||
|
# Move/resize windows with mainMod + LMB/RMB and dragging
|
||||||
|
"${mainMod}, mouse:272, movewindow"
|
||||||
|
"${mainMod}, mouse:273, resizewindow"
|
||||||
|
];
|
||||||
|
|
||||||
|
bindel = [
|
||||||
|
# Media keys
|
||||||
|
", XF86AudioRaiseVolume, exec, dunst-volume set-volume 5%+"
|
||||||
|
", XF86AudioLowerVolume, exec, dunst-volume set-volume 5%-"
|
||||||
|
|
||||||
|
", XF86MonBrightnessDown, exec, dunst-brightness 5%+"
|
||||||
|
", XF86MonBrightnessUp, exec, dunst-brightness 5%-"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
# Passthrough mode
|
||||||
|
bind = ${mainMod}, Escape, submap, passthrough
|
||||||
|
submap = passthrough
|
||||||
|
bind = ${mainMod}, Escape, submap, reset
|
||||||
|
submap = reset
|
||||||
|
|
||||||
|
# OBS
|
||||||
|
bind = ${mainMod} CTRL, O, submap, OBS
|
||||||
|
submap = OBS
|
||||||
|
bind = , Space, pass, ^(com\.obsproject\.Studio)$
|
||||||
|
bind = , P, pass, ^(com\.obsproject\.Studio)$
|
||||||
|
bind = , Escape, submap, reset
|
||||||
|
bind = ${mainMod}, Escape, submap, reset
|
||||||
|
submap = reset
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services = lib.mkIf cfg.wallpaper.enable {
|
||||||
|
hyprpaper = lib.mkIf (cfg.wallpaper.backend == "hyprpaper") {
|
||||||
|
Unit = {
|
||||||
|
Description = "Background wallpaper image via hyprpaper";
|
||||||
|
After = "hyprland-session.target";
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart = let
|
||||||
|
hyprpaperConfig = pkgs.writeText "hyprpaper.conf" ''
|
||||||
|
preload = ${cfg.wallpaper.image}
|
||||||
|
wallpaper = ,${cfg.wallpaper.image}
|
||||||
|
ipc = off
|
||||||
|
splash = off
|
||||||
|
'';
|
||||||
|
in "${pkgs.hyprpaper}/bin/hyprpaper -c ${hyprpaperConfig}";
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "hyprland-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
swaybg = lib.mkIf (cfg.wallpaper.backend == "swaybg") {
|
||||||
|
Unit = {
|
||||||
|
Description = "Background wallpaper image via swaybg";
|
||||||
|
After = "hyprland-session.target";
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart = "${pkgs.swaybg}/bin/swaybg -i ${cfg.wallpaper.image} -m fill -o '*'";
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "hyprland-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
66
modules/home/graphical/wayland/hyprlock.nix
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
{ pkgs, config, lib, self, theme, inputs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland.hyprlock;
|
||||||
|
in {
|
||||||
|
options.my.graphical.wayland.hyprlock = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs.hyprlock = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
package = inputs.hyprlock.packages.${pkgs.system}.hyprlock;
|
||||||
|
|
||||||
|
settings = let
|
||||||
|
c = builtins.mapAttrs (_: t: "0xFF${t}") theme;
|
||||||
|
commaVals = x: y: "${builtins.toString x}, ${builtins.toString y}";
|
||||||
|
in {
|
||||||
|
general = {
|
||||||
|
hide_cursor = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
background = lib.singleton {
|
||||||
|
path = "screenshot";
|
||||||
|
blur_size = 15;
|
||||||
|
blur_passes = 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
input-field = lib.singleton {
|
||||||
|
fade_on_empty = false;
|
||||||
|
placeholder_text = "";
|
||||||
|
size = commaVals 350 70;
|
||||||
|
dots_size= 0.33;
|
||||||
|
outline_thickness = 5;
|
||||||
|
position = commaVals 0 (-100);
|
||||||
|
outer_color = c.mauve;
|
||||||
|
inner_color = c.crust;
|
||||||
|
font_color = c.text;
|
||||||
|
check_color = c.blue;
|
||||||
|
fail_color = c.red;
|
||||||
|
capslock_color = c.yellow;
|
||||||
|
numlock_color = c.yellow;
|
||||||
|
bothlock_color = c.yellow;
|
||||||
|
};
|
||||||
|
|
||||||
|
image = lib.singleton {
|
||||||
|
path = "${self}/assets/quag-head.png";
|
||||||
|
size = 180;
|
||||||
|
border_size = 5;
|
||||||
|
position = commaVals 0 80;
|
||||||
|
border_color = c.mauve;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
my.graphical.wayland = {
|
||||||
|
ydotool.enable = true;
|
||||||
|
swayidle.lockCommand = "${config.programs.hyprlock.package}/bin/hyprlock --no-fade-in & sleep 0.3";
|
||||||
|
hyprland.lockBinary = "hyprlock";
|
||||||
|
};
|
||||||
|
|
||||||
|
wayland.windowManager.hyprland.settings.misc.allow_session_lock_restore = true;
|
||||||
|
};
|
||||||
|
}
|
40
modules/home/graphical/wayland/kanshi.nix
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland.kanshi;
|
||||||
|
in {
|
||||||
|
options.my.graphical.wayland.kanshi = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.kanshi = {
|
||||||
|
enable = true;
|
||||||
|
systemdTarget = "hyprland-session.target";
|
||||||
|
profiles = {
|
||||||
|
undocked = {
|
||||||
|
outputs = [
|
||||||
|
{
|
||||||
|
criteria = "eDP-1";
|
||||||
|
status = "enable";
|
||||||
|
scale = 1.0;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
docked = {
|
||||||
|
exec = "${pkgs.systemd}/bin/systemctl --user restart eww-bar.service";
|
||||||
|
outputs = [
|
||||||
|
{
|
||||||
|
criteria = "eDP-1";
|
||||||
|
status = "disable";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
criteria = "HDMI-A-1";
|
||||||
|
status = "enable";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
41
modules/home/graphical/wayland/swayidle.nix
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{ pkgs, config, lib, osConfig, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland.swayidle;
|
||||||
|
in {
|
||||||
|
options.my.graphical.wayland.swayidle = {
|
||||||
|
enable = lib.mkEnableOption null // {
|
||||||
|
default = osConfig.my.laptop.enable;
|
||||||
|
};
|
||||||
|
lockCommand = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.swayidle = {
|
||||||
|
enable = true;
|
||||||
|
systemdTarget = "hyprland-session.target";
|
||||||
|
timeouts = let
|
||||||
|
inherit (pkgs) brightnessctl acpi gnugrep systemd;
|
||||||
|
withBat = command: "${acpi}/bin/acpi -b | ${gnugrep}/bin/grep -q 'Discharging' && ${command}";
|
||||||
|
in [
|
||||||
|
{
|
||||||
|
timeout = 60;
|
||||||
|
command = withBat "${brightnessctl}/bin/brightnessctl -s s 0";
|
||||||
|
resumeCommand = withBat "${brightnessctl}/bin/brightnessctl -r";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
timeout = 300;
|
||||||
|
command = withBat "${systemd}/bin/systemctl suspend";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
events = [
|
||||||
|
{
|
||||||
|
event = "before-sleep";
|
||||||
|
command = cfg.lockCommand;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
75
modules/home/graphical/wayland/swaylock.nix
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
{ pkgs, config, lib, theme, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland.swaylock;
|
||||||
|
in {
|
||||||
|
options.my.graphical.wayland.swaylock = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs.swaylock = {
|
||||||
|
enable = true;
|
||||||
|
package = with pkgs; symlinkJoin {
|
||||||
|
name = "swaylock-effects-blur-flags";
|
||||||
|
paths = [ swaylock-effects ];
|
||||||
|
nativeBuildInputs = [ makeWrapper ];
|
||||||
|
postBuild = ''
|
||||||
|
wrapProgram $out/bin/swaylock \
|
||||||
|
--add-flags -S \
|
||||||
|
--add-flags --fade-in \
|
||||||
|
--add-flags 0.3 \
|
||||||
|
--add-flags --effect-blur \
|
||||||
|
--add-flags 15x3
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
settings = with theme; {
|
||||||
|
indicator = true;
|
||||||
|
clock = true;
|
||||||
|
indicator-thickness = 6;
|
||||||
|
|
||||||
|
ignore-empty-password = true;
|
||||||
|
show-failed-attempts = true;
|
||||||
|
show-keyboard-layout = true;
|
||||||
|
indicator-caps-lock = true;
|
||||||
|
|
||||||
|
line-uses-inside = true;
|
||||||
|
key-hl-color = crust;
|
||||||
|
bs-hl-color = crust;
|
||||||
|
|
||||||
|
inside-caps-lock-color = yellow;
|
||||||
|
caps-lock-key-hl-color = yellow;
|
||||||
|
caps-lock-bs-hl-color = yellow;
|
||||||
|
text-caps-lock-color = crust;
|
||||||
|
ring-caps-lock-color = crust;
|
||||||
|
|
||||||
|
ring-ver-color = blue;
|
||||||
|
text-ver-color = blue;
|
||||||
|
|
||||||
|
ring-clear-color = yellow;
|
||||||
|
text-clear-color = yellow;
|
||||||
|
|
||||||
|
ring-wrong-color = red;
|
||||||
|
text-wrong-color = red;
|
||||||
|
|
||||||
|
inside-color = crust;
|
||||||
|
inside-ver-color = crust;
|
||||||
|
inside-clear-color = crust;
|
||||||
|
inside-wrong-color = crust;
|
||||||
|
ring-color = mauve;
|
||||||
|
|
||||||
|
text-color = rosewater;
|
||||||
|
|
||||||
|
layout-bg-color = mauve;
|
||||||
|
layout-text-color = crust;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
my.graphical.wayland = {
|
||||||
|
swayidle.lockCommand = "${pkgs.swaylock-effects}/bin/swaylock -f -S --effect-blur 15x3";
|
||||||
|
hyprland.lockBinary = "swaylock";
|
||||||
|
};
|
||||||
|
|
||||||
|
wayland.windowManager.hyprland.settings.misc.allow_session_lock_restore = true;
|
||||||
|
};
|
||||||
|
}
|
20
modules/home/graphical/wayland/ydotool.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.wayland.ydotool;
|
||||||
|
in {
|
||||||
|
options.my.graphical.wayland.ydotool = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
home.packages = [ pkgs.ydotool ];
|
||||||
|
xdg.configFile = let
|
||||||
|
serviceName = "ydotool.service";
|
||||||
|
service = "${pkgs.ydotool}/share/systemd/user/${serviceName}";
|
||||||
|
in {
|
||||||
|
"systemd/user/${serviceName}".source = service;
|
||||||
|
"systemd/user/default.target.wants/${serviceName}".source = service;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
19
modules/home/graphical/zathura.nix
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.graphical.zathura;
|
||||||
|
in {
|
||||||
|
options.my.graphical.zathura = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
home.packages = [ pkgs.zathura ];
|
||||||
|
xdg.configFile."zathura/zathurarc".source = pkgs.fetchFromGitHub {
|
||||||
|
owner = "catppuccin";
|
||||||
|
repo = "zathura";
|
||||||
|
rev = "1bda9d8274dd327b7931886ef0c5c1eb33903814";
|
||||||
|
hash = "sha256-HWOc5tnVgU/HUcVcIXACeuu3RDH1pHO/8DQRsWqumIA=";
|
||||||
|
} + "/src/catppuccin-mocha";
|
||||||
|
};
|
||||||
|
}
|
44
modules/home/mpd.nix
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
{ pkgs, config, lib, osConfig, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.mpd;
|
||||||
|
in {
|
||||||
|
options.my.mpd = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
usePipewire = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
ncmpcpp = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.mpd = {
|
||||||
|
enable = true;
|
||||||
|
extraConfig = ''
|
||||||
|
restore_paused "yes"
|
||||||
|
zeroconf_enabled "no"
|
||||||
|
|
||||||
|
${lib.optionalString cfg.usePipewire ''
|
||||||
|
audio_output {
|
||||||
|
type "pipewire"
|
||||||
|
name "Pipewire Sound Server"
|
||||||
|
mixer_type "hardware"
|
||||||
|
replay_gain_handler "none"
|
||||||
|
}
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.packages = [ pkgs.mpc-cli ];
|
||||||
|
|
||||||
|
programs.ncmpcpp = lib.mkIf cfg.ncmpcpp.enable {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
mpd_host = "127.0.0.1";
|
||||||
|
mpd_port = config.services.mpd.network.port;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
39
modules/home/nix.nix
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{ config, lib, osConfig, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.nix;
|
||||||
|
in {
|
||||||
|
options.my.nix = {
|
||||||
|
gc = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
xdg.configFile = {
|
||||||
|
"nixpkgs/config.nix".text = lib.generators.toPretty {multiline = true;} {
|
||||||
|
inherit (osConfig.nixpkgs.config) allowUnfree;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user = lib.mkIf cfg.gc {
|
||||||
|
services.nix-gc = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Nix User Garbage Collector";
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
ExecStart = "${osConfig.nix.package}/bin/nix-collect-garbage ${osConfig.nix.gc.options}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
timers = {
|
||||||
|
nix-gc = lib.mkIf osConfig.nix.gc.automatic {
|
||||||
|
Timer = osConfig.systemd.timers.nix-gc.timerConfig;
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "timers.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
10
modules/home/packages.nix
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
xdg-utils
|
||||||
|
libnotify
|
||||||
|
pulsemixer
|
||||||
|
pavucontrol
|
||||||
|
];
|
||||||
|
}
|
52
modules/home/scripts/listen-hyprland.rb
Executable file
|
@ -0,0 +1,52 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'socket'
|
||||||
|
|
||||||
|
Thread.abort_on_exception = true
|
||||||
|
|
||||||
|
SOCK_DIR = "#{ENV['XDG_RUNTIME_DIR']}/hypr/#{ENV['HYPRLAND_INSTANCE_SIGNATURE']}"
|
||||||
|
SOCK1 = "#{SOCK_DIR}/.socket.sock"
|
||||||
|
SOCK2 = "#{SOCK_DIR}/.socket2.sock"
|
||||||
|
SOCK_ = "#{SOCK_DIR}/.personal.sock"
|
||||||
|
|
||||||
|
def hyprctl(cmd)
|
||||||
|
Socket.unix(SOCK1) do |s|
|
||||||
|
s.print cmd
|
||||||
|
s.read.force_encoding('UTF-8')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def server_listen(server, sig_out)
|
||||||
|
while (socket = server.accept)
|
||||||
|
while (line = socket.gets)
|
||||||
|
case line.chomp
|
||||||
|
when 'group_next'
|
||||||
|
sig_out[:group_next] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
File.unlink(SOCK_)
|
||||||
|
end
|
||||||
|
|
||||||
|
signals = {}
|
||||||
|
|
||||||
|
Thread.new do
|
||||||
|
server = UNIXServer.new(SOCK_)
|
||||||
|
rescue Errno::EADDRINUSE
|
||||||
|
puts 'personal sock address in use' rescue nil
|
||||||
|
else
|
||||||
|
server_listen(server, signals)
|
||||||
|
end
|
||||||
|
|
||||||
|
Socket.unix(SOCK2) do |socket|
|
||||||
|
while (line = socket.gets)
|
||||||
|
event, _, data = line.partition('>>')
|
||||||
|
data = data.split(',')
|
||||||
|
case event
|
||||||
|
when 'openwindow'
|
||||||
|
hyprctl 'dispatch togglegroup' if signals.delete(:group_next)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
29
modules/home/scripts/sync-music.lisp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
(asdf:load-system :alexandria)
|
||||||
|
(asdf:load-system :cl-fad)
|
||||||
|
|
||||||
|
(uiop:define-package #:sync-music
|
||||||
|
(:use #:cl #:alexandria)
|
||||||
|
(:export #:sync-music #:main))
|
||||||
|
|
||||||
|
(in-package #:sync-music)
|
||||||
|
|
||||||
|
(defvar *dry-run-p* nil)
|
||||||
|
(defvar *cleanupp* nil)
|
||||||
|
|
||||||
|
(defun translate-file-name (file)
|
||||||
|
(when (cl-fad:directory-pathname-p file)
|
||||||
|
(return file))
|
||||||
|
(switch ((pathname-type file) :test #'string-equal)
|
||||||
|
("flac" (make-pathname :name (pathname-name file) :type "ogg"))
|
||||||
|
(("mp3" "ogg" "cue" "m3u" "m3u8") file)))
|
||||||
|
|
||||||
|
(defun sync-directory (directory destination)
|
||||||
|
(loop :for file :in (cl-fad:list-directory directory :follow-symlinks t)
|
||||||
|
:for file-destination := (merge-pathnames destination (translate-file-name file))
|
||||||
|
:when file-destination
|
||||||
|
:collect file-destination :into destinations))
|
||||||
|
|
||||||
|
(defun sync-music (destination &key (music-directory #P"~/Music/"))
|
||||||
|
(unless (cl-fad:directory-exists-p music-directory)
|
||||||
|
(error "Music directory `~A` does not exist!" music-directory))
|
||||||
|
(sync-directory music-directory destination))
|
31
modules/home/scripts/time-window.lisp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
(asdf:load-system :cl-hyprland-ipc)
|
||||||
|
|
||||||
|
(uiop:define-package #:time-window
|
||||||
|
(:use #:cl)
|
||||||
|
(:export #:time-window #:main))
|
||||||
|
|
||||||
|
(in-package #:time-window)
|
||||||
|
|
||||||
|
(defun time-window (argv use-pid)
|
||||||
|
(time
|
||||||
|
(let* ((process-info (uiop:launch-program argv))
|
||||||
|
(pid (uiop:process-info-pid process-info)))
|
||||||
|
(format t "Started process via `~{~A~^ ~}` with PID ~A~%" argv pid)
|
||||||
|
(hyprland-ipc:handle-events
|
||||||
|
:return-on-non-nil-p t
|
||||||
|
:open-window (lambda (address workspace-name class title)
|
||||||
|
(declare (ignorable address workspace-name class title))
|
||||||
|
(or (not use-pid)
|
||||||
|
(= pid
|
||||||
|
(gethash "pid"
|
||||||
|
(hyprland-ipc:find-client-data address)))))))))
|
||||||
|
|
||||||
|
(defun main ()
|
||||||
|
(let* ((argv (uiop:command-line-arguments))
|
||||||
|
(use-pid (string= (first argv) "-p")))
|
||||||
|
(when use-pid
|
||||||
|
(setf argv (rest argv)))
|
||||||
|
(unless argv
|
||||||
|
(format *error-output* "Needs command string!~%")
|
||||||
|
(uiop:quit 1 t))
|
||||||
|
(time-window argv use-pid)))
|
219
modules/home/shell.nix
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.shell;
|
||||||
|
in {
|
||||||
|
options.my.shell = {
|
||||||
|
aliases.enable = lib.mkEnableOption null;
|
||||||
|
direnv.enable = lib.mkEnableOption null;
|
||||||
|
fish.enable = lib.mkEnableOption null;
|
||||||
|
globalNpmPackages.enable = lib.mkEnableOption null;
|
||||||
|
starship.enable = lib.mkEnableOption null;
|
||||||
|
zsh.enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkMerge [
|
||||||
|
(lib.mkIf cfg.aliases.enable {
|
||||||
|
home.shellAliases = {
|
||||||
|
e = "emacsclient -n -c";
|
||||||
|
et = "emacsclient -nw";
|
||||||
|
v = lib.mkDefault "vim";
|
||||||
|
jq = "jaq";
|
||||||
|
java = "java -Dawt.useSystemAAFontSettings=lcd";
|
||||||
|
j = "javac *.java && java Main";
|
||||||
|
syu = "nh os switch --ask --update -- --accept-flake-config";
|
||||||
|
nswitch = "nh os switch --ask -- --accept-flake-config";
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.direnv.enable {
|
||||||
|
programs.direnv = {
|
||||||
|
enable = true;
|
||||||
|
nix-direnv.enable = true;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.fish.enable {
|
||||||
|
programs.fish = {
|
||||||
|
enable = true;
|
||||||
|
interactiveShellInit = let
|
||||||
|
catppuccinMochaSrc = pkgs.fetchFromGitHub {
|
||||||
|
owner = "catppuccin";
|
||||||
|
repo = "fish";
|
||||||
|
rev = "91e6d6721362be05a5c62e235ed8517d90c567c9";
|
||||||
|
hash = "sha256-l9V7YMfJWhKDL65dNbxaddhaM6GJ0CFZ6z+4R6MJwBA=";
|
||||||
|
};
|
||||||
|
catppuccinMochaVars = pkgs.runCommandLocal "catppuccin-mocha-vars" { } ''
|
||||||
|
${pkgs.ed}/bin/ed '${catppuccinMochaSrc}/themes/Catppuccin Mocha.theme' <<- EOF
|
||||||
|
v/^fish_/d
|
||||||
|
%s/^/set -g /
|
||||||
|
w $out
|
||||||
|
EOF
|
||||||
|
'';
|
||||||
|
in ''
|
||||||
|
set -g fish_greeting
|
||||||
|
|
||||||
|
${lib.optionalString config.my.graphical.wayland.foot.enable ''
|
||||||
|
if [ "$TERM" = "foot" ]
|
||||||
|
function mark_prompt_start --on-event fish_prompt
|
||||||
|
echo -en "\e]133;A\e\\"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
plugins = with pkgs.fishPlugins; [
|
||||||
|
{
|
||||||
|
name = "autopair";
|
||||||
|
src = autopair.src;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "sponge";
|
||||||
|
src = sponge.src;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.globalNpmPackages.enable {
|
||||||
|
home = let
|
||||||
|
npmPackagesPath = "${config.home.homeDirectory}/.npm-packages";
|
||||||
|
in {
|
||||||
|
file.".npmrc".text = ''
|
||||||
|
prefix = ${npmPackagesPath}
|
||||||
|
'';
|
||||||
|
sessionPath = [
|
||||||
|
"${npmPackagesPath}/bin"
|
||||||
|
];
|
||||||
|
sessionVariables.NODE_PATH = "${npmPackagesPath}/lib/node_modules";
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.zsh.enable {
|
||||||
|
programs.zsh = {
|
||||||
|
enable = true;
|
||||||
|
dotDir = ".config/zsh";
|
||||||
|
autocd = true;
|
||||||
|
localVariables = {
|
||||||
|
ZVM_VI_HIGHLIGHT_FOREGROUND = "black";
|
||||||
|
ZVM_VI_HIGHLIGHT_BACKGROUND = "red";
|
||||||
|
};
|
||||||
|
initExtraFirst = ''
|
||||||
|
if [[ -n $INSIDE_EMACS ]]; then
|
||||||
|
bindkey -e
|
||||||
|
else
|
||||||
|
AUTOPAIR_INHIBIT_INIT=true
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
initExtra = ''
|
||||||
|
zstyle ':completion:*' menu select
|
||||||
|
zstyle ':completion:*' matcher-list ''\'' \
|
||||||
|
'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' \
|
||||||
|
'+r:|[._-]=* r:|=*' \
|
||||||
|
'+l:|=* r:|=*'
|
||||||
|
zmodload zsh/complist
|
||||||
|
bindkey -M menuselect "''${terminfo[kcbt]}" reverse-menu-complete
|
||||||
|
if [[ -n $INSIDE_EMACS ]]; then
|
||||||
|
autoload -Uz add-zsh-hook
|
||||||
|
add-zsh-hook -d precmd zvm_init
|
||||||
|
bindkey "^W" vi-backward-kill-word
|
||||||
|
else
|
||||||
|
zle -N autopair-insert
|
||||||
|
zle -N autopair-close
|
||||||
|
zle -N autopair-delete
|
||||||
|
|
||||||
|
zvm_after_init_commands+=('
|
||||||
|
for p in ''${(@k)AUTOPAIR_PAIRS}; do
|
||||||
|
zvm_bindkey viins "$p" autopair-insert
|
||||||
|
bindkey -M isearch "$p" self-insert
|
||||||
|
|
||||||
|
local rchar="$(_ap-get-pair $p)"
|
||||||
|
if [[ $p != $rchar ]]; then
|
||||||
|
zvm_bindkey viins "$rchar" autopair-close
|
||||||
|
bindkey -M isearch "$rchar" self-insert
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
zvm_bindkey viins "''${terminfo[kbs]}" autopair-delete
|
||||||
|
zvm_bindkey viins "^h" autopair-delete
|
||||||
|
bindkey -M isearch "''${terminfo[kbs]}" backward-delete-char
|
||||||
|
bindkey -M isearch "^h" backward-delete-char
|
||||||
|
zvm_bindkey viins "^[''${terminfo[kbs]}" vi-backward-kill-word
|
||||||
|
zvm_bindkey viins "^W" vi-backward-kill-word
|
||||||
|
')
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
plugins = with pkgs; [
|
||||||
|
{
|
||||||
|
name = "zsh-autopair";
|
||||||
|
src = zsh-autopair;
|
||||||
|
file = "share/zsh/zsh-autopair/autopair.zsh";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "zsh-vi-mode";
|
||||||
|
src = zsh-vi-mode;
|
||||||
|
file = "share/zsh-vi-mode/zsh-vi-mode.plugin.zsh";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "fast-syntax-highlighting";
|
||||||
|
src = zsh-fast-syntax-highlighting;
|
||||||
|
file = "share/zsh/site-functions/fast-syntax-highlighting.plugin.zsh";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.starship.enable {
|
||||||
|
programs.starship = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
add_newline = false;
|
||||||
|
continuation_prompt = "[>](bold green) ";
|
||||||
|
character = {
|
||||||
|
disabled = false;
|
||||||
|
success_symbol = "[%](bold green)";
|
||||||
|
error_symbol = "[%](bold yellow)";
|
||||||
|
vimcmd_symbol = "[%](bold blue)";
|
||||||
|
};
|
||||||
|
status = {
|
||||||
|
disabled = false;
|
||||||
|
format = "[$symbol$common_meaning$status]($style) ";
|
||||||
|
symbol = "";
|
||||||
|
map_symbol = true;
|
||||||
|
not_executable_symbol = "+x ";
|
||||||
|
not_found_symbol = "?? ";
|
||||||
|
sigint_symbol = "XX ";
|
||||||
|
signal_symbol = "!! ";
|
||||||
|
pipestatus = true;
|
||||||
|
pipestatus_separator = "[|](bold yellow) ";
|
||||||
|
pipestatus_format = "[\\[](bold yellow) $pipestatus"
|
||||||
|
+ "[\\] => ](bold yellow)"
|
||||||
|
+ "[$symbol$common_meaning$status]($style) ";
|
||||||
|
};
|
||||||
|
directory = {
|
||||||
|
style = "bold blue";
|
||||||
|
truncation_length = 6;
|
||||||
|
truncate_to_repo = false;
|
||||||
|
truncation_symbol = ".../";
|
||||||
|
};
|
||||||
|
nix_shell.format = "[$state( \\($name\\))]($style) ";
|
||||||
|
git_branch.format = "[$symbol$branch(:$remote_branch)]($style) ";
|
||||||
|
line_break.disabled = true;
|
||||||
|
c.disabled = true;
|
||||||
|
cmake.disabled = true;
|
||||||
|
golang.disabled = true;
|
||||||
|
haskell.disabled = true;
|
||||||
|
java.disabled = false; # the only marginally useful one
|
||||||
|
nodejs.disabled = true;
|
||||||
|
lua.disabled = true;
|
||||||
|
nim.disabled = true;
|
||||||
|
package.disabled = true;
|
||||||
|
perl.disabled = true;
|
||||||
|
php.disabled = true;
|
||||||
|
python.disabled = true;
|
||||||
|
ruby.disabled = true;
|
||||||
|
rust.disabled = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
74
modules/home/spotify.nix
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
{ pkgs, inputs, config, lib, osConfig, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.spotify;
|
||||||
|
in {
|
||||||
|
imports = [ inputs.spicetify-nix.homeManagerModule ];
|
||||||
|
|
||||||
|
options.my.spotify = {
|
||||||
|
spicetify.enable = lib.mkEnableOption null;
|
||||||
|
spotifyd.enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkMerge [
|
||||||
|
(lib.mkIf cfg.spicetify.enable {
|
||||||
|
home.packages = [
|
||||||
|
(pkgs.runCommandLocal "spicetify-desktop" { } ''
|
||||||
|
mkdir -p "$out/share/applications"
|
||||||
|
${pkgs.ed}/bin/ed ${pkgs.spotify}/share/applications/spotify.desktop <<- EOF
|
||||||
|
%s/^Exec=spotify/Exec=spotifywm/
|
||||||
|
w $out/share/applications/spotify.desktop
|
||||||
|
EOF
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.spicetify = let
|
||||||
|
spicePkgs = inputs.spicetify-nix.packages.${pkgs.system}.default;
|
||||||
|
in {
|
||||||
|
enable = true;
|
||||||
|
theme = spicePkgs.themes.catppuccin;
|
||||||
|
colorScheme = "mocha";
|
||||||
|
windowManagerPatch = true;
|
||||||
|
enabledExtensions = with spicePkgs.extensions; [
|
||||||
|
fullAppDisplay
|
||||||
|
shuffle
|
||||||
|
];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf cfg.spotifyd.enable {
|
||||||
|
home.packages = [ pkgs.spotify-tui ];
|
||||||
|
|
||||||
|
services.spotifyd = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.spotifyd.override {
|
||||||
|
withMpris = true;
|
||||||
|
withPulseAudio = true;
|
||||||
|
};
|
||||||
|
settings.global = {
|
||||||
|
username_cmd = "head -1 ${osConfig.age.secrets.spotify.path}";
|
||||||
|
password_cmd = "tail -1 ${osConfig.age.secrets.spotify.path}";
|
||||||
|
device_name = "spotifyd";
|
||||||
|
cache_path = "${config.xdg.cacheHome}/spotifyd";
|
||||||
|
max_cache_size = 1000000000;
|
||||||
|
no_audio_cache = false;
|
||||||
|
bitrate = 320;
|
||||||
|
initial_volume = "60";
|
||||||
|
volume_normalization = true;
|
||||||
|
normalisation_pregain = -10;
|
||||||
|
use_mpris = true;
|
||||||
|
backend = "pulseaudio";
|
||||||
|
volume_controller = "softvol";
|
||||||
|
zeroconf_port = 1234;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."spotify-tui/config.yml".source = pkgs.fetchFromGitHub {
|
||||||
|
owner = "catppuccin";
|
||||||
|
repo = "spotify-tui";
|
||||||
|
rev = "45a4ef12508784410c516746c9d84862d52e4567";
|
||||||
|
sha256 = "1i9c30n20wq0mpvfd2ip19b1mp9ifiy2shxh16i6kfql9jr7wwj5";
|
||||||
|
} + "/mocha.yml";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
31
modules/home/themes/catppuccin.nix
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
rosewater = "F5E0DC";
|
||||||
|
flamingo = "F2CDCD";
|
||||||
|
pink = "F5C2E7";
|
||||||
|
mauve = "CBA6F7";
|
||||||
|
red = "F38BA8";
|
||||||
|
maroon = "EBA0AC";
|
||||||
|
peach = "FAB387";
|
||||||
|
yellow = "F9E2AF";
|
||||||
|
green = "A6E3A1";
|
||||||
|
teal = "94E2D5";
|
||||||
|
sky = "89DCEB";
|
||||||
|
sapphire = "74C7EC";
|
||||||
|
blue = "89B4FA";
|
||||||
|
lavender = "B4BEFE";
|
||||||
|
|
||||||
|
text = "CDD6F4";
|
||||||
|
subtext1 = "BAC2DE";
|
||||||
|
subtext0 = "A6ADC8";
|
||||||
|
overlay2 = "9399B2";
|
||||||
|
overlay1 = "7F849C";
|
||||||
|
overlay0 = "6C7086";
|
||||||
|
|
||||||
|
surface2 = "585B70";
|
||||||
|
surface1 = "45475A";
|
||||||
|
surface0 = "313244";
|
||||||
|
|
||||||
|
base = "1E1E2E";
|
||||||
|
mantle = "181825";
|
||||||
|
crust = "11111B";
|
||||||
|
}
|
5
modules/home/themes/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
_:
|
||||||
|
|
||||||
|
{
|
||||||
|
_module.args.theme = import ./catppuccin.nix;
|
||||||
|
}
|
44
modules/os/cli/applications.nix
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.cli.applications;
|
||||||
|
in {
|
||||||
|
options.my.cli.applications = {
|
||||||
|
enable = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
environment = {
|
||||||
|
systemPackages = with pkgs; [
|
||||||
|
vim
|
||||||
|
wget
|
||||||
|
gnumake
|
||||||
|
findutils
|
||||||
|
psmisc
|
||||||
|
file
|
||||||
|
file-rename
|
||||||
|
moreutils
|
||||||
|
pciutils
|
||||||
|
rlwrap
|
||||||
|
unzip
|
||||||
|
unar
|
||||||
|
bat
|
||||||
|
fd
|
||||||
|
ripgrep
|
||||||
|
eza
|
||||||
|
];
|
||||||
|
|
||||||
|
sessionVariables = {
|
||||||
|
EDITOR = lib.mkDefault "ex";
|
||||||
|
VISUAL = lib.mkDefault "vim";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
git.enable = true;
|
||||||
|
htop.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
12
modules/os/cli/default.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
_:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./applications.nix
|
||||||
|
./fish.nix
|
||||||
|
./less.nix
|
||||||
|
./nix-index.nix
|
||||||
|
./sudo.nix
|
||||||
|
./tmux.nix
|
||||||
|
];
|
||||||
|
}
|
16
modules/os/cli/fish.nix
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.cli.fish;
|
||||||
|
in {
|
||||||
|
options.my.cli.fish = {
|
||||||
|
enable = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
users.defaultUserShell = pkgs.fish;
|
||||||
|
programs.fish.enable = true;
|
||||||
|
};
|
||||||
|
}
|
19
modules/os/cli/less.nix
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.cli.less;
|
||||||
|
in {
|
||||||
|
options.my.cli.less = {
|
||||||
|
enable = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs.less.enable = true;
|
||||||
|
environment.sessionVariables = {
|
||||||
|
MANPAGER = "less -R --use-color -Dd+r -Du+b";
|
||||||
|
MANROFFOPT = "-P -c";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
28
modules/os/cli/nix-index.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{ inputs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.cli.nix-index;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
inputs.nix-index-database.nixosModules.nix-index
|
||||||
|
];
|
||||||
|
|
||||||
|
options.my.cli.nix-index = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs = {
|
||||||
|
nix-index = {
|
||||||
|
enable = true;
|
||||||
|
enableBashIntegration = false;
|
||||||
|
enableFishIntegration = false;
|
||||||
|
enableZshIntegration = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
nix-index-database = {
|
||||||
|
comma.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
20
modules/os/cli/sudo.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.cli.sudo;
|
||||||
|
in {
|
||||||
|
options.my.cli.sudo = {
|
||||||
|
insults.enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkMerge [
|
||||||
|
(lib.mkIf cfg.insults.enable {
|
||||||
|
security.sudo = {
|
||||||
|
package = pkgs.sudo.override {withInsults = true;};
|
||||||
|
extraConfig = ''
|
||||||
|
Defaults insults
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
15
modules/os/cli/tmux.nix
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.cli.tmux;
|
||||||
|
in {
|
||||||
|
options.my.cli.tmux = {
|
||||||
|
enable = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
programs.tmux.enable = true;
|
||||||
|
};
|
||||||
|
}
|
23
modules/os/core/bootloader.nix
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.bootloader;
|
||||||
|
in {
|
||||||
|
options.my.bootloader = {
|
||||||
|
type = lib.mkOption {
|
||||||
|
type = with lib.types; nullOr (enum [ "systemdBoot" ]);
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
boot.loader = lib.mkIf (cfg.type != null) {
|
||||||
|
systemd-boot = lib.mkIf (cfg.type == "systemdBoot") {
|
||||||
|
enable = true;
|
||||||
|
editor = false;
|
||||||
|
};
|
||||||
|
efi.canTouchEfiVariables = true;
|
||||||
|
timeout = lib.mkDefault 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
14
modules/os/core/default.nix
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
_:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./shared
|
||||||
|
|
||||||
|
./fs
|
||||||
|
./networking
|
||||||
|
./bootloader.nix
|
||||||
|
./secure-boot.nix
|
||||||
|
./user.nix
|
||||||
|
./zram.nix
|
||||||
|
];
|
||||||
|
}
|
33
modules/os/core/fs/btrfs.nix
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.fs;
|
||||||
|
in {
|
||||||
|
config = lib.mkIf (cfg.type == "btrfs") {
|
||||||
|
fileSystems = builtins.mapAttrs (_: options: {
|
||||||
|
inherit (cfg) device;
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [ "noatime" "space_cache=v2" "compress=zstd:9" ]
|
||||||
|
++ options
|
||||||
|
++ lib.optional config.services.fstrim.enable "nodiscard";
|
||||||
|
}) ({
|
||||||
|
"/" = [ "subvol=root" ];
|
||||||
|
"/nix" = [ "subvol=nix" ];
|
||||||
|
"/home" = [ "subvol=home" ];
|
||||||
|
} // lib.optionalAttrs cfg.snapshots {
|
||||||
|
"/home/${config.my.user.username}/.cache" = [ "subvol=misc/cache" ];
|
||||||
|
"/home/${config.my.user.username}/no-snapshot" = [ "subvol=misc/other" ];
|
||||||
|
});
|
||||||
|
|
||||||
|
services = {
|
||||||
|
snapper = lib.mkIf cfg.snapshots {
|
||||||
|
configs.home = {
|
||||||
|
SUBVOLUME = "/home";
|
||||||
|
ALLOW_USERS = [ config.my.user.username ];
|
||||||
|
TIMELINE_CREATE = true;
|
||||||
|
TIMELINE_CLEANUP = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
42
modules/os/core/fs/default.nix
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.fs;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./btrfs.nix
|
||||||
|
./ext4.nix
|
||||||
|
./luks.nix
|
||||||
|
./ssd.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.my.fs = {
|
||||||
|
bootPartition = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
device = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
default = "/dev/disk/by-label/nixos";
|
||||||
|
};
|
||||||
|
snapshots = lib.mkEnableOption null;
|
||||||
|
swapPartition = lib.mkEnableOption null;
|
||||||
|
type = lib.mkOption {
|
||||||
|
type = with lib.types; nullOr (enum [ "btrfs" "ext4" ]);
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
fileSystems = lib.mkIf cfg.bootPartition {
|
||||||
|
"/boot" = {
|
||||||
|
device = "/dev/disk/by-label/BOOT";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "umask=0077" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = lib.mkIf cfg.swapPartition [
|
||||||
|
{device = "/dev/disk/by-label/swap";}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
15
modules/os/core/fs/ext4.nix
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.fs;
|
||||||
|
in {
|
||||||
|
config = lib.mkIf (cfg.type == "ext4") {
|
||||||
|
fileSystems = {
|
||||||
|
"/" = {
|
||||||
|
inherit (cfg) device;
|
||||||
|
fsType = "ext4";
|
||||||
|
options = [ "noatime" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
23
modules/os/core/fs/luks.nix
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.fs.luks;
|
||||||
|
in {
|
||||||
|
options.my.fs.luks = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
device = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
default = "/dev/disk/by-label/nixos-crypt";
|
||||||
|
};
|
||||||
|
name = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "nixos";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
my.fs.device = lib.mkDefault "/dev/mapper/${cfg.name}";
|
||||||
|
|
||||||
|
boot.initrd.luks.devices.${cfg.name} = {inherit (cfg) device;};
|
||||||
|
};
|
||||||
|
}
|
19
modules/os/core/fs/ssd.nix
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.fs.ssd;
|
||||||
|
in {
|
||||||
|
options.my.fs.ssd = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
enableLuksIntegration = lib.mkEnableOption null // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
boot.initrd.luks.devices.${config.my.fs.luks.name} = lib.mkIf cfg.enableLuksIntegration {
|
||||||
|
allowDiscards = true;
|
||||||
|
bypassWorkqueues = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
106
modules/os/core/networking/cloudflare-warp.nix
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.networking.warp;
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
my.networking.warp = {
|
||||||
|
enable = lib.mkEnableOption (lib.mdDoc "cloudflare-warp, a service that replaces the connection between your device and the Internet with a modern, optimized, protocol");
|
||||||
|
|
||||||
|
package = lib.mkOption {
|
||||||
|
type = lib.types.package;
|
||||||
|
default = pkgs.cloudflare-warp;
|
||||||
|
defaultText = lib.literalExpression "pkgs.cloudflare-warp";
|
||||||
|
description = lib.mdDoc "The package to use for Cloudflare Warp.";
|
||||||
|
};
|
||||||
|
|
||||||
|
user = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "warp";
|
||||||
|
description = lib.mdDoc "User account under which Cloudflare Warp runs.";
|
||||||
|
};
|
||||||
|
|
||||||
|
group = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "warp";
|
||||||
|
description = lib.mdDoc "Group under which Cloudflare Warp runs.";
|
||||||
|
};
|
||||||
|
|
||||||
|
certificate = lib.mkOption {
|
||||||
|
type = with lib.types; nullOr path;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Path to the Cloudflare root certificate. There is a download link in the docs [here](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/install-cloudflare-cert/).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
udpPort = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 2408;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The UDP port to open in the firewall. Warp uses port 2408 by default, but fallback ports can be used if that conflicts with another service. See the [firewall documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/firewall#warp-udp-ports) for the pre-configured available fallback ports.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
openFirewall = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Opens UDP port in the firewall. See `udpPort` configuration option, and [firewall documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/firewall#warp-udp-ports).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
|
security.pki = lib.mkIf (cfg.certificate != null) {
|
||||||
|
certificateFiles = [ cfg.certificate ];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||||
|
allowedUDPPorts = [ cfg.udpPort ];
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users = lib.mkIf (cfg.user == "warp") {
|
||||||
|
warp = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "warp";
|
||||||
|
description = "Cloudflare Warp user";
|
||||||
|
home = "/var/lib/cloudflare-warp";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
users.groups = lib.mkIf (cfg.group == "warp") {
|
||||||
|
warp = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
packages = [ cfg.package ];
|
||||||
|
services.warp-svc = {
|
||||||
|
after = [ "network-online.target" "systemd-resolved.service" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
StateDirectory = "cloudflare-warp";
|
||||||
|
User = "warp";
|
||||||
|
Umask = "0077";
|
||||||
|
# Hardening
|
||||||
|
LockPersonality = true;
|
||||||
|
PrivateMounts = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
# Leaving on strict activates warp on plus
|
||||||
|
ProtectSystem = "full";
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
26
modules/os/core/networking/default.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.networking;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./cloudflare-warp.nix
|
||||||
|
./eddie.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.my.networking = {
|
||||||
|
networkManager.enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.networkManager.enable {
|
||||||
|
networking.networkmanager = {
|
||||||
|
enable = true;
|
||||||
|
wifi = {
|
||||||
|
scanRandMacAddress = lib.mkDefault false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.NetworkManager-wait-online.enable = lib.mkDefault false;
|
||||||
|
my.user.extraGroups = [ "networkmanager" ];
|
||||||
|
};
|
||||||
|
}
|
64
modules/os/core/networking/eddie.nix
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
{ pkgs, config, lib, inputs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.networking.eddie;
|
||||||
|
in {
|
||||||
|
options.my.networking.eddie = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
package = lib.mkPackageOption inputs.my-nix-packages.packages.${pkgs.system} "eddie-ui" {};
|
||||||
|
allowedTCPPorts = lib.mkOption {
|
||||||
|
type = with lib.types; listOf port;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
allowedUDPPorts = lib.mkOption {
|
||||||
|
type = with lib.types; listOf port;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
boot.kernelModules = [ "tun" ];
|
||||||
|
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
|
networking.iproute2.enable = true;
|
||||||
|
|
||||||
|
networking.firewall = {
|
||||||
|
checkReversePath = "loose";
|
||||||
|
|
||||||
|
interfaces = rec {
|
||||||
|
tun0 = {inherit (cfg) allowedTCPPorts allowedUDPPorts;};
|
||||||
|
Eddie = tun0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.eddie-elevated = {
|
||||||
|
description = "Eddie Elevation";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network.target" "network-online.target" ];
|
||||||
|
after = [
|
||||||
|
"network-online.target"
|
||||||
|
"NetworkManager.service"
|
||||||
|
"systemd-resolved.service"
|
||||||
|
];
|
||||||
|
path = (with pkgs; [
|
||||||
|
iproute2
|
||||||
|
procps
|
||||||
|
kmod
|
||||||
|
mono
|
||||||
|
])
|
||||||
|
++ lib.optional config.services.nscd.enable
|
||||||
|
config.services.nscd.package
|
||||||
|
++ lib.optional config.networking.firewall.enable
|
||||||
|
(if config.networking.nftables.enable
|
||||||
|
then pkgs.nftables
|
||||||
|
else pkgs.iptables);
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${cfg.package}/lib/eddie-ui/eddie-cli-elevated mode=service";
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = 5;
|
||||||
|
TimeoutStopSec = 5;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
26
modules/os/core/secure-boot.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ pkgs, config, lib, inputs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.secure-boot;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
inputs.lanzaboote.nixosModules.lanzaboote
|
||||||
|
];
|
||||||
|
|
||||||
|
options.my.secure-boot = {
|
||||||
|
enable = lib.mkEnableOption null;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [ pkgs.sbctl ];
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
loader.systemd-boot.enable = lib.mkForce false;
|
||||||
|
|
||||||
|
lanzaboote = {
|
||||||
|
enable = true;
|
||||||
|
pkiBundle = "/etc/secureboot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|