Reformat all Nix files

This commit is contained in:
Geoffrey Frogeye 2024-12-15 00:29:51 +01:00
parent 9e0c1102a9
commit 355b63cf73
Signed by: geoffrey
GPG key ID: C72403E7F82E6AD8
81 changed files with 2293 additions and 1153 deletions

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
passwordFile = "/tmp/dotfiles_${config.frogeye.name}_password"; passwordFile = "/tmp/dotfiles_${config.frogeye.name}_password";
in in
@ -41,15 +46,24 @@ in
subvolumes = { subvolumes = {
"/nixos" = { "/nixos" = {
mountpoint = "/"; mountpoint = "/";
mountOptions = [ "compress=zstd" "noatime" ]; mountOptions = [
"compress=zstd"
"noatime"
];
}; };
"/home" = { "/home" = {
mountpoint = "/home"; mountpoint = "/home";
mountOptions = [ "compress=zstd" "relatime" ]; mountOptions = [
"compress=zstd"
"relatime"
];
}; };
"/nix" = { "/nix" = {
mountpoint = "/nix"; mountpoint = "/nix";
mountOptions = [ "compress=zstd" "noatime" ]; mountOptions = [
"compress=zstd"
"noatime"
];
}; };
# Maybe later # Maybe later
# "/swap" = { # "/swap" = {

View file

@ -1,2 +1,2 @@
{ pkgs, ... }: { pkgs, ... }:
pkgs.writers.writePython3Bin "update-local-flakes" {} (builtins.readFile ./update-local-flakes.py) pkgs.writers.writePython3Bin "update-local-flakes" { } (builtins.readFile ./update-local-flakes.py)

View file

@ -1,3 +1,3 @@
(self: super: { (self: super: {
update-local-flakes = super.callPackage ./. {}; update-local-flakes = super.callPackage ./. { };
}) })

View file

@ -1,8 +1,14 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
frogeye.name = "cranberry"; frogeye.name = "cranberry";
disko.devices.disk."${config.frogeye.name}".device = "/dev/disk/by-id/nvme-UMIS_RPJTJ128MEE1MWX_SS0L25188X3RC12121TP"; disko.devices.disk."${config.frogeye.name
}".device = "/dev/disk/by-id/nvme-UMIS_RPJTJ128MEE1MWX_SS0L25188X3RC12121TP";
}; };
imports = [ imports = [
../common/disko/single_uefi_btrfs.nix ../common/disko/single_uefi_btrfs.nix

View file

@ -1,9 +1,21 @@
{ pkgs, lib, config, nixos-hardware, ... }: {
pkgs,
lib,
config,
nixos-hardware,
...
}:
{ {
config = { config = {
boot = { boot = {
# From nixos-generate-config # From nixos-generate-config
initrd.availableKernelModules = [ "nvme" "xhci_pci" "usb_storage" "sd_mod" "sdhci_pci" ]; initrd.availableKernelModules = [
"nvme"
"xhci_pci"
"usb_storage"
"sd_mod"
"sdhci_pci"
];
kernelModules = [ "kvm-amd" ]; kernelModules = [ "kvm-amd" ];
}; };
@ -31,7 +43,9 @@
}; };
# Alt key swallowed the Meta one # Alt key swallowed the Meta one
home-manager.users.geoffrey = { ... }: { home-manager.users.geoffrey =
{ ... }:
{
xsession.windowManager.i3.config.modifier = "Mod1"; xsession.windowManager.i3.config.modifier = "Mod1";
}; };

View file

@ -2,13 +2,25 @@
# MANU Snapper is not able to create the snapshot directory, so you'll need to do this after eventually running the backup script: # MANU Snapper is not able to create the snapshot directory, so you'll need to do this after eventually running the backup script:
# sudo btrfs subvol create /mnt/razmo/$subvolume/.snapshots # sudo btrfs subvol create /mnt/razmo/$subvolume/.snapshots
let let
backup_subvolumes = [ "nixos" "home.rapido" "home.nixos" ]; backup_subvolumes = [
"nixos"
"home.rapido"
"home.nixos"
];
backup_app = pkgs.writeShellApplication { backup_app = pkgs.writeShellApplication {
name = "backup-subvolume"; name = "backup-subvolume";
runtimeInputs = with pkgs; [ coreutils btrfs-progs ]; runtimeInputs = with pkgs; [
coreutils
btrfs-progs
];
text = builtins.readFile ./backup.sh; text = builtins.readFile ./backup.sh;
}; };
snapper_subvolumes = [ "nixos" "home.rapido" "home.razmo" "home.nixos" ]; snapper_subvolumes = [
"nixos"
"home.rapido"
"home.razmo"
"home.nixos"
];
in in
{ {
services = services =
@ -39,9 +51,14 @@ in
}; };
in in
{ {
snapper.configs = lib.attrsets.mergeAttrsList (map (s: { "${s}" = default // { SUBVOLUME = "/mnt/razmo/${s}"; }; }) snapper_subvolumes); snapper.configs = lib.attrsets.mergeAttrsList (
map (s: {
"${s}" = default // {
SUBVOLUME = "/mnt/razmo/${s}";
};
}) snapper_subvolumes
);
}; };
systemd = { systemd = {
services.bkp_rapido = { services.bkp_rapido = {

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
zytemp_mqtt_src = pkgs.fetchFromGitHub { zytemp_mqtt_src = pkgs.fetchFromGitHub {
# owner = "patrislav1"; # owner = "patrislav1";
@ -7,11 +12,14 @@ let
rev = "push-nurpouorqoyr"; # Humidity + availability support rev = "push-nurpouorqoyr"; # Humidity + availability support
sha256 = "sha256-nOhyBAgvjeQh9ys3cBJOVR67SDs96zBzxIRGpaq4yoA="; sha256 = "sha256-nOhyBAgvjeQh9ys3cBJOVR67SDs96zBzxIRGpaq4yoA=";
}; };
zytemp_mqtt = pkgs.python3Packages.buildPythonPackage zytemp_mqtt = pkgs.python3Packages.buildPythonPackage rec {
rec {
name = "zytemp_mqtt"; name = "zytemp_mqtt";
src = zytemp_mqtt_src; src = zytemp_mqtt_src;
propagatedBuildInputs = with pkgs.python3Packages; [ hidapi paho-mqtt pyaml ]; propagatedBuildInputs = with pkgs.python3Packages; [
hidapi
paho-mqtt
pyaml
];
}; };
usb_zytemp_udev = pkgs.stdenv.mkDerivation { usb_zytemp_udev = pkgs.stdenv.mkDerivation {
pname = "usb-zytemp-udev-rules"; pname = "usb-zytemp-udev-rules";
@ -63,7 +71,11 @@ in
RestrictRealtime = true; RestrictRealtime = true;
RestrictSUIDSGID = true; RestrictSUIDSGID = true;
SystemCallArchitectures = "native"; SystemCallArchitectures = "native";
SystemCallFilter = [ "@system-service" "~@privileged" "~@resouces" ]; SystemCallFilter = [
"@system-service"
"~@privileged"
"~@resouces"
];
UMask = "0077"; UMask = "0077";
}; };
}; };

View file

@ -1,16 +1,27 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
services.beesd.filesystems = { services.beesd.filesystems = {
razmo = { razmo = {
spec = "/mnt/razmo"; spec = "/mnt/razmo";
hashTableSizeMB = 512; # Recommended for 1 TiB, ×2 for compression, x2 for time hashTableSizeMB = 512; # Recommended for 1 TiB, ×2 for compression, x2 for time
extraOptions = [ "--loadavg-target" "7.5" ]; extraOptions = [
"--loadavg-target"
"7.5"
];
}; };
rapido = { rapido = {
spec = "/mnt/rapido"; spec = "/mnt/rapido";
hashTableSizeMB = 128; # 4 times smaller disk, 4 times smaller hashtable? hashTableSizeMB = 128; # 4 times smaller disk, 4 times smaller hashtable?
extraOptions = [ "--loadavg-target" "5" ]; extraOptions = [
"--loadavg-target"
"5"
];
}; };
}; };
}; };

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
frogeye.name = "curacao"; frogeye.name = "curacao";

View file

@ -1,10 +1,16 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
desk_mqtt = pkgs.writers.writePython3 "desk_mqtt" desk_mqtt = pkgs.writers.writePython3 "desk_mqtt" {
{ libraries = with pkgs.python3Packages; [
libraries = with pkgs.python3Packages; [ pyusb ha-mqtt-discoverable ]; pyusb
} ha-mqtt-discoverable
(builtins.readFile ./desk_mqtt.py); ];
} (builtins.readFile ./desk_mqtt.py);
usb2lin06_udev = pkgs.writeTextFile { usb2lin06_udev = pkgs.writeTextFile {
name = "usb2lin06-udev-rules"; name = "usb2lin06-udev-rules";
text = '' text = ''
@ -44,7 +50,11 @@ in
RestrictRealtime = true; RestrictRealtime = true;
RestrictSUIDSGID = true; RestrictSUIDSGID = true;
SystemCallArchitectures = "native"; SystemCallArchitectures = "native";
SystemCallFilter = [ "@system-service" "~@privileged" "~@resouces" ]; SystemCallFilter = [
"@system-service"
"~@privileged"
"~@resouces"
];
UMask = "0077"; UMask = "0077";
}; };
}; };

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
# TODO Find a way to use keys in filesystem # TODO Find a way to use keys in filesystem
# TODO Not relatime everywhere, thank you # TODO Not relatime everywhere, thank you
# TODO Default options # TODO Default options
@ -62,11 +67,17 @@ in
subvolumes = { subvolumes = {
"home.razmo" = { "home.razmo" = {
mountpoint = "/home.heavy"; mountpoint = "/home.heavy";
mountOptions = [ "compress=zstd" "relatime" ]; mountOptions = [
"compress=zstd"
"relatime"
];
}; };
"steam" = { "steam" = {
mountpoint = "/opt/steam.razmo"; mountpoint = "/opt/steam.razmo";
mountOptions = [ "compress=zstd" "noatime" ]; mountOptions = [
"compress=zstd"
"noatime"
];
}; };
}; };
}; };
@ -145,7 +156,10 @@ in
}; };
services.btrfs.autoScrub = { services.btrfs.autoScrub = {
enable = true; enable = true;
fileSystems = [ "/mnt/razmo" "/mnt/rapido" ]; fileSystems = [
"/mnt/razmo"
"/mnt/rapido"
];
# TODO Should be generable from disko config, right? # TODO Should be generable from disko config, right?
}; };
} }

View file

@ -1,4 +1,9 @@
{ pkgs, lib, nixos-hardware, ... }: {
pkgs,
lib,
nixos-hardware,
...
}:
let let
displays = { displays = {
embedded = { embedded = {
@ -19,7 +24,14 @@ in
config = { config = {
boot = { boot = {
# From nixos-generate-config # From nixos-generate-config
initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "sd_mod" "rtsx_usb_sdmmc" ]; initrd.availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usbhid"
"sd_mod"
"rtsx_usb_sdmmc"
];
kernelModules = [ "kvm-intel" ]; kernelModules = [ "kvm-intel" ];
# UEFI works here, and variables can be touched # UEFI works here, and variables can be touched
@ -95,7 +107,10 @@ in
}; };
}; };
# Needs prefetched binary blobs, see https://nixos.wiki/wiki/Displaylink # Needs prefetched binary blobs, see https://nixos.wiki/wiki/Displaylink
xserver.videoDrivers = [ "displaylink" "modesetting" ]; xserver.videoDrivers = [
"displaylink"
"modesetting"
];
# TODO See if nvidia and DL can work together. # TODO See if nvidia and DL can work together.
}; };
}; };

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
networking = { networking = {

View file

@ -1,8 +1,14 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
boot.loader.efi.canTouchEfiVariables = false; boot.loader.efi.canTouchEfiVariables = false;
disko.devices.disk."${config.frogeye.name}".device = "/dev/disk/by-id/usb-Kingston_DataTraveler_3.0_E0D55EA57414F510489F0F1A-0:0"; disko.devices.disk."${config.frogeye.name
}".device = "/dev/disk/by-id/usb-Kingston_DataTraveler_3.0_E0D55EA57414F510489F0F1A-0:0";
frogeye.name = "curacao-usb"; frogeye.name = "curacao-usb";
}; };
imports = [ imports = [

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
# TODO This should install cameractrls, but it seems like it's not easy to install. # TODO This should install cameractrls, but it seems like it's not easy to install.

View file

@ -37,7 +37,15 @@
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
}; };
outputs = { self, nixpkgs, disko, nix-on-droid, flake-utils, ... }@attrs: outputs =
{
self,
nixpkgs,
disko,
nix-on-droid,
flake-utils,
...
}@attrs:
# Machine independant outputs # Machine independant outputs
let let
nixpkgsConfig = { nixpkgsConfig = {
@ -53,7 +61,12 @@
extraSpecialArgs = attrs; extraSpecialArgs = attrs;
}; };
lib = { lib = {
nixosSystem = { system, modules ? [ ] }: nixpkgs.lib.nixosSystem { nixosSystem =
{
system,
modules ? [ ],
}:
nixpkgs.lib.nixosSystem {
inherit system; inherit system;
specialArgs = attrs; specialArgs = attrs;
modules = modules ++ [ modules = modules ++ [
@ -61,14 +74,25 @@
{ {
nixpkgs = nixpkgsConfig; nixpkgs = nixpkgsConfig;
home-manager = homeManagerConfig; home-manager = homeManagerConfig;
frogeye.toplevel = { _type = "override"; content = self; priority = 1000; }; frogeye.toplevel = {
_type = "override";
content = self;
priority = 1000;
};
} }
]; ];
}; };
nixOnDroidConfiguration = { modules ? [ ] }: nix-on-droid.lib.nixOnDroidConfiguration { nixOnDroidConfiguration =
pkgs = import nixpkgs (nixpkgsConfig // { {
modules ? [ ],
}:
nix-on-droid.lib.nixOnDroidConfiguration {
pkgs = import nixpkgs (
nixpkgsConfig
// {
system = "aarch64-linux"; # nod doesn't support anything else system = "aarch64-linux"; # nod doesn't support anything else
}); }
);
modules = modules ++ [ modules = modules ++ [
self.nixOnDroidModules.dotfiles self.nixOnDroidModules.dotfiles
{ {
@ -76,17 +100,22 @@
} }
]; ];
}; };
flakeTools = { self }: flake-utils.lib.eachDefaultSystem (system: flakeTools =
{ self }:
flake-utils.lib.eachDefaultSystem (
system:
let let
pkgs = import nixpkgs pkgs = import nixpkgs (
(nixpkgsConfig // { nixpkgsConfig
// {
inherit system; inherit system;
# We do an overlay here so nixos-rebuild and other use lix. # We do an overlay here so nixos-rebuild and other use lix.
# We don't do an overlay for the whole system because lix is not binary compatible. # We don't do an overlay for the whole system because lix is not binary compatible.
overlays = [ overlays = [
(self: super: { nix = super.lix; }) (self: super: { nix = super.lix; })
]; ];
}); }
);
in in
{ {
apps = { apps = {
@ -115,11 +144,16 @@
}; };
nixosRebuild = { nixosRebuild = {
type = "app"; type = "app";
program = "${pkgs.writeShellScript "rebuild" ''${pkgs.writeShellApplication { program = "${pkgs.writeShellScript "rebuild" ''${
pkgs.writeShellApplication {
name = "rebuild"; name = "rebuild";
runtimeInputs = with pkgs; [ nix-output-monitor nixos-rebuild ]; runtimeInputs = with pkgs; [
nix-output-monitor
nixos-rebuild
];
text = builtins.readFile ./os/rebuild.sh; text = builtins.readFile ./os/rebuild.sh;
}}/bin/rebuild ${self} "$@"''}"; }
}/bin/rebuild ${self} "$@"''}";
}; };
}; };
formatter = pkgs.nixfmt-rfc-style; formatter = pkgs.nixfmt-rfc-style;
@ -165,5 +199,6 @@
modules = [ ./sprinkles/standin.nix ]; modules = [ ./sprinkles/standin.nix ];
}; };
# TODO devices/ or configs/ folders # TODO devices/ or configs/ folders
} // (lib.flakeTools { inherit self; }); }
// (lib.flakeTools { inherit self; });
} }

View file

@ -1,15 +1,25 @@
{ pkgs, config, lib, ... }: {
pkgs,
config,
lib,
...
}:
let let
mkUserJs = with lib; prefs: extraPrefs: '' mkUserJs =
with lib;
prefs: extraPrefs: ''
// Generated by Geoffrey's dotfiles. // Generated by Geoffrey's dotfiles.
${concatStrings (mapAttrsToList (name: value: '' ${concatStrings (
mapAttrsToList (name: value: ''
user_pref("${name}", ${builtins.toJSON value}); user_pref("${name}", ${builtins.toJSON value});
'') prefs)} '') prefs
)}
${extraPrefs} ${extraPrefs}
''; '';
toThunderbirdCalendar = account: toThunderbirdCalendar =
account:
let let
id = builtins.hashString "sha256" account.name; id = builtins.hashString "sha256" account.name;
thunderbird = config.frogeye.accounts.calendar.accounts.${account.name}; thunderbird = config.frogeye.accounts.calendar.accounts.${account.name};
@ -43,23 +53,27 @@ in
profiles.hm = { profiles.hm = {
isDefault = true; isDefault = true;
withExternalGnupg = true; withExternalGnupg = true;
extraConfig = mkUserJs extraConfig = mkUserJs (lib.attrsets.mergeAttrsList (
(lib.attrsets.mergeAttrsList (
# Add calendar config # Add calendar config
(lib.mapAttrsToList (name: account: (toThunderbirdCalendar account)) config.accounts.calendar.accounts) ++ (lib.mapAttrsToList (
name: account: (toThunderbirdCalendar account)
) config.accounts.calendar.accounts)
++
# Add config for every identity (kinda) # Add config for every identity (kinda)
(lib.mapAttrsToList (lib.mapAttrsToList (name: account: ({
(name: account: ({
# UPST Make signature be used in Thunderbird # UPST Make signature be used in Thunderbird
"mail.identity.id_${builtins.hashString "sha256" account.address}.htmlSigText" = account.signature.text; "mail.identity.id_${builtins.hashString "sha256" account.address}.htmlSigText" =
account.signature.text;
"mail.identity.id_${builtins.hashString "sha256" account.address}.compose_html" = false; "mail.identity.id_${builtins.hashString "sha256" account.address}.compose_html" = false;
})) })) config.accounts.email.accounts)
config.accounts.email.accounts) ++ ++
# General settings # General settings
[{ [
{
"mail.pane_config.dynamic" = 0; "mail.pane_config.dynamic" = 0;
"intl.date_time.pattern_override.date_short" = "yyyy-MM-dd"; "intl.date_time.pattern_override.date_short" = "yyyy-MM-dd";
}] }
]
)) ""; )) "";
}; };
@ -69,7 +83,10 @@ in
options = { options = {
frogeye.accounts.calendar.accounts = lib.mkOption { frogeye.accounts.calendar.accounts = lib.mkOption {
default = { }; default = { };
type = lib.types.attrsOf (lib.types.submodule ({ config, name, ... }: { type = lib.types.attrsOf (
lib.types.submodule (
{ config, name, ... }:
{
# TODO Set defaults as Thunderbird sets it # TODO Set defaults as Thunderbird sets it
options = { options = {
color = lib.mkOption { color = lib.mkOption {
@ -102,7 +119,9 @@ in
default = false; default = false;
}; };
}; };
})); }
)
);
}; };
}; };
} }

View file

@ -1,18 +1,36 @@
# Light theme during the day, dark theme during the night (not automatic) # Light theme during the day, dark theme during the night (not automatic)
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
phases = [ phases = [
{ command = "jour"; specialisation = null; } {
{ command = "crepuscule"; specialisation = "dark"; } command = "jour";
{ command = "nuit"; specialisation = "dark"; } specialisation = null;
}
{
command = "crepuscule";
specialisation = "dark";
}
{
command = "nuit";
specialisation = "dark";
}
]; ];
mod = config.xsession.windowManager.i3.config.modifier; mod = config.xsession.windowManager.i3.config.modifier;
in in
{ {
config = { config = {
home.packages = (map home.packages =
(phase: (pkgs.writeShellScriptBin phase.command '' (map (
switch="/nix/var/nix/profiles/system${lib.strings.optionalString (phase.specialisation != null) "/specialisation/${phase.specialisation}"}/bin/switch-to-configuration" phase:
(pkgs.writeShellScriptBin phase.command ''
switch="/nix/var/nix/profiles/system${
lib.strings.optionalString (phase.specialisation != null) "/specialisation/${phase.specialisation}"
}/bin/switch-to-configuration"
if [ -x "$switch" ] if [ -x "$switch" ]
then then
sudo "$switch" test & sudo "$switch" test &
@ -20,8 +38,9 @@ in
fi fi
${builtins.getAttr phase.command config.frogeye.desktop.phasesCommands} ${builtins.getAttr phase.command config.frogeye.desktop.phasesCommands}
wait wait
'')) '')
phases) ++ (with pkgs; [ ) phases)
++ (with pkgs; [
brightnessctl brightnessctl
]); ]);
xsession.windowManager.i3.config.keybindings = { xsession.windowManager.i3.config.keybindings = {

View file

@ -1,4 +1,10 @@
{ pkgs, config, lib, labellenixpkgs, ... }: {
pkgs,
config,
lib,
labellenixpkgs,
...
}:
let let
labellepkgs = import labellenixpkgs { inherit (pkgs) system; }; labellepkgs = import labellenixpkgs { inherit (pkgs) system; };
in in
@ -41,7 +47,6 @@ in
la = "lsd -la"; la = "lsd -la";
s = "sudo -s -E"; s = "sudo -s -E";
# Preference # Preference
wol = "wakeonlan"; # TODO Really, isn't wol better? Also wtf Arch aliases to pass because neither is installed anyways x) wol = "wakeonlan"; # TODO Really, isn't wol better? Also wtf Arch aliases to pass because neither is installed anyways x)
mutt = "neomutt"; mutt = "neomutt";
@ -73,13 +78,48 @@ in
}; };
colors = { colors = {
# Base16 only, so it reuses the current theme. # Base16 only, so it reuses the current theme.
date = { day-old = 4; hour-old = 6; older = 5; }; date = {
git-status = { conflicted = 14; default = 13; deleted = 1; ignored = 13; modified = 3; new-in-index = 2; new-in-workdir = 2; renamed = 4; typechange = 3; unmodified = 13; }; day-old = 4;
hour-old = 6;
older = 5;
};
git-status = {
conflicted = 14;
default = 13;
deleted = 1;
ignored = 13;
modified = 3;
new-in-index = 2;
new-in-workdir = 2;
renamed = 4;
typechange = 3;
unmodified = 13;
};
group = 6; group = 6;
inode = { invalid = 245; valid = 13; }; inode = {
links = { invalid = 9; valid = 14; }; invalid = 245;
permission = { acl = 6; context = 14; exec = 1; exec-sticky = 5; no-access = 245; octal = 6; read = 2; write = 3; }; valid = 13;
size = { large = 1; medium = 9; none = 11; small = 3; }; };
links = {
invalid = 9;
valid = 14;
};
permission = {
acl = 6;
context = 14;
exec = 1;
exec-sticky = 5;
no-access = 245;
octal = 6;
read = 2;
write = 3;
};
size = {
large = 1;
medium = 9;
none = 11;
small = 3;
};
tree-edge = 13; tree-edge = 13;
user = 2; user = 2;
}; };
@ -95,8 +135,13 @@ in
fzf = { fzf = {
enable = true; enable = true;
enableZshIntegration = true; enableZshIntegration = true;
defaultOptions = [ "--height 40%" "--layout=default" ]; defaultOptions = [
fileWidgetOptions = [ "--preview '[[ -d {} ]] && ${pkgs.coreutils}/bin/ls -l --color=always {} || [[ \$(${pkgs.file}/bin/file --mime {}) =~ binary ]] && ${pkgs.file}/bin/file --brief {} || (${pkgs.highlight}/bin/highlight -O ansi -l {} || coderay {} || rougify {} || ${pkgs.coreutils}/bin/cat {}) 2> /dev/null | head -500'" ]; "--height 40%"
"--layout=default"
];
fileWidgetOptions = [
"--preview '[[ -d {} ]] && ${pkgs.coreutils}/bin/ls -l --color=always {} || [[ \$(${pkgs.file}/bin/file --mime {}) =~ binary ]] && ${pkgs.file}/bin/file --brief {} || (${pkgs.highlight}/bin/highlight -O ansi -l {} || coderay {} || rougify {} || ${pkgs.coreutils}/bin/cat {}) 2> /dev/null | head -500'"
];
# TODO Above not working... not really used either? # TODO Above not working... not really used either?
# file and friends are not in PATH by default... so here we want aboslute paths, which means those won't get reloaded. Meh. # file and friends are not in PATH by default... so here we want aboslute paths, which means those won't get reloaded. Meh.
}; };

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
pactl = "exec ${pkgs.pulseaudio}/bin/pactl"; # TODO Use NixOS package if using NixOS pactl = "exec ${pkgs.pulseaudio}/bin/pactl"; # TODO Use NixOS package if using NixOS
mod = config.xsession.windowManager.i3.config.modifier; mod = config.xsession.windowManager.i3.config.modifier;
@ -27,8 +32,7 @@ in
text = ''cookie-file = .config/pulse/pulse-cookie''; text = ''cookie-file = .config/pulse/pulse-cookie'';
}; };
}; };
xsession.windowManager.i3.config.keybindings = xsession.windowManager.i3.config.keybindings = {
{
"XF86AudioRaiseVolume" = "${pactl} set-sink-mute @DEFAULT_SINK@ false; ${pactl} set-sink-volume @DEFAULT_SINK@ +5%"; "XF86AudioRaiseVolume" = "${pactl} set-sink-mute @DEFAULT_SINK@ false; ${pactl} set-sink-volume @DEFAULT_SINK@ +5%";
"XF86AudioLowerVolume" = "${pactl} set-sink-mute @DEFAULT_SINK@ false; ${pactl} set-sink-volume @DEFAULT_SINK@ -5%"; "XF86AudioLowerVolume" = "${pactl} set-sink-mute @DEFAULT_SINK@ false; ${pactl} set-sink-volume @DEFAULT_SINK@ -5%";
"XF86AudioMute" = "${pactl} set-sink-mute @DEFAULT_SINK@ true"; "XF86AudioMute" = "${pactl} set-sink-mute @DEFAULT_SINK@ true";

View file

@ -1,10 +1,30 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
builtin_configs = [ "off" "common" "clone-largest" "horizontal" "vertical" "horizontal-reverse" "vertical-reverse" ]; builtin_configs = [
autorandrmenu = { title, option, builtin ? false }: pkgs.writeShellScript "autorandrmenu" "off"
'' "common"
"clone-largest"
"horizontal"
"vertical"
"horizontal-reverse"
"vertical-reverse"
];
autorandrmenu =
{
title,
option,
builtin ? false,
}:
pkgs.writeShellScript "autorandrmenu" ''
shopt -s nullglob globstar shopt -s nullglob globstar
profiles="${if builtin then lib.strings.concatLines builtin_configs else ""}$(${pkgs.autorandr}/bin/autorandr | ${pkgs.gawk}/bin/awk '{ print $1 }')" profiles="${
if builtin then lib.strings.concatLines builtin_configs else ""
}$(${pkgs.autorandr}/bin/autorandr | ${pkgs.gawk}/bin/awk '{ print $1 }')"
profile="$(echo "$profiles" | ${config.programs.rofi.package}/bin/rofi -dmenu -p "${title}")" profile="$(echo "$profiles" | ${config.programs.rofi.package}/bin/rofi -dmenu -p "${title}")"
[[ -n "$profile" ]] || exit [[ -n "$profile" ]] || exit
${pkgs.autorandr}/bin/autorandr ${option} "$profile" ${pkgs.autorandr}/bin/autorandr ${option} "$profile"
@ -13,14 +33,35 @@ in
{ {
config = lib.mkIf config.frogeye.desktop.xorg { config = lib.mkIf config.frogeye.desktop.xorg {
frogeye.desktop.i3.bindmodes = { frogeye.desktop.i3.bindmodes = {
"Screen setup [A] Auto [L] Load [S] Save [R] Remove [D] Default" = "Screen setup [A] Auto [L] Load [S] Save [R] Remove [D] Default" = {
{
bindings = { bindings = {
"a" = "exec ${pkgs.autorandr}/bin/autorandr --change --force, mode default"; "a" = "exec ${pkgs.autorandr}/bin/autorandr --change --force, mode default";
"l" = "exec ${autorandrmenu {title="Load profile"; option="--load"; builtin = true;}}, mode default"; "l" = "exec ${
"s" = "exec ${autorandrmenu {title="Save profile"; option="--save";}}, mode default"; autorandrmenu {
"r" = "exec ${autorandrmenu {title="Remove profile"; option="--remove";}}, mode default"; title = "Load profile";
"d" = "exec ${autorandrmenu {title="Default profile"; option="--default"; builtin = true;}}, mode default"; option = "--load";
builtin = true;
}
}, mode default";
"s" = "exec ${
autorandrmenu {
title = "Save profile";
option = "--save";
}
}, mode default";
"r" = "exec ${
autorandrmenu {
title = "Remove profile";
option = "--remove";
}
}, mode default";
"d" = "exec ${
autorandrmenu {
title = "Default profile";
option = "--default";
builtin = true;
}
}, mode default";
}; };
mod_enter = "t"; mod_enter = "t";
}; };

View file

@ -1,4 +1,9 @@
{ pkgs, config, lib, ... }: {
pkgs,
config,
lib,
...
}:
{ {
config = { config = {
# This correctly sets the background on some occasions, below does the rest # This correctly sets the background on some occasions, below does the rest

View file

@ -1,4 +1,10 @@
{ pkgs, lib, config, nur, ... }: {
pkgs,
lib,
config,
nur,
...
}:
{ {
config = lib.mkIf config.frogeye.desktop.xorg { config = lib.mkIf config.frogeye.desktop.xorg {
home.sessionVariables = { home.sessionVariables = {
@ -14,8 +20,7 @@
}; };
profiles.hm = { profiles.hm = {
extensions = with config.nur.repos.rycee.firefox-addons; extensions = with config.nur.repos.rycee.firefox-addons; [
[
(buildFirefoxXpiAddon { (buildFirefoxXpiAddon {
pname = "onetab"; pname = "onetab";
@ -23,8 +28,7 @@
addonId = "onetab@nated"; addonId = "onetab@nated";
url = "https://addons.mozilla.org/firefox/downloads/file/4118712/one_tab_per_window-0.1.0.xpi"; url = "https://addons.mozilla.org/firefox/downloads/file/4118712/one_tab_per_window-0.1.0.xpi";
sha256 = "sha256-64DeL2xgXpqz32LJWDx4jhS2Fvbld8re3z8fdwnNTw0="; sha256 = "sha256-64DeL2xgXpqz32LJWDx4jhS2Fvbld8re3z8fdwnNTw0=";
meta = with lib; meta = with lib; {
{
homepage = "https://git.sr.ht/~nated/onetab"; homepage = "https://git.sr.ht/~nated/onetab";
description = "When a new tab is opened, redirects it to a new window instead."; description = "When a new tab is opened, redirects it to a new window instead.";
license = licenses.unfree; license = licenses.unfree;
@ -44,8 +48,14 @@
{ {
template = "https://search.nixos.org/packages"; template = "https://search.nixos.org/packages";
params = [ params = [
{ name = "type"; value = "packages"; } {
{ name = "query"; value = "{searchTerms}"; } name = "type";
value = "packages";
}
{
name = "query";
value = "{searchTerms}";
}
]; ];
} }
]; ];
@ -53,7 +63,7 @@
definedAliases = [ "@np" ]; definedAliases = [ "@np" ];
}; };
"NixOS Wiki" = { "NixOS Wiki" = {
urls = [{ template = "https://nixos.wiki/index.php?search={searchTerms}"; }]; urls = [ { template = "https://nixos.wiki/index.php?search={searchTerms}"; } ];
iconUpdateURL = "https://nixos.wiki/favicon.png"; iconUpdateURL = "https://nixos.wiki/favicon.png";
updateInterval = 24 * 60 * 60 * 1000; # every day updateInterval = 24 * 60 * 60 * 1000; # every day
definedAliases = [ "@nw" ]; definedAliases = [ "@nw" ];
@ -151,7 +161,14 @@
tls.certificate_errors = "ask-block-thirdparty"; tls.certificate_errors = "ask-block-thirdparty";
javascript.clipboard = "access"; # copy-paste is fine javascript.clipboard = "access"; # copy-paste is fine
}; };
editor.command = [ "${pkgs.neovide}/bin/neovide" "--" "-f" "{file}" "-c" "normal {line}G{column0}l" ]; editor.command = [
"${pkgs.neovide}/bin/neovide"
"--"
"-f"
"{file}"
"-c"
"normal {line}G{column0}l"
];
# TODO Doesn't work on Arch. Does it even load the right profile on Nix? # TODO Doesn't work on Arch. Does it even load the right profile on Nix?
# TODO spellcheck.languages = ["fr-FR" "en-GB" "en-US"]; # TODO spellcheck.languages = ["fr-FR" "en-GB" "en-US"];
}; };

View file

@ -1,4 +1,9 @@
{ pkgs, config, lib, ... }: {
pkgs,
config,
lib,
...
}:
{ {
imports = [ imports = [
./audio ./audio
@ -52,7 +57,10 @@
hwdec = "auto-safe"; hwdec = "auto-safe";
profile = "gpu-hq"; profile = "gpu-hq";
}; };
scripts = with pkgs.mpvScripts; [ thumbnail mpris ]; scripts = with pkgs.mpvScripts; [
thumbnail
mpris
];
scriptOpts = { scriptOpts = {
mpv_thumbnail_script = { mpv_thumbnail_script = {
autogenerate = false; # TODO It creates too many processes at once, crashing the system autogenerate = false; # TODO It creates too many processes at once, crashing the system
@ -66,27 +74,43 @@
xdg = { xdg = {
userDirs = userDirs =
let let
wellKnownUserDirs = [ "desktop" "documents" "download" "music" "pictures" "publicShare" "templates" "videos" ]; wellKnownUserDirs = [
wellKnownUserDirsNulled = builtins.listToAttrs (builtins.map (name: { inherit name; value = null; }) wellKnownUserDirs); "desktop"
"documents"
"download"
"music"
"pictures"
"publicShare"
"templates"
"videos"
];
wellKnownUserDirsNulled = builtins.listToAttrs (
builtins.map (name: {
inherit name;
value = null;
}) wellKnownUserDirs
);
allFolders = builtins.attrValues config.frogeye.folders; allFolders = builtins.attrValues config.frogeye.folders;
folders = builtins.filter (folder: folder.xdgUserDirVariable != null && folder.user == config.home.username) allFolders; folders = builtins.filter (
folder: folder.xdgUserDirVariable != null && folder.user == config.home.username
) allFolders;
in in
{ {
enable = true; enable = true;
createDirectories = true; createDirectories = true;
extraConfig = builtins.listToAttrs (builtins.map extraConfig = builtins.listToAttrs (
(folder: { builtins.map (folder: {
name = folder.xdgUserDirVariable; name = folder.xdgUserDirVariable;
value = "${config.home.homeDirectory}/${folder.path}"; value = "${config.home.homeDirectory}/${folder.path}";
}) }) folders
folders); );
} // wellKnownUserDirsNulled; # Don't use defaults dirs }
// wellKnownUserDirsNulled; # Don't use defaults dirs
}; };
services = { services = {
blueman-applet.enable = true; blueman-applet.enable = true;
unclutter.enable = true; unclutter.enable = true;
dunst = dunst = {
{
enable = true; enable = true;
settings = settings =
# TODO Change dmenu for rofi, so we can use context # TODO Change dmenu for rofi, so we can use context
@ -127,7 +151,9 @@
file = { file = {
".face" = { ".face" = {
# TODO Only works on pindakaas? See https://wiki.archlinux.org/title/LightDM#Changing_your_avatar # TODO Only works on pindakaas? See https://wiki.archlinux.org/title/LightDM#Changing_your_avatar
source = pkgs.runCommand "face.png" { } "${pkgs.inkscape}/bin/inkscape ${./face.svg} -w 1024 -o $out"; source =
pkgs.runCommand "face.png" { }
"${pkgs.inkscape}/bin/inkscape ${./face.svg} -w 1024 -o $out";
}; };
}; };
packages = with pkgs; [ packages = with pkgs; [

View file

@ -1,6 +1,13 @@
{ pkgs ? import <nixpkgs> { config = { }; overlays = [ ]; }, ... }: {
pkgs ? import <nixpkgs> {
config = { };
overlays = [ ];
},
...
}:
let let
lemonbar = (pkgs.lemonbar-xft.overrideAttrs (old: { lemonbar = (
pkgs.lemonbar-xft.overrideAttrs (old: {
src = pkgs.fetchFromGitHub { src = pkgs.fetchFromGitHub {
owner = "drscream"; owner = "drscream";
repo = "lemonbar-xft"; repo = "lemonbar-xft";
@ -8,10 +15,11 @@ let
sha256 = "sha256-T5FhEPIiDt/9paJwL9Sj84CBtA0YFi1hZz0+87Hd6jU="; sha256 = "sha256-T5FhEPIiDt/9paJwL9Sj84CBtA0YFi1hZz0+87Hd6jU=";
# https://github.com/drscream/lemonbar-xft/pull/2 # https://github.com/drscream/lemonbar-xft/pull/2
}; };
})); })
);
in in
# Tried using pyproject.nix but mpd2 dependency wouldn't resolve, # Tried using pyproject.nix but mpd2 dependency wouldn't resolve,
# is called pyton-mpd2 on PyPi but mpd2 in nixpkgs. # is called pyton-mpd2 on PyPi but mpd2 in nixpkgs.
pkgs.python3Packages.buildPythonApplication rec { pkgs.python3Packages.buildPythonApplication rec {
pname = "frobar"; pname = "frobar";
version = "2.0"; version = "2.0";
@ -25,7 +33,12 @@ pkgs.python3Packages.buildPythonApplication rec {
pulsectl pulsectl
pyinotify pyinotify
]; ];
nativeBuildInputs = [ lemonbar ] ++ (with pkgs; [ wirelesstools playerctl ]); nativeBuildInputs =
[ lemonbar ]
++ (with pkgs; [
wirelesstools
playerctl
]);
makeWrapperArgs = [ "--prefix PATH : ${pkgs.lib.makeBinPath nativeBuildInputs}" ]; makeWrapperArgs = [ "--prefix PATH : ${pkgs.lib.makeBinPath nativeBuildInputs}" ];
src = ./.; src = ./.;

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkIf config.frogeye.desktop.xorg { config = lib.mkIf config.frogeye.desktop.xorg {
xsession.windowManager.i3.config.bars = [ ]; xsession.windowManager.i3.config.bars = [ ];
@ -15,10 +20,12 @@
Service = { Service = {
# Wait for i3 to start. Can't use ExecStartPre because otherwise it blocks graphical-session.target, and there's nothing i3/systemd # Wait for i3 to start. Can't use ExecStartPre because otherwise it blocks graphical-session.target, and there's nothing i3/systemd
# TODO Do that better # TODO Do that better
ExecStart = ''${pkgs.bash}/bin/bash -c "while ! ${pkgs.i3}/bin/i3-msg; do ${pkgs.coreutils}/bin/sleep 1; done; ${pkgs.callPackage ./. {}}/bin/frobar"''; ExecStart = ''${pkgs.bash}/bin/bash -c "while ! ${pkgs.i3}/bin/i3-msg; do ${pkgs.coreutils}/bin/sleep 1; done; ${pkgs.callPackage ./. { }}/bin/frobar"'';
}; };
Install = { WantedBy = [ "graphical-session.target" ]; }; Install = {
WantedBy = [ "graphical-session.target" ];
};
}; };
}; };
} }

View file

@ -1,33 +1,59 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
# FOCUS # FOCUS
focus = "exec ${ pkgs.writeShellScript "i3-focus-window" '' focus = "exec ${pkgs.writeShellScript "i3-focus-window" ''
WINDOW=`${pkgs.xdotool}/bin/xdotool getwindowfocus` WINDOW=`${pkgs.xdotool}/bin/xdotool getwindowfocus`
eval `${pkgs.xdotool}/bin/xdotool getwindowgeometry --shell $WINDOW` # this brings in variables WIDTH and HEIGHT eval `${pkgs.xdotool}/bin/xdotool getwindowgeometry --shell $WINDOW` # this brings in variables WIDTH and HEIGHT
TX=`${pkgs.coreutils}/bin/expr $WIDTH / 2` TX=`${pkgs.coreutils}/bin/expr $WIDTH / 2`
TY=`${pkgs.coreutils}/bin/expr $HEIGHT / 2` TY=`${pkgs.coreutils}/bin/expr $HEIGHT / 2`
${pkgs.xdotool}/bin/xdotool mousemove -window $WINDOW $TX $TY ${pkgs.xdotool}/bin/xdotool mousemove -window $WINDOW $TX $TY
'' ''}";
}";
# CARDINALS # CARDINALS
cardinals = [ cardinals = [
{ vi = "h"; arrow = "Left"; container = "left"; workspace = "prev_on_output"; output = "left"; } {
{ vi = "l"; arrow = "Right"; container = "right"; workspace = "next_on_output"; output = "right"; } vi = "h";
{ vi = "j"; arrow = "Down"; container = "down"; workspace = "prev"; output = "below"; } arrow = "Left";
{ vi = "k"; arrow = "Up"; container = "up"; workspace = "next"; output = "above"; } container = "left";
workspace = "prev_on_output";
output = "left";
}
{
vi = "l";
arrow = "Right";
container = "right";
workspace = "next_on_output";
output = "right";
}
{
vi = "j";
arrow = "Down";
container = "down";
workspace = "prev";
output = "below";
}
{
vi = "k";
arrow = "Up";
container = "up";
workspace = "next";
output = "above";
}
]; ];
forEachCardinal = f: map (c: f c) cardinals; forEachCardinal = f: map (c: f c) cardinals;
# WORKSPACES # WORKSPACES
workspaces_keys = lib.strings.stringToCharacters "1234567890"; workspaces_keys = lib.strings.stringToCharacters "1234567890";
workspaces = map workspaces = map (i: {
(i: {
id = i; id = i;
name = builtins.toString (i + 1); name = builtins.toString (i + 1);
key = builtins.elemAt workspaces_keys i; key = builtins.elemAt workspaces_keys i;
}) }) (lib.lists.range 0 ((builtins.length workspaces_keys) - 1));
(lib.lists.range 0 ((builtins.length workspaces_keys) - 1));
forEachWorkspace = f: map (w: f w) workspaces; forEachWorkspace = f: map (w: f w) workspaces;
# MISC # MISC
@ -54,13 +80,47 @@ in
names = [ config.stylix.fonts.sansSerif.name ]; names = [ config.stylix.fonts.sansSerif.name ];
}; };
terminal = "alacritty"; terminal = "alacritty";
colors = let ignore = "#ff00ff"; in colors =
with config.lib.stylix.colors.withHashtag; lib.mkForce { let
focused = { border = base0B; background = base0B; text = base00; indicator = base00; childBorder = base0B; }; ignore = "#ff00ff";
focusedInactive = { border = base02; background = base02; text = base05; indicator = base02; childBorder = base02; }; in
unfocused = { border = base05; background = base04; text = base00; indicator = base04; childBorder = base00; }; with config.lib.stylix.colors.withHashtag;
urgent = { border = base0F; background = base08; text = base00; indicator = base08; childBorder = base0F; }; lib.mkForce {
placeholder = { border = ignore; background = base00; text = base05; indicator = ignore; childBorder = base00; }; focused = {
border = base0B;
background = base0B;
text = base00;
indicator = base00;
childBorder = base0B;
};
focusedInactive = {
border = base02;
background = base02;
text = base05;
indicator = base02;
childBorder = base02;
};
unfocused = {
border = base05;
background = base04;
text = base00;
indicator = base04;
childBorder = base00;
};
urgent = {
border = base0F;
background = base08;
text = base00;
indicator = base08;
childBorder = base0F;
};
placeholder = {
border = ignore;
background = base00;
text = base05;
indicator = ignore;
childBorder = base00;
};
background = base07; background = base07;
# I set the color of the active tab as the the background color of the terminal so they merge together. # I set the color of the active tab as the the background color of the terminal so they merge together.
}; };
@ -82,12 +142,10 @@ in
# Start Applications # Start Applications
"${mod}+p" = "exec ${pkgs.xfce.thunar}/bin/thunar"; "${mod}+p" = "exec ${pkgs.xfce.thunar}/bin/thunar";
# Misc # Misc
"${mod}+F10" = "exec ${ pkgs.writeShellScript "show-keyboard-layout" "${mod}+F10" = "exec ${pkgs.writeShellScript "show-keyboard-layout" ''
''
layout=`${pkgs.xorg.setxkbmap}/bin/setxkbmap -query | ${pkgs.gnugrep}/bin/grep ^layout: | ${pkgs.gawk}/bin/awk '{ print $2 }'` layout=`${pkgs.xorg.setxkbmap}/bin/setxkbmap -query | ${pkgs.gnugrep}/bin/grep ^layout: | ${pkgs.gawk}/bin/awk '{ print $2 }'`
${pkgs.libgnomekbd}/bin/gkbd-keyboard-display -l $layout ${pkgs.libgnomekbd}/bin/gkbd-keyboard-display -l $layout
'' ''}";
}";
# workspace back and forth (with/without active container) # workspace back and forth (with/without active container)
"${mod}+b" = "workspace back_and_forth; ${focus}"; "${mod}+b" = "workspace back_and_forth; ${focus}";
"${mod}+Shift+b" = "move container to workspace back_and_forth; workspace back_and_forth; ${focus}"; "${mod}+Shift+b" = "move container to workspace back_and_forth; workspace back_and_forth; ${focus}";
@ -107,8 +165,12 @@ in
"${mod}+Shift+c" = "reload"; "${mod}+Shift+c" = "reload";
"${mod}+Shift+r" = "restart"; "${mod}+Shift+r" = "restart";
"${mod}+Shift+e" = "exit"; "${mod}+Shift+e" = "exit";
} // lib.mapAttrs' (k: v: lib.nameValuePair v.enter "mode ${v.name}") (lib.filterAttrs (k: v: v.enter != null) modes) }
// lib.attrsets.mergeAttrsList (forEachCardinal (c: { // lib.mapAttrs' (k: v: lib.nameValuePair v.enter "mode ${v.name}") (
lib.filterAttrs (k: v: v.enter != null) modes
)
// lib.attrsets.mergeAttrsList (
forEachCardinal (c: {
# change focus # change focus
"${mod}+${c.vi}" = "focus ${c.container}; ${focus}"; "${mod}+${c.vi}" = "focus ${c.container}; ${focus}";
# move focused window # move focused window
@ -119,26 +181,39 @@ in
"${mod}+Ctrl+Shift+${c.vi}" = "move container to workspace ${c.workspace}; workspace ${c.workspace}; ${focus}"; "${mod}+Ctrl+Shift+${c.vi}" = "move container to workspace ${c.workspace}; workspace ${c.workspace}; ${focus}";
# move workspaces to screen (arrow keys) # move workspaces to screen (arrow keys)
"${mod}+Ctrl+Shift+${c.arrow}" = "move workspace to output ${c.output}; ${focus}"; "${mod}+Ctrl+Shift+${c.arrow}" = "move workspace to output ${c.output}; ${focus}";
})) // lib.attrsets.mergeAttrsList (forEachWorkspace (w: { })
)
// lib.attrsets.mergeAttrsList (
forEachWorkspace (w: {
# Switch to workspace # Switch to workspace
"${mod}+${w.key}" = "workspace ${w.name}; ${focus}"; "${mod}+${w.key}" = "workspace ${w.name}; ${focus}";
# move focused container to workspace # move focused container to workspace
"${mod}+ctrl+${w.key}" = "move container to workspace ${w.name}; ${focus}"; "${mod}+ctrl+${w.key}" = "move container to workspace ${w.name}; ${focus}";
# move to workspace with focused container # move to workspace with focused container
"${mod}+shift+${w.key}" = "move container to workspace ${w.name}; workspace ${w.name}; ${focus}"; "${mod}+shift+${w.key}" = "move container to workspace ${w.name}; workspace ${w.name}; ${focus}";
})); })
modes = lib.mapAttrs' );
(k: v: lib.nameValuePair v.name (v.bindings // lib.optionalAttrs v.return_bindings { modes = lib.mapAttrs' (
k: v:
lib.nameValuePair v.name (
v.bindings
// lib.optionalAttrs v.return_bindings {
"Return" = "mode default"; "Return" = "mode default";
"Escape" = "mode default"; "Escape" = "mode default";
})) }
modes; )
) modes;
window = { window = {
hideEdgeBorders = "both"; hideEdgeBorders = "both";
titlebar = false; # So that single-container screens are basically almost fullscreen titlebar = false; # So that single-container screens are basically almost fullscreen
commands = [ commands = [
# switch to workspace with urgent window automatically # switch to workspace with urgent window automatically
{ criteria = { urgent = "latest"; }; command = "focus"; } {
criteria = {
urgent = "latest";
};
command = "focus";
}
]; ];
}; };
floating = { floating = {
@ -150,19 +225,26 @@ in
startup = [ startup = [
{ {
notification = false; notification = false;
command = "${pkgs.writeShellApplication { command = "${
pkgs.writeShellApplication {
name = "batteryNotify"; name = "batteryNotify";
runtimeInputs = with pkgs; [coreutils libnotify]; runtimeInputs = with pkgs; [
coreutils
libnotify
];
text = builtins.readFile ./batteryNotify.sh; text = builtins.readFile ./batteryNotify.sh;
# TODO Use batsignal instead? # TODO Use batsignal instead?
# TODO Only on computers with battery # TODO Only on computers with battery
}}/bin/batteryNotify"; }
}/bin/batteryNotify";
} }
]; ];
workspaceLayout = "tabbed"; workspaceLayout = "tabbed";
focus.mouseWarping = true; # i3 only supports warping to workspace, hence ${focus} focus.mouseWarping = true; # i3 only supports warping to workspace, hence ${focus}
workspaceOutputAssign = workspaceOutputAssign = forEachWorkspace (w: {
forEachWorkspace (w: { output = builtins.elemAt x11_screens (lib.mod w.id (builtins.length x11_screens)); workspace = w.name; }); output = builtins.elemAt x11_screens (lib.mod w.id (builtins.length x11_screens));
workspace = w.name;
});
}; };
frogeye.desktop.i3.bindmodes = { frogeye.desktop.i3.bindmodes = {
"Resize" = { "Resize" = {
@ -190,7 +272,10 @@ in
options = { options = {
frogeye.desktop.i3.bindmodes = lib.mkOption { frogeye.desktop.i3.bindmodes = lib.mkOption {
default = { }; default = { };
type = lib.types.attrsOf (lib.types.submodule ({ config, name, ... }: { type = lib.types.attrsOf (
lib.types.submodule (
{ config, name, ... }:
{
options = { options = {
name = lib.mkOption { name = lib.mkOption {
type = lib.types.str; type = lib.types.str;
@ -212,7 +297,9 @@ in
default = true; default = true;
}; };
}; };
})); }
)
);
}; };
}; };
} }

View file

@ -1,8 +1,17 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
# lockColors = with config.lib.stylix.colors.withHashtag; { a = base00; b = base01; d = base00; }; # Black or White, depending on current theme # lockColors = with config.lib.stylix.colors.withHashtag; { a = base00; b = base01; d = base00; }; # Black or White, depending on current theme
# lockColors = with config.lib.stylix.colors.withHashtag; { a = base0A; b = base0B; d = base00; }; # Green + Yellow # lockColors = with config.lib.stylix.colors.withHashtag; { a = base0A; b = base0B; d = base00; }; # Green + Yellow
lockColors = { a = "#82a401"; b = "#466c01"; d = "#648901"; }; # Old lockColors = {
a = "#82a401";
b = "#466c01";
d = "#648901";
}; # Old
lockSvg = pkgs.writeText "lock.svg" '' lockSvg = pkgs.writeText "lock.svg" ''
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" height="50" width="50"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" height="50" width="50">
<path fill="${lockColors.a}" d="M0 50h50V0H0z"/> <path fill="${lockColors.a}" d="M0 50h50V0H0z"/>
@ -34,7 +43,9 @@ in
} }
trap revert SIGHUP SIGINT SIGTERM trap revert SIGHUP SIGINT SIGTERM
${pkgs.xorg.xset}/bin/xset dpms 5 5 5 ${pkgs.xorg.xset}/bin/xset dpms 5 5 5
${pkgs.i3lock}/bin/i3lock --nofork --color ${builtins.substring 1 6 lockColors.d} --image="$pattern" --tiling --ignore-empty-password ${pkgs.i3lock}/bin/i3lock --nofork --color ${
builtins.substring 1 6 lockColors.d
} --image="$pattern" --tiling --ignore-empty-password
revert revert
fi fi
''; '';
@ -61,10 +72,13 @@ in
}; };
startup = [ startup = [
# Stop screen after 10 minutes, 1 minutes after lock it # Stop screen after 10 minutes, 1 minutes after lock it
{ notification = false; command = "${pkgs.writeShellScript "xautolock-start" '' {
notification = false;
command = "${pkgs.writeShellScript "xautolock-start" ''
echo enabled > ${xautolockState} echo enabled > ${xautolockState}
${pkgs.xautolock}/bin/xautolock -time 10 -locker '${pkgs.xorg.xset}/bin/xset dpms force standby' -killtime 1 -killer xlock ${pkgs.xautolock}/bin/xautolock -time 10 -locker '${pkgs.xorg.xset}/bin/xset dpms force standby' -killtime 1 -killer xlock
''}"; } ''}";
}
# services.screen-locker.xautolock is hardcoded to use systemd for -locker (doesn't even work...) # services.screen-locker.xautolock is hardcoded to use systemd for -locker (doesn't even work...)
]; ];
}; };

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkIf config.frogeye.desktop.xorg { config = lib.mkIf config.frogeye.desktop.xorg {
home = { home = {
@ -53,8 +58,7 @@
}; };
}; };
}; };
xsession.windowManager.i3.config.keybindings = xsession.windowManager.i3.config.keybindings = {
{
"XF86AudioPrev" = "exec ${lib.getExe pkgs.playerctl} previous"; "XF86AudioPrev" = "exec ${lib.getExe pkgs.playerctl} previous";
"XF86AudioPlay" = "exec ${lib.getExe pkgs.playerctl} play-pause"; "XF86AudioPlay" = "exec ${lib.getExe pkgs.playerctl} play-pause";
"XF86AudioNext" = "exec ${lib.getExe pkgs.playerctl} next"; "XF86AudioNext" = "exec ${lib.getExe pkgs.playerctl} next";

View file

@ -2,7 +2,12 @@
# Not tested since Nix. # Not tested since Nix.
# Config mentions pdfpc, although the last thing I used was Impressive, even made patches to it. # Config mentions pdfpc, although the last thing I used was Impressive, even made patches to it.
# UPST Add Impressive to nixpkgs # UPST Add Impressive to nixpkgs
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
mode_pres_main = "Presentation (main display)"; mode_pres_main = "Presentation (main display)";
mode_pres_sec = "Presentation (secondary display)"; mode_pres_sec = "Presentation (secondary display)";
@ -31,8 +36,20 @@ in
}; };
xsession.windowManager.i3.config.window.commands = [ xsession.windowManager.i3.config.window.commands = [
# Open specific applications in floating mode # Open specific applications in floating mode
{ criteria = { title = "^pdfpc.*"; window_role = "presenter"; }; command = "move to output left, fullscreen"; } {
{ criteria = { title = "^pdfpc.*"; window_role = "presentation"; }; command = "move to output right, fullscreen"; } criteria = {
title = "^pdfpc.*";
window_role = "presenter";
};
command = "move to output left, fullscreen";
}
{
criteria = {
title = "^pdfpc.*";
window_role = "presentation";
};
command = "move to output right, fullscreen";
}
]; ];
}; };

View file

@ -1,8 +1,12 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
# UPST # UPST
sct = pkgs.sct.overrideAttrs sct = pkgs.sct.overrideAttrs (old: {
(old: {
patches = (old.patches or [ ]) ++ [ patches = (old.patches or [ ]) ++ [
./sct_aarch64.patch ./sct_aarch64.patch
]; ];

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
dir = config.xdg.userDirs.extraConfig.XDG_SCREENSHOTS_DIR; dir = config.xdg.userDirs.extraConfig.XDG_SCREENSHOTS_DIR;
scrot = "${pkgs.scrot}/bin/scrot --exec '${pkgs.coreutils}/bin/mv $f ${dir}/ && ${pkgs.optipng}/bin/optipng ${dir}/$f'"; scrot = "${pkgs.scrot}/bin/scrot --exec '${pkgs.coreutils}/bin/mv $f ${dir}/ && ${pkgs.optipng}/bin/optipng ${dir}/$f'";

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
mod = config.xsession.windowManager.i3.config.modifier; mod = config.xsession.windowManager.i3.config.modifier;
in in
@ -23,10 +28,28 @@ in
bell = { bell = {
animation = "EaseOutExpo"; animation = "EaseOutExpo";
color = "#000000"; color = "#000000";
command = { program = "${pkgs.sox}/bin/play"; args = [ "-n" "synth" "sine" "C5" "sine" "E4" "remix" "1-2" "fade" "0.1" "0.2" "0.1" ]; }; command = {
program = "${pkgs.sox}/bin/play";
args = [
"-n"
"synth"
"sine"
"C5"
"sine"
"E4"
"remix"
"1-2"
"fade"
"0.1"
"0.2"
"0.1"
];
};
duration = 100; duration = 100;
}; };
cursor = { vi_mode_style = "Underline"; }; cursor = {
vi_mode_style = "Underline";
};
env = { env = {
WINIT_X11_SCALE_FACTOR = "1"; WINIT_X11_SCALE_FACTOR = "1";
# Prevents Alacritty from resizing from one monitor to another. # Prevents Alacritty from resizing from one monitor to another.
@ -35,23 +58,68 @@ in
hints = { hints = {
enabled = [ enabled = [
{ {
binding = { mods = "Control|Alt"; key = "F"; }; binding = {
mods = "Control|Alt";
key = "F";
};
command = "${pkgs.xdg-utils}/bin/xdg-open"; command = "${pkgs.xdg-utils}/bin/xdg-open";
mouse = { enabled = true; mods = "Control"; }; mouse = {
enabled = true;
mods = "Control";
};
post_processing = true; post_processing = true;
regex = "(mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)[^\\u0000-\\u001F\\u007F-\\u009F<>\"\\\\s{-}\\\\^`]+"; regex = "(mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)[^\\u0000-\\u001F\\u007F-\\u009F<>\"\\\\s{-}\\\\^`]+";
} }
]; ];
}; };
keyboard.bindings = [ keyboard.bindings = [
{ mode = "~Search"; mods = "Alt|Control"; key = "Space"; action = "ToggleViMode"; } {
{ mode = "Vi|~Search"; mods = "Control"; key = "K"; action = "ScrollHalfPageUp"; } mode = "~Search";
{ mode = "Vi|~Search"; mods = "Control"; key = "J"; action = "ScrollHalfPageDown"; } mods = "Alt|Control";
{ mode = "~Vi"; mods = "Control|Alt"; key = "V"; action = "Paste"; } key = "Space";
{ mods = "Control|Alt"; key = "C"; action = "Copy"; } action = "ToggleViMode";
{ mode = "~Search"; mods = "Control|Alt"; key = "F"; action = "SearchForward"; } }
{ mode = "~Search"; mods = "Control|Alt"; key = "B"; action = "SearchBackward"; } {
{ mode = "Vi|~Search"; mods = "Control|Alt"; key = "C"; action = "ClearSelection"; } mode = "Vi|~Search";
mods = "Control";
key = "K";
action = "ScrollHalfPageUp";
}
{
mode = "Vi|~Search";
mods = "Control";
key = "J";
action = "ScrollHalfPageDown";
}
{
mode = "~Vi";
mods = "Control|Alt";
key = "V";
action = "Paste";
}
{
mods = "Control|Alt";
key = "C";
action = "Copy";
}
{
mode = "~Search";
mods = "Control|Alt";
key = "F";
action = "SearchForward";
}
{
mode = "~Search";
mods = "Control|Alt";
key = "B";
action = "SearchBackward";
}
{
mode = "Vi|~Search";
mods = "Control|Alt";
key = "C";
action = "ClearSelection";
}
]; ];
window = { window = {
dynamic_padding = false; dynamic_padding = false;

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkIf config.frogeye.dev.c { config = lib.mkIf config.frogeye.dev.c {
frogeye = { frogeye = {

View file

@ -1,9 +1,12 @@
{ pkgs, config, ... }: { { pkgs, config, ... }:
{
# TODO Maybe should be per-directory dotenv # TODO Maybe should be per-directory dotenv
# Or not, for neovim # Or not, for neovim
config = { config = {
# Always on # Always on
home.packages = with pkgs; [ home.packages =
with pkgs;
[
# Common # Common
perf-tools perf-tools
jq jq
@ -25,7 +28,8 @@
nixfmt-rfc-style nixfmt-rfc-style
# Always on (graphical) # Always on (graphical)
] ++ lib.optionals config.frogeye.desktop.xorg [ ]
++ lib.optionals config.frogeye.desktop.xorg [
# Common # Common
# zeal-qt6 # Offline documentation # zeal-qt6 # Offline documentation
sqlitebrowser sqlitebrowser
@ -34,29 +38,35 @@
wireshark-qt wireshark-qt
# Ansible # Ansible
] ++ lib.optionals config.frogeye.dev.ansible [ ]
++ lib.optionals config.frogeye.dev.ansible [
ansible ansible
ansible-lint ansible-lint
# Docker # Docker
] ++ lib.optionals config.frogeye.dev.docker [ ]
++ lib.optionals config.frogeye.dev.docker [
docker docker
docker-compose docker-compose
# FPGA # FPGA
] ++ lib.optionals config.frogeye.dev.fpga [ ]
++ lib.optionals config.frogeye.dev.fpga [
verilog verilog
] ++ lib.optionals (config.frogeye.dev.fpga && pkgs.stdenv.isx86_64) [ ]
++ lib.optionals (config.frogeye.dev.fpga && pkgs.stdenv.isx86_64) [
ghdl ghdl
# FPGA (graphical) # FPGA (graphical)
] ++ lib.optionals (config.frogeye.desktop.xorg && config.frogeye.dev.fpga) [ ]
++ lib.optionals (config.frogeye.desktop.xorg && config.frogeye.dev.fpga) [
yosys yosys
gtkwave gtkwave
# VM (graphical) # VM (graphical)
] ++ lib.optionals (config.frogeye.desktop.xorg && config.frogeye.dev.vm) [ ]
++ lib.optionals (config.frogeye.desktop.xorg && config.frogeye.dev.vm) [
virt-manager virt-manager
]; ];

View file

@ -1,4 +1,5 @@
{ pkgs, config, ... }: { { pkgs, config, ... }:
{
imports = [ imports = [
./c.nix ./c.nix
./common.nix ./common.nix

View file

@ -1,5 +1,10 @@
# Untested post-nix # Untested post-nix
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkIf config.frogeye.dev.go { config = lib.mkIf config.frogeye.dev.go {
frogeye = { frogeye = {

View file

@ -1,5 +1,10 @@
# Untested post-nix # Untested post-nix
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkIf config.frogeye.dev.node { config = lib.mkIf config.frogeye.dev.node {
frogeye = { frogeye = {

View file

@ -1,5 +1,10 @@
# Prose is a programming language, fight me # Prose is a programming language, fight me
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkIf config.frogeye.dev.prose { config = lib.mkIf config.frogeye.dev.prose {
home = { home = {
@ -15,9 +20,15 @@
programs.nixvim = { programs.nixvim = {
autoCmd = [ autoCmd = [
# vim-easy-align: Align Markdown tables with | # vim-easy-align: Align Markdown tables with |
{ event = "FileType"; pattern = "markdown"; command = "vmap <Bar> :EasyAlign*<Bar><Enter>"; } {
event = "FileType";
pattern = "markdown";
command = "vmap <Bar> :EasyAlign*<Bar><Enter>";
}
]; ];
extraPlugins = with pkgs.vimPlugins; lib.optionals config.programs.pandoc.enable [ extraPlugins =
with pkgs.vimPlugins;
lib.optionals config.programs.pandoc.enable [
vim-pandoc # Pandoc-specific stuff because there's no LSP for it vim-pandoc # Pandoc-specific stuff because there's no LSP for it
vim-pandoc-syntax vim-pandoc-syntax
]; ];

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkIf config.frogeye.dev.python { config = lib.mkIf config.frogeye.dev.python {
home = { home = {

View file

@ -1,4 +1,10 @@
{ pkgs, lib, config, onixpkgs, ... }: {
pkgs,
lib,
config,
onixpkgs,
...
}:
let let
opkgs = import onixpkgs { inherit (pkgs) system; }; opkgs = import onixpkgs { inherit (pkgs) system; };
in in
@ -18,7 +24,10 @@ in
}; };
}; };
}; };
home.packages = with pkgs; ([ home.packages =
with pkgs;
(
[
# android tools # android tools
android-tools android-tools
@ -44,7 +53,8 @@ in
haskellPackages.dice haskellPackages.dice
rustdesk-flutter rustdesk-flutter
] ++ lib.optionals config.frogeye.desktop.xorg [ ]
++ lib.optionals config.frogeye.desktop.xorg [
# multimedia editors # multimedia editors
darktable darktable
@ -56,16 +66,19 @@ in
# downloading # downloading
transmission_4-qt transmission_4-qt
# wine only makes sense on x86_64 # wine only makes sense on x86_64
] ++ lib.optionals pkgs.stdenv.isx86_64 [ ]
++ lib.optionals pkgs.stdenv.isx86_64 [
wine wine
# TODO wine-gecko wine-mono lib32-libpulse (?) # TODO wine-gecko wine-mono lib32-libpulse (?)
] ++ lib.optionals (!stdenv.isAarch64) [ ]
++ lib.optionals (!stdenv.isAarch64) [
# Musescore is broken on aarch64 # Musescore is broken on aarch64
musescore musescore
# Blender 4.0.1 can't compile on aarch64 # Blender 4.0.1 can't compile on aarch64
# https://hydra.nixos.org/job/nixos/release-23.11/nixpkgs.blender.aarch64-linux # https://hydra.nixos.org/job/nixos/release-23.11/nixpkgs.blender.aarch64-linux
blender blender
]); ]
);
}; };
} }

View file

@ -1,4 +1,6 @@
{ pkgs ? import <nixpkgs> { } }: {
pkgs ? import <nixpkgs> { },
}:
pkgs.python3Packages.buildPythonPackage { pkgs.python3Packages.buildPythonPackage {
pname = "whisperx"; pname = "whisperx";
version = "2024-08-19"; version = "2024-08-19";
@ -34,4 +36,3 @@ pkgs.python3Packages.buildPythonPackage {
"whisperx" "whisperx"
]; ];
} }

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkIf config.frogeye.gaming { config = lib.mkIf config.frogeye.gaming {
# Using config.nixpkgs.<something> creates an infinite recursion, # Using config.nixpkgs.<something> creates an infinite recursion,

View file

@ -1,16 +1,21 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
cfg = config.programs.git; cfg = config.programs.git;
in in
{ {
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
home.packages = [ home.packages = [
(pkgs.callPackage ./jjui.nix {}) (pkgs.callPackage ./jjui.nix { })
(pkgs.writeShellApplication { (pkgs.writeShellApplication {
name = "git-sync"; name = "git-sync";
text = (lib.strings.concatLines text = (
(map lib.strings.concatLines (
(r: '' map (r: ''
echo "===== ${r.path}" echo "===== ${r.path}"
if [ ! -d "${r.path}" ] if [ ! -d "${r.path}" ]
then then
@ -32,8 +37,7 @@ in
fi fi
) )
fi fi
'') '') (lib.attrsets.attrValues config.services.git-sync.repositories)
(lib.attrsets.attrValues config.services.git-sync.repositories)
) )
); );
}) })
@ -63,7 +67,8 @@ in
lfs.enable = true; lfs.enable = true;
userEmail = lib.mkDefault "geoffrey@frogeye.fr"; userEmail = lib.mkDefault "geoffrey@frogeye.fr";
userName = lib.mkDefault "Geoffrey Frogeye"; userName = lib.mkDefault "Geoffrey Frogeye";
extraConfig = { extraConfig =
{
core = { core = {
editor = "nvim"; editor = "nvim";
}; };
@ -73,7 +78,8 @@ in
pull = { pull = {
ff = "only"; ff = "only";
}; };
} // lib.optionalAttrs config.frogeye.desktop.xorg { }
// lib.optionalAttrs config.frogeye.desktop.xorg {
diff.tool = "meld"; diff.tool = "meld";
difftool.prompt = false; difftool.prompt = false;
"difftool \"meld\"".cmd = "${pkgs.meld}/bin/meld \"$LOCAL\" \"$REMOTE\""; "difftool \"meld\"".cmd = "${pkgs.meld}/bin/meld \"$LOCAL\" \"$REMOTE\"";

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkIf config.programs.gpg.enable { config = lib.mkIf config.programs.gpg.enable {
frogeye.hooks.lock = '' frogeye.hooks.lock = ''
@ -26,13 +31,15 @@
default-preference-list = "SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed"; default-preference-list = "SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed";
personal-cipher-preferences = "TWOFISH CAMELLIA256 AES 3DES"; personal-cipher-preferences = "TWOFISH CAMELLIA256 AES 3DES";
}; };
publicKeys = [{ publicKeys = [
{
source = builtins.fetchurl { source = builtins.fetchurl {
url = "https://keys.openpgp.org/vks/v1/by-fingerprint/4FBA930D314A03215E2CDB0A8312C8CAC1BAC289"; url = "https://keys.openpgp.org/vks/v1/by-fingerprint/4FBA930D314A03215E2CDB0A8312C8CAC1BAC289";
sha256 = "sha256:10y9xqcy1vyk2p8baay14p3vwdnlwynk0fvfbika65hz2z8yw2cm"; sha256 = "sha256:10y9xqcy1vyk2p8baay14p3vwdnlwynk0fvfbika65hz2z8yw2cm";
}; };
trust = "ultimate"; trust = "ultimate";
}]; }
];
}; };
services.gpg-agent = rec { services.gpg-agent = rec {
enableBashIntegration = true; enableBashIntegration = true;
@ -43,7 +50,7 @@
# It will fall back to ncurses when running in non-graphics mode. # It will fall back to ncurses when running in non-graphics mode.
defaultCacheTtl = 3600; defaultCacheTtl = 3600;
defaultCacheTtlSsh = defaultCacheTtl; defaultCacheTtlSsh = defaultCacheTtl;
maxCacheTtl = 3*3600; maxCacheTtl = 3 * 3600;
maxCacheTtlSsh = maxCacheTtl; maxCacheTtlSsh = maxCacheTtl;
}; };
}; };

View file

@ -25,14 +25,19 @@
]; ];
}; };
home = { home = {
activation.createDirenvFolders = lib.hm.dag.entryAfter [ "writeBoundary" ] activation.createDirenvFolders = lib.hm.dag.entryAfter [ "writeBoundary" ] (
(lib.strings.concatLines (map (d: "mkdir -p ${d}") ( lib.strings.concatLines (
map (d: "mkdir -p ${d}") (
(builtins.attrValues config.frogeye.direnv) ++ [ "${config.xdg.cacheHome}/junkhome" ] (builtins.attrValues config.frogeye.direnv) ++ [ "${config.xdg.cacheHome}/junkhome" ]
))); )
)
);
sessionVariables = config.frogeye.direnv; sessionVariables = config.frogeye.direnv;
}; };
programs.bash.shellAliases = lib.attrsets.mergeAttrsList (map (p: { "${p}" = "HOME=${config.xdg.cacheHome}/junkhome ${p}"; }) config.frogeye.junkhome); programs.bash.shellAliases = lib.attrsets.mergeAttrsList (
map (p: { "${p}" = "HOME=${config.xdg.cacheHome}/junkhome ${p}"; }) config.frogeye.junkhome
);
}; };
options.frogeye = { options.frogeye = {
direnv = lib.mkOption { direnv = lib.mkOption {

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
home.packages = with pkgs; [ home.packages = with pkgs; [

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
home.packages = with pkgs; [ home.packages = with pkgs; [
@ -16,7 +21,10 @@
nix = { nix = {
package = lib.mkDefault pkgs.lix; package = lib.mkDefault pkgs.lix;
settings = { settings = {
experimental-features = [ "nix-command" "flakes" ]; experimental-features = [
"nix-command"
"flakes"
];
warn-dirty = false; warn-dirty = false;
}; };
}; };

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
mod = config.xsession.windowManager.i3.config.modifier; mod = config.xsession.windowManager.i3.config.modifier;
in in
@ -8,32 +13,51 @@ in
pwgen pwgen
(pkgs.writeShellApplication { (pkgs.writeShellApplication {
name = "install-passwords"; name = "install-passwords";
runtimeInputs = [ yq gawk moreutils ]; runtimeInputs = [
text = (lib.strings.concatLines (map yq
(file: '' gawk
moreutils
];
text = (
lib.strings.concatLines (
map (
file:
''
( (
echo "===== Preparing to write ${file.path}" echo "===== Preparing to write ${file.path}"
temp="$(mktemp --tmpdir="${builtins.dirOf file.path}")" temp="$(mktemp --tmpdir="${builtins.dirOf file.path}")"
cat "${file.template}" > "$temp" cat "${file.template}" > "$temp"
'' + (lib.strings.concatLines (map ''
(password: (if password.selector == null then '' + (lib.strings.concatLines (
map (
password:
(
if password.selector == null then
''
echo "Reading ${password.path} for substituting ${password.variable}" echo "Reading ${password.path} for substituting ${password.variable}"
value="$(pass "${password.path}" | head -n1)" value="$(pass "${password.path}" | head -n1)"
'' else '' ''
else
''
echo "Reading ${password.path} -> ${password.selector} for substituting ${password.variable}" echo "Reading ${password.path} -> ${password.selector} for substituting ${password.variable}"
value="$(pass "${password.path}" | tail -n +2 | yq -r '.${password.selector}')" value="$(pass "${password.path}" | tail -n +2 | yq -r '.${password.selector}')"
'') + '' ''
)
+ ''
key="${password.variable}" key="${password.variable}"
K="$key" V="$value" awk '{ gsub (ENVIRON["K"], ENVIRON["V"]); print }' "$temp" | sponge "$temp" K="$key" V="$value" awk '{ gsub (ENVIRON["K"], ENVIRON["V"]); print }' "$temp" | sponge "$temp"
'') ''
(lib.attrsets.attrValues file.passwords))) + '' ) (lib.attrsets.attrValues file.passwords)
))
+ ''
echo "Moving the file in place" echo "Moving the file in place"
chown "${file.owner}" "$temp" chown "${file.owner}" "$temp"
chmod u=r "$temp" chmod u=r "$temp"
mv -f "$temp" "${file.path}" mv -f "$temp" "${file.path}"
) )
'') ''
config.frogeye.passwordFiles) ) config.frogeye.passwordFiles
)
); );
}) })
]; ];
@ -50,7 +74,9 @@ in
frogeye.passwordFiles = frogeye.passwordFiles =
let let
defaultvar = "@PASSWORD@"; defaultvar = "@PASSWORD@";
pwtype = { name, ... }: { pwtype =
{ name, ... }:
{
options = { options = {
variable = lib.mkOption { variable = lib.mkOption {
type = lib.types.str; type = lib.types.str;
@ -72,7 +98,10 @@ in
in in
lib.mkOption { lib.mkOption {
default = [ ]; default = [ ];
type = lib.types.listOf (lib.types.submodule ({ config, ... }: { type = lib.types.listOf (
lib.types.submodule (
{ config, ... }:
{
options = { options = {
path = lib.mkOption { path = lib.mkOption {
type = lib.types.str; type = lib.types.str;
@ -106,7 +135,9 @@ in
description = "Path to password that will substitute '@PASSWORD@' in the template. Exclusive with `passwords`."; description = "Path to password that will substitute '@PASSWORD@' in the template. Exclusive with `passwords`.";
}; };
}; };
})); }
)
);
}; };
}; };
} }

View file

@ -1,10 +1,27 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkIf config.programs.less.enable { config = lib.mkIf config.programs.less.enable {
programs.powerline-go = { programs.powerline-go = {
enable = true; enable = true;
modules = [ "user" "host" "venv" "cwd" "perms" "nix-shell" "git" ]; modules = [
modulesRight = [ "jobs" "exit" "duration" ]; "user"
"host"
"venv"
"cwd"
"perms"
"nix-shell"
"git"
];
modulesRight = [
"jobs"
"exit"
"duration"
];
settings = { settings = {
colorize-hostname = true; colorize-hostname = true;
hostname-only-if-ssh = true; hostname-only-if-ssh = true;

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
programs.atuin = { programs.atuin = {

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
cfg = config.programs.bash; cfg = config.programs.bash;
in in
@ -14,7 +19,11 @@ in
historySize = 100000; historySize = 100000;
historyFile = "${config.xdg.stateHome}/shell_history"; historyFile = "${config.xdg.stateHome}/shell_history";
historyFileSize = 100000; historyFileSize = 100000;
historyControl = [ "erasedups" "ignoredups" "ignorespace" ]; historyControl = [
"erasedups"
"ignoredups"
"ignorespace"
];
}; };
zsh = { zsh = {
enable = true; enable = true;

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
frogeye.hooks.lock = '' frogeye.hooks.lock = ''

View file

@ -1,4 +1,10 @@
{ pkgs, config, lib, stylix, ... }: {
pkgs,
config,
lib,
stylix,
...
}:
{ {
config = { config = {
stylix = { stylix = {

View file

@ -1,7 +1,11 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
themepack = pkgs.tmuxPlugins.mkTmuxPlugin themepack = pkgs.tmuxPlugins.mkTmuxPlugin rec {
rec {
pluginName = "tmux-themepack"; pluginName = "tmux-themepack";
version = "1.1.0"; version = "1.1.0";
rtpFilePath = "themepack.tmux"; rtpFilePath = "themepack.tmux";
@ -26,7 +30,9 @@ in
plugins = with pkgs.tmuxPlugins; [ plugins = with pkgs.tmuxPlugins; [
sensible sensible
]; ];
extraConfig = builtins.readFile ./tmux.conf + "source-file ${themepack}/share/tmux-plugins/tmux-themepack/powerline/default/green.tmuxtheme\n"; extraConfig =
builtins.readFile ./tmux.conf
+ "source-file ${themepack}/share/tmux-plugins/tmux-themepack/powerline/default/green.tmuxtheme\n";
}; };
stylix.targets.tmux.enable = false; stylix.targets.tmux.enable = false;
xdg.configFile.screenrc.text = (builtins.readFile ./screenrc); xdg.configFile.screenrc.text = (builtins.readFile ./screenrc);

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
# UPST # UPST
vim-shot-f = pkgs.vimUtils.buildVimPlugin { vim-shot-f = pkgs.vimUtils.buildVimPlugin {

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
# Completion # Completion

View file

@ -1,4 +1,10 @@
{ pkgs, lib, config, nixvimLib, ... }: {
pkgs,
lib,
config,
nixvimLib,
...
}:
let let
nv = nixvimLib.nixvim; nv = nixvimLib.nixvim;
in in
@ -6,37 +12,86 @@ in
config = { config = {
programs = { programs = {
# https://www.reddit.com/r/neovim/comments/mbj8m5/how_to_setup_ctrlshiftkey_mappings_in_neovim_and/ # https://www.reddit.com/r/neovim/comments/mbj8m5/how_to_setup_ctrlshiftkey_mappings_in_neovim_and/
alacritty.settings.keyboard.bindings = [ alacritty.settings.keyboard.bindings =
{ key = "H"; mods = "Control|Shift"; chars = "\\u001b[72;5u"; } [
{ key = "L"; mods = "Control|Shift"; chars = "\\u001b[76;5u"; } {
] ++ (map key = "H";
(n: { key = "Key${builtins.toString n}"; mods = "Control"; chars = "\\u001b[${builtins.toString (48+n)};5u"; }) mods = "Control|Shift";
(lib.lists.range 0 9)); chars = "\\u001b[72;5u";
}
{
key = "L";
mods = "Control|Shift";
chars = "\\u001b[76;5u";
}
]
++ (map (n: {
key = "Key${builtins.toString n}";
mods = "Control";
chars = "\\u001b[${builtins.toString (48 + n)};5u";
}) (lib.lists.range 0 9));
# Ctrl+<number> doesn't get interpreted, but Ctrl+Shift+<number> does, so let's use that # Ctrl+<number> doesn't get interpreted, but Ctrl+Shift+<number> does, so let's use that
nixvim = { nixvim = {
autoCmd = [ autoCmd = [
# Turn off relativenumber only for insert mode # Turn off relativenumber only for insert mode
{ event = "InsertEnter"; pattern = "*"; command = "set norelativenumber"; } {
{ event = "InsertLeave"; pattern = "*"; command = "set relativenumber"; } event = "InsertEnter";
pattern = "*";
command = "set norelativenumber";
}
{
event = "InsertLeave";
pattern = "*";
command = "set relativenumber";
}
]; ];
extraPlugins = with pkgs.vimPlugins; [ extraPlugins = with pkgs.vimPlugins; [
nvim-scrollview # Scroll bar nvim-scrollview # Scroll bar
]; ];
keymaps = keymaps =
let let
options = { silent = true; }; options = {
silent = true;
};
in in
[ [
# barbar # barbar
{ key = "gb"; action = "<Cmd>BufferPick<CR>"; inherit options; } {
{ key = "<C-H>"; action = "<Cmd>BufferPrevious<CR>"; inherit options; } key = "gb";
{ key = "<C-L>"; action = "<Cmd>BufferNext<CR>"; inherit options; } action = "<Cmd>BufferPick<CR>";
{ key = "<C-S-H>"; action = "<Cmd>BufferMovePrevious<CR>"; inherit options; } inherit options;
{ key = "<C-S-L>"; action = "<Cmd>BufferMoveNext<CR>"; inherit options; } }
{ key = "<C-0>"; action = "<Cmd>BufferLast<CR>"; inherit options; } {
] ++ (map key = "<C-H>";
(n: { key = "<C-${builtins.toString n}>"; action = "<Cmd>BufferGoto ${builtins.toString n}<CR>"; inherit options; }) action = "<Cmd>BufferPrevious<CR>";
(lib.lists.range 1 9)); inherit options;
}
{
key = "<C-L>";
action = "<Cmd>BufferNext<CR>";
inherit options;
}
{
key = "<C-S-H>";
action = "<Cmd>BufferMovePrevious<CR>";
inherit options;
}
{
key = "<C-S-L>";
action = "<Cmd>BufferMoveNext<CR>";
inherit options;
}
{
key = "<C-0>";
action = "<Cmd>BufferLast<CR>";
inherit options;
}
]
++ (map (n: {
key = "<C-${builtins.toString n}>";
action = "<Cmd>BufferGoto ${builtins.toString n}<CR>";
inherit options;
}) (lib.lists.range 1 9));
opts = { opts = {
showmode = false; showmode = false;
number = true; number = true;
@ -48,11 +103,25 @@ in
barbar.enable = true; barbar.enable = true;
# TODO Reload make it use the preset colorscheme # TODO Reload make it use the preset colorscheme
# Status line # Status line
lualine = with config.lib.stylix.colors.withHashtag; let lualine =
normal = { fg = base05; bg = base01; }; with config.lib.stylix.colors.withHashtag;
inverted = { fg = base00; bg = base03; }; let
normal_ina = { fg = base02; bg = base01; }; normal = {
inverted_ina = { fg = base00; bg = base02; }; fg = base05;
bg = base01;
};
inverted = {
fg = base00;
bg = base03;
};
normal_ina = {
fg = base02;
bg = base01;
};
inverted_ina = {
fg = base00;
bg = base02;
};
in in
{ {
enable = true; enable = true;
@ -64,7 +133,9 @@ in
]; ];
lualine_b = [ "mode" ]; lualine_b = [ "mode" ];
lualine_c = [ lualine_c = [
((nv.listToUnkeyedAttrs [ "filename" ]) // { (
(nv.listToUnkeyedAttrs [ "filename" ])
// {
color = nv.mkRaw '' color = nv.mkRaw ''
function(section) function(section)
return { fg = vim.bo.modified and '${base08}' or '${normal.fg}' } return { fg = vim.bo.modified and '${base08}' or '${normal.fg}' }
@ -77,28 +148,49 @@ in
readonly = "󰏯"; readonly = "󰏯";
unnamed = "󱀶"; unnamed = "󱀶";
}; };
}) }
)
"location" "location"
]; ];
lualine_x = [ lualine_x =
((nv.listToUnkeyedAttrs [ ''(next(vim.lsp.buf_get_clients()) == nil) and "󰒲 " or ""'' ]) // { [
separator = { left = ""; right = ""; }; (
}) (nv.listToUnkeyedAttrs [ ''(next(vim.lsp.buf_get_clients()) == nil) and "󰒲 " or ""'' ])
] ++ (lib.mapAttrsToList // {
(diag_name: diag_color: ((nv.listToUnkeyedAttrs [ "diagnostics" ]) // { separator = {
left = "";
right = "";
};
}
)
]
++ (lib.mapAttrsToList
(
diag_name: diag_color:
(
(nv.listToUnkeyedAttrs [ "diagnostics" ])
// {
color.bg = diag_color; color.bg = diag_color;
colored = false; colored = false;
separator = { left = ""; right = ""; }; separator = {
left = "";
right = "";
};
sections = [ diag_name ]; sections = [ diag_name ];
})) }
)
)
{ {
error = base08; error = base08;
warn = base0A; warn = base0A;
hint = base0C; hint = base0C;
info = base0B; info = base0B;
}); }
);
lualine_y = [ lualine_y = [
((nv.listToUnkeyedAttrs [ "diff" ]) // { (
(nv.listToUnkeyedAttrs [ "diff" ])
// {
diff_color = { diff_color = {
added.fg = base0B; added.fg = base0B;
modified.fg = base0A; modified.fg = base0A;
@ -109,7 +201,8 @@ in
modified = " "; modified = " ";
removed = " "; removed = " ";
}; };
}) }
)
"branch" "branch"
]; ];
lualine_z = [ lualine_z = [
@ -118,14 +211,20 @@ in
"encoding" "encoding"
]; ];
}; };
options.theme = (lib.mapAttrs options.theme =
(lib.mapAttrs
(mode_name: mode_color: { (mode_name: mode_color: {
a = inverted; a = inverted;
b = inverted // { bg = mode_color; gui = "bold"; }; b = inverted // {
bg = mode_color;
gui = "bold";
};
c = normal; c = normal;
x = inverted; x = inverted;
y = normal; y = normal;
z = inverted // { bg = mode_color; }; z = inverted // {
bg = mode_color;
};
}) })
{ {
normal = base0D; normal = base0D;
@ -133,14 +232,21 @@ in
visual = base0F; visual = base0F;
replace = base08; replace = base08;
command = base0E; command = base0E;
}) // { }
)
// {
inactive = { inactive = {
a = inverted_ina; a = inverted_ina;
b = normal_ina // { bg = base00; gui = "bold"; }; b = normal_ina // {
bg = base00;
gui = "bold";
};
c = normal_ina; c = normal_ina;
x = inverted_ina; x = inverted_ina;
y = normal_ina; y = normal_ina;
z = normal_ina // { bg = base00; }; z = normal_ina // {
bg = base00;
};
}; };
}; };
}; };

View file

@ -1,10 +1,18 @@
{ pkgs, lib, config, nixvim, ... }: {
pkgs,
lib,
config,
nixvim,
...
}:
{ {
# config = lib.mkIf config.programs.nixvim.enable { # Somehow this is infinite recursion? # config = lib.mkIf config.programs.nixvim.enable { # Somehow this is infinite recursion?
config = { config = {
home.sessionVariables = { home.sessionVariables =
{
EDITOR = "nvim"; EDITOR = "nvim";
} // lib.optionalAttrs config.frogeye.desktop.xorg { }
// lib.optionalAttrs config.frogeye.desktop.xorg {
VISUAL = "nvim"; VISUAL = "nvim";
}; };
programs.bash.shellAliases = { programs.bash.shellAliases = {
@ -84,7 +92,9 @@
undotree.enable = true; # Navigate edition history undotree.enable = true; # Navigate edition history
}; };
extraPlugins = with pkgs.vimPlugins; [ extraPlugins =
with pkgs.vimPlugins;
[
# Search/replace # Search/replace
vim-abolish # Regex for words, with case in mind vim-abolish # Regex for words, with case in mind
vim-easy-align # Aligning lines around a certain character vim-easy-align # Aligning lines around a certain character
@ -94,7 +104,8 @@
# Language-specific # Language-specific
tcomment_vim # Language-aware (un)commenting tcomment_vim # Language-aware (un)commenting
] ++ lib.optionals config.frogeye.dev.ansible [ ]
++ lib.optionals config.frogeye.dev.ansible [
ansible-vim ansible-vim
# Doesn't generate snippets, but those are for UltiSnip anyways # Doesn't generate snippets, but those are for UltiSnip anyways
]; ];
@ -110,7 +121,9 @@
''; '';
userCommands = { userCommands = {
Reload = { command = "source ${config.xdg.configHome}/nvim/init.lua"; }; Reload = {
command = "source ${config.xdg.configHome}/nvim/init.lua";
};
}; };
keymaps = [ keymaps = [
@ -118,24 +131,54 @@
# Allow saving of files as sudo when I forgot to start vim using sudo. # Allow saving of files as sudo when I forgot to start vim using sudo.
# From https://stackoverflow.com/a/7078429 # From https://stackoverflow.com/a/7078429
{ mode = "c"; key = "w!!"; action = "w !sudo tee > /dev/null %"; } {
mode = "c";
key = "w!!";
action = "w !sudo tee > /dev/null %";
}
{ mode = "i"; key = "jk"; action = "<Esc>"; } {
{ mode = "v"; key = "<Enter>"; action = "<Esc>"; } mode = "i";
{ key = "<Enter>"; action = "o<Esc>"; } key = "jk";
action = "<Esc>";
}
{
mode = "v";
key = "<Enter>";
action = "<Esc>";
}
{
key = "<Enter>";
action = "o<Esc>";
}
# { key = "<C-H>"; action = ":bp<CR>"; } # { key = "<C-H>"; action = ":bp<CR>"; }
# { key = "<C-L>"; action = ":bn<CR>"; } # { key = "<C-L>"; action = ":bn<CR>"; }
{ key = "<C-K>"; action = "kkkkkkkkkkkkkkkkkkkkk"; } {
{ key = "<C-J>"; action = "jjjjjjjjjjjjjjjjjjjjj"; } key = "<C-K>";
action = "kkkkkkkkkkkkkkkkkkkkk";
}
{
key = "<C-J>";
action = "jjjjjjjjjjjjjjjjjjjjj";
}
# \s to replace globally the word under the cursor # \s to replace globally the word under the cursor
{ key = "<Leader>s"; action = ":%s/\\<<C-r><C-w>\\>/"; } {
key = "<Leader>s";
action = ":%s/\\<<C-r><C-w>\\>/";
}
# PLUGINS # PLUGINS
# undotree # undotree
{ key = "<Space>u"; action = "<Cmd>UndotreeToggle<CR>"; options = { silent = true; }; } {
key = "<Space>u";
action = "<Cmd>UndotreeToggle<CR>";
options = {
silent = true;
};
}
]; ];
}; };

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
programs.nixvim = { programs.nixvim = {

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
programs.nixvim = { programs.nixvim = {

View file

@ -3,7 +3,9 @@
environment.motd = ""; environment.motd = "";
home-manager = { home-manager = {
useGlobalPkgs = true; useGlobalPkgs = true;
config = {...}: { config =
{ ... }:
{
frogeye = config.frogeye; frogeye = config.frogeye;
home.file = { home.file = {
".ssh/authorized_keys" = { ".ssh/authorized_keys" = {
@ -17,6 +19,7 @@
terminal.font = "${ terminal.font = "${
pkgs.nerdfonts.override { pkgs.nerdfonts.override {
fonts = [ "DejaVuSansMono" ]; fonts = [ "DejaVuSansMono" ];
}}/share/fonts/truetype/NerdFonts/DejaVuSansMNerdFont-Regular.ttf"; }
}/share/fonts/truetype/NerdFonts/DejaVuSansMNerdFont-Regular.ttf";
time.timeZone = "Europe/Amsterdam"; time.timeZone = "Europe/Amsterdam";
} }

View file

@ -1,6 +1,14 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
capitalizeFirstLetter = str: (lib.strings.toUpper (builtins.substring 0 1 str)) + (builtins.substring 1 (builtins.stringLength str) str); capitalizeFirstLetter =
str:
(lib.strings.toUpper (builtins.substring 0 1 str))
+ (builtins.substring 1 (builtins.stringLength str) str);
in in
{ {
options.frogeye = { options.frogeye = {
@ -18,7 +26,10 @@ in
polarity = lib.mkOption { polarity = lib.mkOption {
default = "light"; default = "light";
description = "Whether to use light theme or dark theme."; description = "Whether to use light theme or dark theme.";
type = lib.types.enum [ "light" "dark" ]; type = lib.types.enum [
"light"
"dark"
];
}; };
desktop = { desktop = {
xorg = lib.mkEnableOption "Enable X11 support"; xorg = lib.mkEnableOption "Enable X11 support";
@ -35,9 +46,21 @@ in
default = 1080; default = 1080;
}; };
phasesCommands = { phasesCommands = {
jour = lib.mkOption { type = lib.types.lines; default = ""; description = "Command to execute for phase: jour"; }; jour = lib.mkOption {
crepuscule = lib.mkOption { type = lib.types.lines; default = ""; description = "Command to execute for phase: crepuscule"; }; type = lib.types.lines;
nuit = lib.mkOption { type = lib.types.lines; default = ""; description = "Command to execute for phase: nuit"; }; default = "";
description = "Command to execute for phase: jour";
};
crepuscule = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Command to execute for phase: crepuscule";
};
nuit = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Command to execute for phase: nuit";
};
}; };
}; };
dev = { dev = {
@ -55,14 +78,21 @@ in
}; };
storageSize = lib.mkOption { storageSize = lib.mkOption {
default = "small"; default = "small";
type = lib.types.enum [ "small" "big" "phone" ]; type = lib.types.enum [
"small"
"big"
"phone"
];
description = "Type of storage for the device. Used to determine which folder to include."; description = "Type of storage for the device. Used to determine which folder to include.";
}; };
folders = lib.mkOption { folders = lib.mkOption {
default = { }; default = { };
description = "Folders used by users"; description = "Folders used by users";
# Top-level so Syncthing can work for all users. Also there's no real home-manager syncthing module. # Top-level so Syncthing can work for all users. Also there's no real home-manager syncthing module.
type = lib.types.attrsOf (lib.types.submodule ({ config, name, ... }: { type = lib.types.attrsOf (
lib.types.submodule (
{ config, name, ... }:
{
options = { options = {
name = lib.mkOption { name = lib.mkOption {
type = lib.types.str; type = lib.types.str;
@ -104,7 +134,9 @@ in
syncthing = lib.mkOption { syncthing = lib.mkOption {
default = { }; default = { };
description = "Syncthing configuration for the folder"; description = "Syncthing configuration for the folder";
type = lib.types.submodule ({ ... }: { type = lib.types.submodule (
{ ... }:
{
freeformType = (pkgs.formats.json { }).type; freeformType = (pkgs.formats.json { }).type;
options = { options = {
enable = lib.mkOption { enable = lib.mkOption {
@ -118,7 +150,8 @@ in
description = "Syncthing folder id"; description = "Syncthing folder id";
}; };
}; };
}); }
);
}; };
versionsMaxDays = lib.mkOption { versionsMaxDays = lib.mkOption {
type = lib.types.nullOr lib.types.int; type = lib.types.nullOr lib.types.int;
@ -126,7 +159,9 @@ in
description = "For big systems, how many days of staggered versions should be kept"; description = "For big systems, how many days of staggered versions should be kept";
}; };
}; };
})); }
)
);
}; };
hooks.lock = lib.mkOption { hooks.lock = lib.mkOption {
type = lib.types.lines; type = lib.types.lines;

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
boot.loader = { boot.loader = {
grub = { grub = {
@ -10,4 +15,3 @@
}; };
} }

View file

@ -6,10 +6,12 @@
eap=TTLS eap=TTLS
identity="37C3" identity="37C3"
password="37C3" password="37C3"
ca_cert="${builtins.fetchurl { ca_cert="${
builtins.fetchurl {
url = "https://letsencrypt.org/certs/isrgrootx1.pem"; url = "https://letsencrypt.org/certs/isrgrootx1.pem";
sha256 = "sha256:1la36n2f31j9s03v847ig6ny9lr875q3g7smnq33dcsmf2i5gd92"; sha256 = "sha256:1la36n2f31j9s03v847ig6ny9lr875q3g7smnq33dcsmf2i5gd92";
}}" }
}"
altsubject_match="DNS:radius.c3noc.net" altsubject_match="DNS:radius.c3noc.net"
phase2="auth=PAP" phase2="auth=PAP"
''; '';

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
networking = { networking = {
hostName = config.frogeye.name; hostName = config.frogeye.name;
@ -16,13 +21,17 @@
# Enable passwordless sudo # Enable passwordless sudo
# TODO execWheelOnly? sudo-rs? # TODO execWheelOnly? sudo-rs?
security.sudo.extraRules = [{ security.sudo.extraRules = [
{
groups = [ "wheel" ]; groups = [ "wheel" ];
commands = [{ commands = [
{
command = "ALL"; command = "ALL";
options = [ "NOPASSWD" ]; options = [ "NOPASSWD" ];
}]; }
}]; ];
}
];
# UPST disko --root-mountpoint doesn't work when using flake, workaround: # UPST disko --root-mountpoint doesn't work when using flake, workaround:
disko.rootMountPoint = "/mnt/nixos"; disko.rootMountPoint = "/mnt/nixos";
@ -44,7 +53,10 @@
nix = { nix = {
package = pkgs.lix; package = pkgs.lix;
settings = { settings = {
experimental-features = [ "nix-command" "flakes" ]; experimental-features = [
"nix-command"
"flakes"
];
warn-dirty = false; warn-dirty = false;
}; };
}; };

View file

@ -1,5 +1,11 @@
# Need nvidia proprietary drivers to work # Need nvidia proprietary drivers to work
{ pkgs, nixpkgs, config, lib, ... }: {
pkgs,
nixpkgs,
config,
lib,
...
}:
{ {
config = lib.mkIf config.frogeye.cuda { config = lib.mkIf config.frogeye.cuda {
nix.settings = { nix.settings = {
@ -11,7 +17,8 @@
]; ];
}; };
nixpkgs.overlays = [ nixpkgs.overlays = [
(self: super: (
self: super:
let let
pkgs_uf = import nixpkgs { pkgs_uf = import nixpkgs {
inherit (super) system; inherit (super) system;
@ -19,11 +26,14 @@
}; };
in in
{ {
ctranslate2 = (pkgs_uf.ctranslate2.override { ctranslate2 = (
pkgs_uf.ctranslate2.override {
withCUDA = true; withCUDA = true;
withCuDNN = true; withCuDNN = true;
}); }
}) );
}
)
]; ];
}; };
} }

View file

@ -1,12 +1,19 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
setupScript = "${pkgs.writeShellApplication { setupScript = "${
pkgs.writeShellApplication {
name = "greeter-setup-script"; name = "greeter-setup-script";
runtimeInputs = [ pkgs.autorandr ]; runtimeInputs = [ pkgs.autorandr ];
text = '' text = ''
autorandr --change autorandr --change
''; '';
}}/bin/greeter-setup-script"; }
}/bin/greeter-setup-script";
in in
{ {
config = { config = {

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkIf config.frogeye.desktop.xorg { config = lib.mkIf config.frogeye.desktop.xorg {
boot.kernelModules = [ "i2c-dev" ]; # Allows using ddcutil boot.kernelModules = [ "i2c-dev" ]; # Allows using ddcutil
@ -19,7 +24,7 @@
# https://wiki.archlinux.org/title/PipeWire#Noticeable_audio_delay_or_audible_pop/crack_when_starting_playback # https://wiki.archlinux.org/title/PipeWire#Noticeable_audio_delay_or_audible_pop/crack_when_starting_playback
preventGetTogetherDuoFromShuttingDown."monitor.bluez.rules" = [ preventGetTogetherDuoFromShuttingDown."monitor.bluez.rules" = [
{ {
matches = [{ "node.name" = "~bluez_output.41_42_D2_B5_13_72.*"; }]; matches = [ { "node.name" = "~bluez_output.41_42_D2_B5_13_72.*"; } ];
actions.update-props = { actions.update-props = {
"session.suspend-timeout-seconds" = 0; "session.suspend-timeout-seconds" = 0;
"dither.method" = "wannamaker3"; "dither.method" = "wannamaker3";
@ -39,7 +44,8 @@
extraLayouts.qwerty-fr = { extraLayouts.qwerty-fr = {
description = "QWERTY-fr"; description = "QWERTY-fr";
languages = [ "fr" ]; languages = [ "fr" ];
symbolsFile = "${pkgs.stdenv.mkDerivation { symbolsFile = "${
pkgs.stdenv.mkDerivation {
name = "qwerty-fr-keypad"; name = "qwerty-fr-keypad";
src = pkgs.fetchFromGitHub { src = pkgs.fetchFromGitHub {
owner = "qwerty-fr"; owner = "qwerty-fr";
@ -55,7 +61,8 @@
cp $src/linux/us_qwerty-fr $out/linux cp $src/linux/us_qwerty-fr $out/linux
runHook postInstall runHook postInstall
''; '';
}}/linux/us_qwerty-fr"; }
}/linux/us_qwerty-fr";
}; };
layout = "qwerty-fr"; layout = "qwerty-fr";
}; };

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = lib.mkMerge [ config = lib.mkMerge [
(lib.mkIf config.frogeye.dev.docker { (lib.mkIf config.frogeye.dev.docker {

View file

@ -1,7 +1,11 @@
{ pkgs, lib, config, ... }:
{ {
config = lib.mkIf config.frogeye.gaming pkgs,
{ lib,
config,
...
}:
{
config = lib.mkIf config.frogeye.gaming {
programs.steam.enable = true; programs.steam.enable = true;
hardware.graphics.enable32Bit = true; # Needed by Steam hardware.graphics.enable32Bit = true; # Needed by Steam
services = { services = {

View file

@ -1,11 +1,20 @@
{ pkgs, lib, config, home-manager, ... }: {
pkgs,
lib,
config,
home-manager,
...
}:
{ {
config = { config = {
users.users.root.initialHashedPassword = "$y$j9T$e64bjL7iyVlniEKwKbM9g0$cCn74za0r6L9QMO20Fdxz3/SX0yvhz3Xd6.2BhtbRL1"; # Not a real password users.users.root.initialHashedPassword = "$y$j9T$e64bjL7iyVlniEKwKbM9g0$cCn74za0r6L9QMO20Fdxz3/SX0yvhz3Xd6.2BhtbRL1"; # Not a real password
users.users.geoffrey = { users.users.geoffrey = {
isNormalUser = true; isNormalUser = true;
extraGroups = [ "adbusers" "wheel" ]; extraGroups = [
"adbusers"
"wheel"
];
shell = pkgs.zsh; shell = pkgs.zsh;
initialHashedPassword = "$y$j9T$e64bjL7iyVlniEKwKbM9g0$cCn74za0r6L9QMO20Fdxz3/SX0yvhz3Xd6.2BhtbRL1"; # Not a real password initialHashedPassword = "$y$j9T$e64bjL7iyVlniEKwKbM9g0$cCn74za0r6L9QMO20Fdxz3/SX0yvhz3Xd6.2BhtbRL1"; # Not a real password
@ -21,7 +30,9 @@
nix.settings.trusted-users = [ "geoffrey" ]; nix.settings.trusted-users = [ "geoffrey" ];
home-manager = { home-manager = {
users.geoffrey = { pkgs, ... }: { users.geoffrey =
{ pkgs, ... }:
{
frogeye = lib.mkDefault config.frogeye; frogeye = lib.mkDefault config.frogeye;
# Propagating options that way doesn't seem to conserve priority info, # Propagating options that way doesn't seem to conserve priority info,
# this is not great. Hopefully mkDefault resolve conflicts. # this is not great. Hopefully mkDefault resolve conflicts.

View file

@ -1,9 +1,18 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
passwordStoreDir = "/etc/passwords"; passwordStoreDir = "/etc/passwords";
passwordHash = password: builtins.hashString "sha256" "${password.path}\n${builtins.toString password.selector}\n${builtins.toString password.transform}"; passwordHash =
password:
builtins.hashString "sha256" "${password.path}\n${builtins.toString password.selector}\n${builtins.toString password.transform}";
passwordStorePath = password: "${passwordStoreDir}/${passwordHash password}"; passwordStorePath = password: "${passwordStoreDir}/${passwordHash password}";
describePassword = password: password.path describePassword =
password:
password.path
+ (if password.selector != null then " -> ${password.selector}" else "") + (if password.selector != null then " -> ${password.selector}" else "")
+ (if password.transform != null then " | (${password.transform})" else ""); + (if password.transform != null then " | (${password.transform})" else "");
passwordFiles = builtins.attrValues config.vivarium.passwordFiles; passwordFiles = builtins.attrValues config.vivarium.passwordFiles;
@ -12,16 +21,23 @@ in
config = { config = {
system = { system = {
activationScripts.secrets = { activationScripts.secrets = {
deps = [ "users" "groups" ]; deps = [
"users"
"groups"
];
supportsDryActivation = false; # TODO supportsDryActivation = false; # TODO
text = text =
let let
readPassword = password: "cat ${lib.strings.escapeShellArg (passwordStorePath password)}"; readPassword = password: "cat ${lib.strings.escapeShellArg (passwordStorePath password)}";
# Using awk's ENVIRON so it should resist any input? # Using awk's ENVIRON so it should resist any input?
pipeSubstitute = k: v: ''K=${lib.strings.escapeShellArg k} V="$(${v})" awk '{ gsub (ENVIRON["K"], ENVIRON["V"]); print }' ''; pipeSubstitute =
k: v:
''K=${lib.strings.escapeShellArg k} V="$(${v})" awk '{ gsub (ENVIRON["K"], ENVIRON["V"]); print }' '';
subsitutePassword = variable: password: pipeSubstitute variable (readPassword password); subsitutePassword = variable: password: pipeSubstitute variable (readPassword password);
subsitutePasswordFile = passwordFile: lib.mapAttrsToList subsitutePassword passwordFile.passwords; subsitutePasswordFile = passwordFile: lib.mapAttrsToList subsitutePassword passwordFile.passwords;
renderPasswordFile = passwordFile: "${lib.strings.concatStringsSep "| " (subsitutePasswordFile passwordFile)} < ${passwordFile.template}"; renderPasswordFile =
passwordFile:
"${lib.strings.concatStringsSep "| " (subsitutePasswordFile passwordFile)} < ${passwordFile.template}";
installPasswordFile = passwordFile: '' installPasswordFile = passwordFile: ''
install -C -o ${passwordFile.owner} -g ${passwordFile.group} -m ${passwordFile.mode} -d ${builtins.dirOf passwordFile.path} install -C -o ${passwordFile.owner} -g ${passwordFile.group} -m ${passwordFile.mode} -d ${builtins.dirOf passwordFile.path}
temp="$(mktemp)" temp="$(mktemp)"
@ -31,12 +47,15 @@ in
rm "$temp" rm "$temp"
trap - ERR trap - ERR
''; '';
installPasswordFileApp = passwordFile: pkgs.writeShellApplication { installPasswordFileApp =
name = builtins.replaceStrings ["/"] ["_"] passwordFile.path; passwordFile:
pkgs.writeShellApplication {
name = builtins.replaceStrings [ "/" ] [ "_" ] passwordFile.path;
runtimeInputs = with pkgs; [ gawk ]; runtimeInputs = with pkgs; [ gawk ];
text = installPasswordFile passwordFile; text = installPasswordFile passwordFile;
}; };
installPasswordFileSandboxed = passwordFile: installPasswordFileSandboxed =
passwordFile:
''${lib.getExe (installPasswordFileApp passwordFile)} || echo Failed to install ${lib.strings.escapeShellArg passwordFile.path}''; ''${lib.getExe (installPasswordFileApp passwordFile)} || echo Failed to install ${lib.strings.escapeShellArg passwordFile.path}'';
in in
'' ''
@ -47,22 +66,38 @@ in
extraSystemBuilderCmds = extraSystemBuilderCmds =
let let
passwords = builtins.attrValues config.vivarium.passwords; passwords = builtins.attrValues config.vivarium.passwords;
readPasswordClear = password: "pass show ${lib.strings.escapeShellArg password.path}" + ( readPasswordClear =
if password.selector == null password:
then " | head -n1" "pass show ${lib.strings.escapeShellArg password.path}"
+ (
if password.selector == null then
" | head -n1"
else else
(if password.selector == "@" (if password.selector == "@" then "" else " | tail -n +2 | yq -r '.${password.selector}'")
then ""
else " | tail -n +2 | yq -r '.${password.selector}'")
); );
readPassword = password: (readPasswordClear password) + (lib.strings.optionalString (password.transform != null) " | ${password.transform}"); readPassword =
password:
(readPasswordClear password)
+ (lib.strings.optionalString (password.transform != null) " | ${password.transform}");
gitPath = password: ''"$PASSWORD_STORE_DIR"/${lib.strings.escapeShellArg password.path}.gpg''; gitPath = password: ''"$PASSWORD_STORE_DIR"/${lib.strings.escapeShellArg password.path}.gpg'';
isGeneratedPassword = password: ''test -f ${gitPath password}''; isGeneratedPassword = password: ''test -f ${gitPath password}'';
dateGit = password: " " + ''(cd "$(dirname ${gitPath password})"; git log -n1 --format='format:%ct' "$(basename ${gitPath password})")'' + " "; dateGit =
password:
" "
+ ''(cd "$(dirname ${gitPath password})"; git log -n1 --format='format:%ct' "$(basename ${gitPath password})")''
+ " ";
dateStore = password: ''sudo stat -c '%Y' ${passwordStorePath password}''; dateStore = password: ''sudo stat -c '%Y' ${passwordStorePath password}'';
isInStore = password: ''sudo test -f ${passwordStorePath password}''; isInStore = password: ''sudo test -f ${passwordStorePath password}'';
testCanGenerate = password: lib.asserts.assertMsg (builtins.elem password.selector [ "@" null ]) "Unimplemented: generator + selector ${describePassword password}"; testCanGenerate =
generatePassword = password: assert testCanGenerate password; ''${password.generator} | pass insert -m ${lib.strings.escapeShellArg password.path}''; password:
lib.asserts.assertMsg (builtins.elem password.selector [
"@"
null
]) "Unimplemented: generator + selector ${describePassword password}";
generatePassword =
password:
assert testCanGenerate password;
''${password.generator} | pass insert -m ${lib.strings.escapeShellArg password.path}'';
raiseCantGenerate = password: ''echo "Error: no generator" ; exit 1''; raiseCantGenerate = password: ''echo "Error: no generator" ; exit 1'';
syncPasswordStore = password: '' syncPasswordStore = password: ''
# ${describePassword password} # ${describePassword password}
@ -112,7 +147,9 @@ in
allFilenames = builtins.map (password: "${passwordStoreDir}/${passwordHash password}") passwords; allFilenames = builtins.map (password: "${passwordStoreDir}/${passwordHash password}") passwords;
in in
'' ''
ln -s ${lib.getExe (pkgs.writeShellApplication { ln -s ${
lib.getExe (
pkgs.writeShellApplication {
name = "update-password-store"; name = "update-password-store";
text = '' text = ''
test -d "$PASSWORD_STORE_DIR" test -d "$PASSWORD_STORE_DIR"
@ -128,7 +165,9 @@ in
''; '';
# -ctime +60 is so it is possible to boot from previous nixpkgs without missing transform hashes # -ctime +60 is so it is possible to boot from previous nixpkgs without missing transform hashes
# TODO Find a better mechanism, maybe à la bootspec, or something compatible with cross-arch # TODO Find a better mechanism, maybe à la bootspec, or something compatible with cross-arch
})} $out/bin/ }
)
} $out/bin/
''; '';
}; };
vivarium.passwords = vivarium.passwords =
@ -144,7 +183,9 @@ in
vivarium = vivarium =
let let
defaultvar = "@PASSWORD@"; defaultvar = "@PASSWORD@";
passwordSubmodule = lib.types.submodule ({ ... }: { passwordSubmodule = lib.types.submodule (
{ ... }:
{
options = { options = {
path = lib.mkOption { path = lib.mkOption {
type = lib.types.str; type = lib.types.str;
@ -166,17 +207,20 @@ in
description = "Shell command to transform the password with before substitution"; description = "Shell command to transform the password with before substitution";
}; };
}; };
}); }
);
in in
{ {
passwords = lib.mkOption { passwords = lib.mkOption {
default = { }; default = { };
type = lib.types.attrsOf passwordSubmodule; type = lib.types.attrsOf passwordSubmodule;
}; };
passwordFiles = passwordFiles = lib.mkOption {
lib.mkOption {
default = { }; default = { };
type = lib.types.attrsOf (lib.types.submodule ({ name, config, ... }: { type = lib.types.attrsOf (
lib.types.submodule (
{ name, config, ... }:
{
options = { options = {
path = lib.mkOption { path = lib.mkOption {
type = lib.types.str; type = lib.types.str;
@ -218,7 +262,9 @@ in
description = "Path to password that will substitute '@PASSWORD@' in the template. Exclusive with `passwords`."; description = "Path to password that will substitute '@PASSWORD@' in the template. Exclusive with `passwords`.";
}; };
}; };
})); }
)
);
}; };
}; };
}; };

View file

@ -1,7 +1,15 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
vivariumBuilderDefault = { vivariumBuilderDefault = {
systems = [ "x86_64-linux" "aarch64-linux" ]; systems = [
"x86_64-linux"
"aarch64-linux"
];
protocol = "ssh-ng"; protocol = "ssh-ng";
sshUser = "nixremote"; sshUser = "nixremote";
# sshKey doesn't work # sshKey doesn't work
@ -11,7 +19,12 @@ let
{ {
hostName = "abavorana.frogeye.fr"; hostName = "abavorana.frogeye.fr";
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU5iNzcrS01tRHI0MVhZdmZITXQvK3NHMkJCSEIzYUl4M045WDNVejhFaUogZ2VvZmZyZXlAY3VyYWNhbwo="; publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU5iNzcrS01tRHI0MVhZdmZITXQvK3NHMkJCSEIzYUl4M045WDNVejhFaUogZ2VvZmZyZXlAY3VyYWNhbwo=";
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ]; supportedFeatures = [
"nixos-test"
"benchmark"
"big-parallel"
"kvm"
];
maxJobs = 8; maxJobs = 8;
} }
{ {
@ -32,21 +45,31 @@ in
supportsDryActivation = true; supportsDryActivation = true;
text = '' text = ''
mkdir -p /root/.ssh mkdir -p /root/.ssh
cat ${pkgs.writeText "root-ssh-config" (lib.strings.concatLines (builtins.map (builder: '' cat ${
pkgs.writeText "root-ssh-config" (
lib.strings.concatLines (
builtins.map (builder: ''
Host ${builder.hostName} Host ${builder.hostName}
ControlMaster auto ControlMaster auto
ControlPath ~/.ssh/master-%r@%n:%p ControlPath ~/.ssh/master-%r@%n:%p
ControlPersist 60s ControlPersist 60s
'') vivariumBuilders)) } > /root/.ssh/config '') vivariumBuilders
)
)
} > /root/.ssh/config
''; '';
}; };
nix = { nix = {
buildMachines = builtins.map (vivariumBuilder: vivariumBuilderDefault // vivariumBuilder) vivariumBuilders; buildMachines = builtins.map (
vivariumBuilder: vivariumBuilderDefault // vivariumBuilder
) vivariumBuilders;
distributedBuilds = false; distributedBuilds = false;
settings = { settings = {
builders-use-substitutes = true; builders-use-substitutes = true;
trusted-public-keys = publicKeys; trusted-public-keys = publicKeys;
trusted-substituters = builtins.map (builder: "${builder.protocol}://${builder.sshUser}@${builder.hostName}") config.nix.buildMachines; trusted-substituters = builtins.map (
builder: "${builder.protocol}://${builder.sshUser}@${builder.hostName}"
) config.nix.buildMachines;
}; };
}; };
}; };

View file

@ -1,4 +1,10 @@
{ pkgs, lib, config, stylix, ... }: {
pkgs,
lib,
config,
stylix,
...
}:
{ {
config = { config = {
boot = { boot = {
@ -9,10 +15,14 @@
enable = true; enable = true;
homeManagerIntegration.autoImport = false; # Makes config reuse easier homeManagerIntegration.autoImport = false; # Makes config reuse easier
polarity = "dark"; polarity = "dark";
targets.plymouth.logo = pkgs.runCommand "flower.png" { } "${pkgs.inkscape}/bin/inkscape ${pkgs.substituteAll { targets.plymouth.logo =
pkgs.runCommand "flower.png" { }
"${pkgs.inkscape}/bin/inkscape ${
pkgs.substituteAll {
src = ./flower.svg; src = ./flower.svg;
color = config.lib.stylix.colors.withHashtag.base07; color = config.lib.stylix.colors.withHashtag.base07;
}} -w 256 -o $out"; }
} -w 256 -o $out";
# UPST Default grub font is sansSerif, which doesn't work. # UPST Default grub font is sansSerif, which doesn't work.
# Maybe because people patch mono with nerdfonts and that isn't compatible? # Maybe because people patch mono with nerdfonts and that isn't compatible?
}; };

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
cfg = config.services.syncthing; cfg = config.services.syncthing;
service = "syncthing"; service = "syncthing";
@ -9,9 +14,14 @@ let
generator = ''(t="$(mktemp -d)" && ${lib.getExe pkgs.syncthing} generate --home="$t" &> /dev/null && cat "$t"/{cert,key}.pem && rm -rf "$t")''; generator = ''(t="$(mktemp -d)" && ${lib.getExe pkgs.syncthing} generate --home="$t" &> /dev/null && cat "$t"/{cert,key}.pem && rm -rf "$t")'';
}; };
capitalizeFirstLetter = str: (lib.strings.toUpper (builtins.substring 0 1 str)) + (builtins.substring 1 (builtins.stringLength str) str); capitalizeFirstLetter =
str:
(lib.strings.toUpper (builtins.substring 0 1 str))
+ (builtins.substring 1 (builtins.stringLength str) str);
nixosDevices = builtins.map (system: system.config.frogeye) (builtins.attrValues config.frogeye.toplevel.nixosConfigurations); nixosDevices = builtins.map (system: system.config.frogeye) (
builtins.attrValues config.frogeye.toplevel.nixosConfigurations
);
allDevices = nixosDevices; allDevices = nixosDevices;
syncingDevices = builtins.filter (device: device.syncthing.id != null) allDevices; syncingDevices = builtins.filter (device: device.syncthing.id != null) allDevices;
peerDevices = builtins.filter (device: device.name != config.frogeye.name) syncingDevices; peerDevices = builtins.filter (device: device.name != config.frogeye.name) syncingDevices;
@ -20,7 +30,10 @@ let
allFolders = builtins.attrValues config.frogeye.folders; allFolders = builtins.attrValues config.frogeye.folders;
syncedFolders = builtins.filter (folder: folder.syncthing.enable) allFolders; syncedFolders = builtins.filter (folder: folder.syncthing.enable) allFolders;
folderShouldSyncWith = folder: device: (lib.hasAttrByPath [ folder.name ] device.folders) && device.folders.${folder.name}.syncthing.enable; folderShouldSyncWith =
folder: device:
(lib.hasAttrByPath [ folder.name ] device.folders)
&& device.folders.${folder.name}.syncthing.enable;
folderDeviceEntry = folder: device: { deviceID = device.syncthing.id; }; folderDeviceEntry = folder: device: { deviceID = device.syncthing.id; };
enable = (builtins.length syncedFolders) > 0; enable = (builtins.length syncedFolders) > 0;
@ -38,29 +51,38 @@ in
cert = "${secretsDir}/cert.pem"; cert = "${secretsDir}/cert.pem";
settings = { settings = {
devices = builtins.listToAttrs (builtins.map (device: { inherit (device) name; value = device.syncthing; }) syncingDevices); devices = builtins.listToAttrs (
folders = builtins.listToAttrs (builtins.map builtins.map (device: {
(folder: { inherit (device) name;
value = device.syncthing;
}) syncingDevices
);
folders = builtins.listToAttrs (
builtins.map (folder: {
inherit (folder) name; inherit (folder) name;
value = value = {
{
label = "${capitalizeFirstLetter folder.user} ${folder.label}"; label = "${capitalizeFirstLetter folder.user} ${folder.label}";
path = "${config.users.users.${folder.user}.home}/${folder.path}"; path = "${config.users.users.${folder.user}.home}/${folder.path}";
# Despite further in the code indicating this is possible, it is, actually not # Despite further in the code indicating this is possible, it is, actually not
# devices = builtins.map (folderDeviceEntry folder) (builtins.filter (folderShouldSyncWith folder) peerDevices); # devices = builtins.map (folderDeviceEntry folder) (builtins.filter (folderShouldSyncWith folder) peerDevices);
devices = builtins.map (device: device.name) (builtins.filter (folderShouldSyncWith folder) peerDevices); devices = builtins.map (device: device.name) (
builtins.filter (folderShouldSyncWith folder) peerDevices
);
versioning = versioning =
if (config.frogeye.storageSize == "big" && folder.versionsMaxDays != null) then { if (config.frogeye.storageSize == "big" && folder.versionsMaxDays != null) then
{
type = "staggered"; type = "staggered";
params.maxAge = builtins.toString (folder.versionsMaxDays * 24 * 3600); params.maxAge = builtins.toString (folder.versionsMaxDays * 24 * 3600);
# TODO Increase cleanupIntervalS to 1 day or so # TODO Increase cleanupIntervalS to 1 day or so
} else null; }
else
null;
rescanIntervalS = 10 * 3600; # Using watcher, should be good enough rescanIntervalS = 10 * 3600; # Using watcher, should be good enough
copyRangeMethod = "all"; # Prevents duplication copyRangeMethod = "all"; # Prevents duplication
copyOwnershipFromParent = true; copyOwnershipFromParent = true;
} // folder.syncthing; } // folder.syncthing;
}) }) syncedFolders
syncedFolders); );
options = rec { options = rec {
urAccepted = 3; urAccepted = 3;
urSeen = urAccepted; urSeen = urAccepted;
@ -75,7 +97,11 @@ in
''}" ''}"
]; ];
PrivateUsers = lib.mkForce false; PrivateUsers = lib.mkForce false;
AmbientCapabilities = ["CAP_CHOWN" "CAP_DAC_OVERRIDE" "CAP_FOWNER"]; AmbientCapabilities = [
"CAP_CHOWN"
"CAP_DAC_OVERRIDE"
"CAP_FOWNER"
];
}; };
vivarium.passwordFiles = { vivarium.passwordFiles = {
${cfg.key}.password = password // { ${cfg.key}.password = password // {

View file

@ -1,17 +1,23 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
importScript = pkgs.writers.writePython3 "install-wifi-import" importScript = pkgs.writers.writePython3 "install-wifi-import" {
{
libraries = [ pkgs.python3Packages.pyaml ]; libraries = [ pkgs.python3Packages.pyaml ];
} } (builtins.readFile ./import.py);
(builtins.readFile ./import.py);
applyScript = pkgs.writers.writePython3 "install-wifi-apply" { } (builtins.readFile ./apply.py); applyScript = pkgs.writers.writePython3 "install-wifi-apply" { } (builtins.readFile ./apply.py);
in in
{ {
environment.systemPackages = [ environment.systemPackages = [
(pkgs.writeShellApplication { (pkgs.writeShellApplication {
name = "install-wifi"; name = "install-wifi";
runtimeInputs = with pkgs; [ wpa_supplicant diffutils ]; runtimeInputs = with pkgs; [
wpa_supplicant
diffutils
];
text = '' text = ''
temp="$(mktemp --directory --suffix="-install-wifi")" temp="$(mktemp --directory --suffix="-install-wifi")"
cd "$temp" cd "$temp"
@ -61,8 +67,7 @@ in
"WiFi in de trein" "WiFi in de trein"
"_WIFI_LYRIA" "_WIFI_LYRIA"
"WIFIonICE" "WIFIonICE"
] ] (ssid: { });
(ssid: { });
userControlled.enable = true; # Allow some control with wpa_cli userControlled.enable = true; # Allow some control with wpa_cli
}; };
services.chrony.serverOption = "offline"; services.chrony.serverOption = "offline";

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
disko.devices.disk."${config.frogeye.name}".device = "/dev/disk/by-id/mmc-DA4064_0x931f080f"; disko.devices.disk."${config.frogeye.name}".device = "/dev/disk/by-id/mmc-DA4064_0x931f080f";

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
frogeye = { frogeye = {

View file

@ -1,4 +1,10 @@
{ pkgs, lib, config, nixos-hardware, ... }: {
pkgs,
lib,
config,
nixos-hardware,
...
}:
{ {
config = { config = {
boot = { boot = {
@ -10,7 +16,10 @@
}; };
frogeye.desktop = { frogeye.desktop = {
x11_screens = [ "DP-1" "eDP-1" ]; x11_screens = [
"DP-1"
"eDP-1"
];
maxVideoHeight = 1080; maxVideoHeight = 1080;
phasesCommands = { phasesCommands = {
jour = '' jour = ''
@ -30,10 +39,12 @@
# https://wiki.pine64.org/wiki/Mainline_Hardware_Decoding#mpv # https://wiki.pine64.org/wiki/Mainline_Hardware_Decoding#mpv
# Might be worth if using CI to build. # Might be worth if using CI to build.
home-manager.sharedModules = [{ home-manager.sharedModules = [
{
# gpu-hq is too much for it to handle, even with hw decoding # gpu-hq is too much for it to handle, even with hw decoding
config.programs.mpv.config.profile = lib.mkForce "default"; config.programs.mpv.config.profile = lib.mkForce "default";
}]; }
];
zramSwap = { zramSwap = {
# Not capable of building itself otherwise # Not capable of building itself otherwise

View file

@ -1,4 +1,9 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
{ {
config = { config = {
boot.loader.efi.canTouchEfiVariables = false; boot.loader.efi.canTouchEfiVariables = false;