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