Create initial flake structure with london configuration

This commit is contained in:
Victor Mignot 2023-10-22 17:12:42 +02:00
parent f65434f701
commit 81353cd437
Signed by: dala
GPG key ID: 5E7F2CE1BEAFED3D
38 changed files with 2360 additions and 0 deletions

13
.sops.yaml Normal file
View file

@ -0,0 +1,13 @@
keys:
- &london_system age1rr2u4kk5jc0zk5mmgcfzlddzz82u9ldqwnd2mkcspnps7pzegsms7fys7u
- &london_dala age19m7s6rl4l88nv0f7el70k9u9mv6fd0nq5nw5a3f6p3ffzch274lsksu3y7
creation_rules:
- path_regex: configurations/london/secrets/secrets.yaml$
key_groups:
- age:
- *london_system
- path_regex: configurations/london/secrets/users/dala.yaml$
key_groups:
- age:
- *london_dala

View file

@ -0,0 +1,128 @@
{ pkgs, config, lib, extraInfo, ... }:
{
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
/* Meta */
isProfessional = false;
/* Volumes */
luksDevices = [
{
name = "crypted-nixos";
deviceUUID = "5a1ac4ae-d74f-4599-bc5a-fc0a3501a196";
isPreLVM = true;
}
];
filesystems = [
{
mountpoint = "/";
deviceUUID = "8dd700f8-7bf7-426c-8869-d31687e343df";
fsType = "ext4";
}
{
mountpoint = "/boot";
deviceUUID = "F2B6-C8CA";
fsType = "vfat";
}
{
mountpoint = "/nix";
deviceUUID = "b7a643f6-a78e-4e32-a1a3-22b321465bf6";
fsType = "ext4";
}
{
mountpoint = "/home";
deviceUUID = "e26f6727-3712-4830-b8e8-fdbce5e3584b";
fsType = "ext4";
}
];
swapDeviceUUID = "5fe5e76b-df3d-43ce-abf9-d2b63078df09";
/* Linux kernel */
useLatestKernel = true;
/* Nix */
allowUnfreePackages = true;
/* Hardware acceleration */
hwAccelerationGPU = "nvidia";
/* System secrets */
sops = {
gnupg.sshKeyPaths = [ ];
age = {
sshKeyPaths = [ ];
keyFile = "/var/lib/sops-nix/key.txt";
};
defaultSopsFile = ./secrets/secrets.yaml;
secrets.wg0_private = { };
};
/* Wireguard */
networking.wg-quick.interfaces.wg0 = {
address = [ "10.100.0.4/24" ];
dns = [ "10.100.0.1" ];
listenPort = 51820;
privateKeyFile = config.sops.secrets.wg0_private.path;
peers = [
{
# Rock Pro 64
publicKey = "XVmG3/rNsCqc8KCmOx3+UUn9DJOnJ40Uxid5JGdChR4=";
endpoint = "${extraInfo.wireguard.rockProEndpoint}:51820";
allowedIPs = [ "10.100.0.1" ];
persistentKeepalive = 25;
}
{
# VPS
publicKey = "x45YsLDpMJw1pwKOvkyzdesen3lFcKpxCXACGz+xtDs=";
endpoint = "${extraInfo.wireguard.VPSEndpoint}:51820";
allowedIPs = [ "10.100.0.2" ];
persistentKeepalive = 25;
}
];
};
/* User config */
machineUsers = {
dala = {
description = "Dala";
groups = [ "wheel" "video" "audio" "seat" "keys" "lp" "dialout" "network" ];
uid = 1000;
shell = pkgs.fish;
enableHomeManagerProfile = true;
homeManagerConfig = {
desktop.monitors = [
{
name = "Iiyama North America PL2470H 0x0000047B";
resolution = "1920x1080@165.003Hz";
position = "1920 0";
defaultWorkspace = 1;
}
{
name = "Iiyama North America PL2530H 1154392601941";
resolution = "1920x1080@74.973Hz";
position = "0 0";
defaultWorkspace = 2;
}
];
nixpkgs.config.allowUnfree = true;
development.embedded.enableTools = true;
};
};
};
}

View file

@ -0,0 +1,21 @@
wg0_private: ENC[AES256_GCM,data:z5G2EFh1vZk1yEwj0pFIU49u84bOjBZRzvKgqluWoQ6vqm+cMQt/dyGqXg4=,iv:XOiExUWxJczO+aJ+BogtlibqVshEkc6r8xeTPmdru4Y=,tag:+v/3JE1rqTm2x2MJUNltqw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1rr2u4kk5jc0zk5mmgcfzlddzz82u9ldqwnd2mkcspnps7pzegsms7fys7u
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNOVhvOFRQQ1ppenZQdEN6
S3FPYkNTTnZWUnBFUXMxNEFWcUQ4WVhzK1g4CitLWktOamUyU2dPOHBUaG40WWxN
Nkw5M2pCWFBtTWtQMjQ0azN3Rjh3ZDAKLS0tIFNyNGxiNE41RUdDVkZmNUxyVVR5
dXhiMUhVc1ZBb0F0bFArZU5OU1ZRK0EKdjtUBIRrw1AhNPczQJiDw6GywJL/jm2r
4o3XkFqMkP93YAoprHw7egH6t/6QVCFQTZPU4cAwJ0y1bLx9ju44uQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-11-01T17:15:27Z"
mac: ENC[AES256_GCM,data:zL3UgmKuyzZzBTlBAyP7+nN1If7AMjq1qGkbbXKW2rlzl41x6orMdZQfOWG06eBdd7CGBoNgBNV7A9SE11RhXUvr1gdQGILie0ER2/UCEkEgXIV3tpto1C/tsEYDL7z8LSlcuPt3GJkca1Ym6yhIoe576ho7du3HclUCFBPIBQY=,iv:O3/aYlFPiueoByTyvefahrmFwGq5DAEdUaYvJXB1TFI=,tag:1Al7Lw18AZZ8spnITBuGMw==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3

137
flake.lock Normal file
View file

@ -0,0 +1,137 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1699368917,
"narHash": "sha256-nUtGIWf86BOkUbtksWtfglvCZ/otP0FTZlQH8Rzc7PA=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "6a8444467c83c961e2f5ff64fb4f422e303c98d3",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1699291058,
"narHash": "sha256-5ggduoaAMPHUy4riL+OrlAZE14Kh7JWX4oLEs22ZqfU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "41de143fda10e33be0f47eab2bfe08a50f234267",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable_2": {
"locked": {
"lastModified": 1699110214,
"narHash": "sha256-L2TU4RgtiqF69W8Gacg2jEkEYJrW+Kp0Mp4plwQh5b8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "78f3a4ae19f0e99d5323dd2e3853916b8ee4afee",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-23.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1699099776,
"narHash": "sha256-X09iKJ27mGsGambGfkKzqvw5esP1L/Rf8H3u3fCqIiU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "85f1ba3e51676fa8cc604a3d863d729026a6b8eb",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"home-manager": "home-manager",
"nixpkgs-stable": "nixpkgs-stable",
"nixpkgs-unstable": "nixpkgs-unstable",
"sops-nix": "sops-nix"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs-unstable"
],
"nixpkgs-stable": "nixpkgs-stable_2"
},
"locked": {
"lastModified": 1699311858,
"narHash": "sha256-W/sQrghPAn5J9d+9kMnHqi4NPVWVpy0V/qzQeZfS/dM=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "664187539871f63857bda2d498f452792457b998",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

72
flake.nix Normal file
View file

@ -0,0 +1,72 @@
{
description = "Dala's unified NixOS configuration";
inputs = {
# As we have machine using the unstable channel, and other machines using the stable one,
# we import both, and we will select for each machine which one to use.
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-23.05";
flake-utils.url = "github:numtide/flake-utils";
# Home-manager isn't used for anything except my workstations, which all use the unstable channel.
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
# For sops-nix, we keep the unstable nixpkgs, as it shouldn't break anything.
# This input is made to manage secrets on this repository.
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
};
outputs = { self, nixpkgs-unstable, nixpkgs-stable, home-manager, sops-nix, flake-utils }:
let
machines = import ./machines.nix;
in
{
nixosConfigurations = builtins.mapAttrs
(name: value:
let
nixpkgs =
if value.nixpkgsUnstable
then nixpkgs-unstable
else nixpkgs-stable;
in
nixpkgs.lib.nixosSystem {
system = value.system;
specialArgs = {
machineInfos = {
hostname = name;
} // value;
sopsHmModule = sops-nix.homeManagerModules.sops;
};
modules = [
./configurations/${name}
./modules/common
(if (value.machineType == "workstation")
then ./modules/workstation
else ./modules/server)
(if (value.machineType == "workstation" && value.enableHomeManager)
then home-manager.nixosModules.home-manager
else { })
sops-nix.nixosModules.sops
];
}
)
machines;
formatter = builtins.listToAttrs (map
(system:
{
name = system;
value = nixpkgs-unstable.legacyPackages.${system}.nixpkgs-fmt;
}
)
flake-utils.lib.defaultSystems);
};
}

9
machines.nix Normal file
View file

@ -0,0 +1,9 @@
{
london = {
machineType = "workstation";
nixpkgsUnstable = true;
system = "x86_64-linux";
enableHomeManager = true;
stateVersion = "23.11";
};
}

62
modules/common/boot.nix Normal file
View file

@ -0,0 +1,62 @@
{ lib, config, ... }:
with lib;
let
luksDevicesModule = types.submodule {
options.name = mkOption {
type = types.str;
description = ''
The partition name.
'';
};
options.deviceUUID = mkOption {
type = types.str;
description = ''
The partition device UUID.
'';
};
options.isPreLVM = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether the decrypted partition will be a LVM device.
'';
};
};
in
{
options.enableDefaultSystemdBoot = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Whether or not enable the default SystemD boot system.
Can be useful for devices using u-boot.
'';
};
options.luksDevices = mkOption {
type = types.listOf luksDevicesModule;
default = [ ];
description = ''
List of LUKS devices.
'';
};
config = {
boot.initrd.luks.devices = builtins.listToAttrs (map
(fs: {
name = fs.name;
value = {
device = "/dev/disk/by-uuid/${fs.deviceUUID}";
preLVM = fs.isPreLVM;
};
})
config.luksDevices);
boot.loader.systemd-boot.enable = config.enableDefaultSystemdBoot;
boot.loader.efi.canTouchEfiVariables = true;
};
}

View file

@ -0,0 +1,62 @@
{ lib, config, pkgs, machineInfos, modulesPath, ... }:
with lib;
{
imports = [
./filesystem.nix
./boot.nix
./linux.nix
./nix.nix
./network.nix
./hardware.nix
./users.nix
(modulesPath + "/installer/scan/not-detected.nix")
];
options.machineType = mkOption {
type = types.enum [ "workstation" "server" ];
default = "workstation";
example = "server";
description = ''
What is the type of this machine.
'';
};
options.isProfessional = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether or not this machine is used for professionnal purposes.
'';
};
options.enableDocker = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether or not to enable the docker stack.
'';
};
config = {
machineType = machineInfos.machineType;
system.stateVersion = machineInfos.stateVersion;
networking.hostName = machineInfos.hostname;
virtualisation.docker.enable = config.enableDocker;
# Only enable fish shell if there is at least one user using it.
programs.fish.enable = builtins.any (user: user.shell == pkgs.fish) (builtins.attrValues config.machineUsers);
# We always want to disable the X server as only workstation use windows manager
# and they always use wayland.
services.xserver.enable = false;
assertions = [
{
assertion = !(config.machineType == "server" && config.isProfessional);
message = "Only workstations can be professionnal hardware";
}
];
};
}

View file

@ -0,0 +1,67 @@
{ lib, config, ... }:
with lib;
let
fsModule = types.submodule {
options = {
mountpoint = mkOption {
type = types.str;
description = ''
The filesystem mountpoint.
'';
};
deviceUUID = mkOption {
type = types.str;
description = ''
The volume UUID.
'';
};
fsType = mkOption {
type = types.str;
description = ''
The volume filesystem.
'';
};
};
};
in
{
options.filesystems = mkOption {
type = types.listOf fsModule;
default = [ ];
example = [
{
mountpoint = "/";
deviceUUID = "XXXXX-YYYYYY-AJDKKSKSJ";
fsType = "ext4";
}
];
description = ''
The machine filesystem tree description.
'';
};
options.swapDeviceUUID = mkOption {
type = types.nullOr types.str;
default = null;
};
config = {
fileSystems = builtins.listToAttrs (map
(fs: {
name = fs.mountpoint;
value = {
device = "/dev/disk/by-uuid/${fs.deviceUUID}";
fsType = fs.fsType;
};
})
config.filesystems);
swapDevices = mkIf (config.swapDeviceUUID != null) [
{ device = "/dev/disk/by-uuid/${config.swapDeviceUUID}"; }
];
};
}

View file

@ -0,0 +1,26 @@
{ lib, config, pkgs, ... }:
with lib;
{
options.hwAccelerationGPU = mkOption {
type = types.nullOr (types.enum [ "nvidia" "intel" ]);
default = null;
example = "nvidia";
description = ''
The GPU type.
'';
};
config = {
hardware.opengl = {
enable = config.hwAccelerationGPU != null;
extraPackages = with pkgs; [
libvdpau-va-gl
vaapiVdpau
];
};
services.xserver.videoDrivers = [
(mkIf (config.hwAccelerationGPU == "nvidia") "nouveau")
];
};
}

53
modules/common/linux.nix Normal file
View file

@ -0,0 +1,53 @@
{ lib, config, pkgs, ... }:
with lib;
{
options.useLatestKernel = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether or not to use the latest Linux kernel version.
'';
};
options.consoleFont = mkOption {
type = types.str;
default = "Lat2-Terminus16";
description = ''
The font to use in the Linux console.
'';
};
options.timeZone = mkOption {
type = types.str;
default = "Europe/Paris";
description = ''
The system time zone.
'';
};
options.locale = mkOption {
type = types.str;
default = "en_US.utf8";
description = ''
The system locale.
'';
};
options.keymap = mkOption {
type = types.str;
default = "fr";
example = "fr";
description = ''
The keyboard map used.
'';
};
config = {
boot.kernelPackages = mkIf config.useLatestKernel pkgs.linuxPackages_latest;
time.timeZone = config.timeZone;
console.font = config.consoleFont;
console.keyMap = config.keymap;
i18n.defaultLocale = config.locale;
};
}

View file

@ -0,0 +1,38 @@
{ lib, config, ... }:
with lib;
{
options.enableFirewall = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Whether or not to enable firewall.
'';
};
options.extraAllowedTCPPorts = mkOption {
type = types.listOf types.port;
default = [ ];
example = [ 53 ];
description = ''
List of custom TCP ports to open in the firewall.
'';
};
options.extraAllowedUDPPorts = mkOption {
type = types.listOf types.port;
default = [ ];
example = [ 53 ];
description = ''
List of custom UDP ports to open in the firewall.
'';
};
config = {
networking.networkmanager.enable = true;
networking.useDHCP = mkDefault true;
networking.firewall.enable = true;
networking.firewall.allowedTCPPorts = config.extraAllowedTCPPorts;
networking.firewall.allowedUDPPorts = config.extraAllowedUDPPorts;
};
}

26
modules/common/nix.nix Normal file
View file

@ -0,0 +1,26 @@
{ pkgs, lib, config, ... }:
with lib;
{
options.allowUnfreePackages = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Whether the system can use unfree derivations.
'';
};
config = {
nix = {
settings.sandbox = true;
package = pkgs.nixVersions.stable;
extraOptions = ''
experimental-features = nix-command flakes
'';
};
nixpkgs.config.allowUnfree = config.allowUnfreePackages;
};
}

50
modules/common/users.nix Normal file
View file

@ -0,0 +1,50 @@
{ lib, config, ... }:
with lib;
let
userModule = types.submodule {
options = {
description = mkOption {
type = types.str;
};
groups = mkOption {
type = types.listOf types.str;
};
uid = mkOption {
type = types.nullOr types.int;
};
shell = mkOption {
type = types.package;
};
enableHomeManagerProfile = mkOption {
type = types.bool;
default = false;
};
homeManagerConfig = mkOption {
default = { };
};
};
};
in
{
options.machineUsers = mkOption {
type = types.attrsOf userModule;
};
config = {
users.users = builtins.mapAttrs
(name: value: {
isNormalUser = true;
home = "/home/${name}";
description = value.description;
extraGroups = value.groups;
shell = value.shell;
uid = mkIf (value.uid != null) value.uid;
})
config.machineUsers;
};
}

View file

@ -0,0 +1,3 @@
{ lib, config, ... }:
with lib;
{ }

View file

@ -0,0 +1,19 @@
{ lib, config, ... }:
with lib;
{
options.enableBluetooth = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Enable the bluetooth stack
'';
};
config = mkIf config.enableBluetooth {
hardware.bluetooth = {
enable = true;
};
services.blueman.enable = true;
};
}

View file

@ -0,0 +1,50 @@
{ lib, config, pkgs, machineInfos, sopsHmModule, ... }:
with lib;
{
imports = [
./sound.nix
./desktop.nix
./bluetooth.nix
];
options.enableHomeManager = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Whether to install and use home-manager on this machine.
'';
};
config = {
enableHomeManager = machineInfos.enableHomeManager;
home-manager.useGlobalPkgs = mkIf config.enableHomeManager true;
home-manager.useUserPackages = mkIf config.enableHomeManager true;
home-manager.sharedModules = mkIf config.enableHomeManager [
./home-manager
sopsHmModule
];
home-manager.users = builtins.mapAttrs
(name: value:
mkIf value.enableHomeManagerProfile ({
home.username = name;
home.homeDirectory = "/home/${name}";
home.stateVersion = machineInfos.stateVersion;
programs.home-manager.enable = true;
enableFishShell = value.shell == pkgs.fish;
isProfessional = config.isProfessional;
} // value.homeManagerConfig)
)
config.machineUsers;
programs.dconf.enable = true;
security.polkit.enable = true;
services.dbus.enable = true;
fonts.fontconfig.enable = true;
services.gnome.gnome-keyring.enable = true;
};
}

View file

@ -0,0 +1,17 @@
{ config, lib, pkgs, ... }:
with lib;
let
usersHasSway = builtins.any
(user:
config.home-manager.users.${user}.desktop.enableSwayStack
)
(builtins.attrNames config.machineUsers);
in
{
programs.sway.enable = usersHasSway;
xdg.portal = mkIf usersHasSway {
enable = true;
wlr.enable = true;
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
};
}

View file

@ -0,0 +1,38 @@
{ lib, pkgs, config, ... }:
with lib;
{
options = {
communication.discord.enable = mkOption {
type = types.bool;
default = !config.isProfessional;
example = true;
};
communication.slack.enable = mkOption {
type = types.bool;
default = config.isProfessional;
example = true;
};
communication.weechat.enable = mkOption {
type = types.bool;
default = true;
example = false;
};
communication.matrix.enable = mkOption {
type = types.bool;
default = !config.isProfessional;
example = false;
};
};
config.home.packages = with pkgs; [
(mkIf config.communication.discord.enable (discord.override {
nss = nss_latest;
}))
(mkIf config.communication.slack.enable slack)
(mkIf config.communication.weechat.enable weechat)
(mkIf config.communication.matrix.enable element)
];
}

View file

@ -0,0 +1,73 @@
{ pkgs, lib, ... }:
with lib;
let
multimediaPackages = with pkgs; [
qpwgraph
feh
gimp
vlc
];
soundPackages = with pkgs; [
pulseaudio
pavucontrol
pamixer
];
yubikeyTools = with pkgs; [
yubikey-personalization
yubico-pam
yubikey-manager
];
in
{
imports = [
./desktop
./development
./neovim
./fish.nix
./termux.nix
./gpg.nix
./communication.nix
./mail.nix
];
options.isProfessional = mkOption {
type = types.bool;
};
config = {
fonts.fontconfig.enable = true;
home.packages = with pkgs; [
htop
firefox
autojump
nextcloud-client
keepassxc
ranger
libreoffice
tldr
zathura
lazygit
] ++ multimediaPackages
++ soundPackages
++ yubikeyTools;
# XDG-Mime configuration
xdg.mime.enable = true;
xdg.mimeApps.enable = true;
xdg.mimeApps.associations.added = {
"x-scheme-handler/https" = "firefox.desktop";
"x-scheme-handler/http" = "firefox.desktop";
};
xdg.mimeApps.defaultApplications = {
"x-scheme-handler/https" = "firefox.desktop";
"x-scheme-handler/http" = "firefox.desktop";
"text/html" = "firefox.desktop";
};
};
}

View file

@ -0,0 +1,88 @@
{ config, lib, ... }:
with lib;
let
tmuxFix = {
env = {
TERM = "xterm-256color";
};
};
in
{
programs.alacritty = mkIf config.desktop.enableSwayStack {
enable = true;
settings = {
font = {
normal = {
family = "JetBrainsMono Nerd Font Mono";
style = "Regular";
};
size = 10.0;
};
colors = {
primary = {
background = "#2e3440";
foreground = "#d8dee9";
dim_foreground = "#a5abb6";
};
cursor = {
text = "#2e3440";
cursor = "#d8dee9";
};
vi_mode_cursor = {
text = "#2e3440";
cursor = "#d8dee9";
};
selection = {
text = "CellForeground";
background = "#4c566a";
};
search = {
matches = {
foreground = "CellBackground";
background = "#88c0d0";
};
};
footer_bar = {
background = "#434c5e";
foreground = "#d8dee9";
};
normal = {
black = "#3b4252";
red = "#bf616a";
green = "#a3be8c";
yellow = "#ebcb8b";
blue = "#81a1c1";
magenta = "#b48ead";
cyan = "#88c0d0";
white = "#e5e9f0";
};
bright = {
black = "#4c566a";
red = "#bf616a";
green = "#a3be8c";
yellow = "#ebcb8b";
blue = "#81a1c1";
magenta = "#b48ead";
cyan = "#8fbcbb";
white = "#eceff4";
};
dim = {
black = "#373e4d";
red = "#94545d";
green = "#809575";
yellow = "#b29e75";
blue = "#68809a";
magenta = "#8c738c";
cyan = "#6d96a5";
white = "#aeb3bb";
};
};
window = {
opacity = 1;
};
} // tmuxFix;
};
}

View file

@ -0,0 +1,52 @@
{ lib, config, pkgs, ... }:
with lib;
let
desktopPackages = with pkgs; [
xwayland
grim
slurp
wl-clipboard
clipman
wf-recorder
(nerdfonts.override { fonts = [ "JetBrainsMono" ]; })
qt5ct
libsForQt5.qtstyleplugin-kvantum
font-awesome
nordzy-cursor-theme
jetbrains-mono
xdg-utils
libnotify
];
in
{
imports = [
./sway.nix
./alacritty.nix
./swaylock.nix
./waybar.nix
./wofi.nix
./mako.nix
];
options.desktop.enableSwayStack = mkOption {
type = types.bool;
default = true;
};
config = mkIf config.desktop.enableSwayStack {
home.packages = desktopPackages;
# Theming GTK
gtk = {
enable = true;
theme = {
name = "Nordic-darker";
package = pkgs.nordic;
};
cursorTheme = {
name = "Nordzy-cursors";
package = pkgs.nordzy-cursor-theme;
};
};
};
}

View file

@ -0,0 +1,29 @@
{ lib, config, ... }:
with lib;
{
services.mako = mkIf config.desktop.enableSwayStack {
enable = true;
layer = "overlay";
anchor = "top-right";
font = "JetBrainsMono Nerd Font 10";
backgroundColor = "#3b4252";
textColor = "#d8dee9";
width = 330;
height = 100;
borderRadius = 2;
defaultTimeout = 15000;
extraConfig = ''
[urgency=low]
border-color=#434c5e
[urgency=normal]
border-color=#4c566a
[urgency=high]
default-timeout=0
border-color=#bf616a
'';
};
}

View file

@ -0,0 +1,245 @@
{ config, pkgs, lib, ... }:
with lib;
let
gnomeSchema = "org.gnome.desktop.interface";
monitorModule = types.submodule {
options = {
name = mkOption {
type = types.str;
};
resolution = mkOption {
type = types.str;
};
position = mkOption {
type = types.str;
};
defaultWorkspace = mkOption {
type = types.int;
};
};
};
in
{
options = {
desktop.monitors = mkOption {
type = types.listOf monitorModule;
};
};
config.wayland.windowManager.sway = mkIf config.desktop.enableSwayStack {
enable = true;
#systemd.enable = false;
config = rec {
modifier = "Mod4";
left = "left";
right = "right";
up = "up";
down = "down";
terminal = "${pkgs.alacritty}/bin/alacritty";
menu = "${pkgs.wofi}/bin/wofi --show drun,run";
fonts = {
names = [ "pango:JetBrainsMono Nerd Font Mono" ];
size = 11.0;
};
input = {
"*" = {
xkb_layout = "fr";
# xkb_options = "compose:ralt";
};
};
seat = {
"seat0" = {
"xcursor_theme" = "Nordzy-cursors";
};
};
output = builtins.listToAttrs
(builtins.map
(monitor: {
name = monitor.name;
value = {
resolution = monitor.resolution;
position = monitor.position;
};
})
config.desktop.monitors) // {
"*".bg = "/home/dala/Perso/wallpapers/tanuki.jpg fill";
};
workspaceOutputAssign = map
(monitor: {
output = monitor.name;
workspace = builtins.toString monitor.defaultWorkspace;
})
config.desktop.monitors;
startup = [
{
command = ''
${pkgs.swayidle}/bin/swayidle -w \
timeout 1200 '${pkgs.swaylock}/bin/swaylock -f' \
timeout 1800 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on"' \
before-sleep '${pkgs.swaylock}/bin/swaylock -f'
'';
}
{ command = "${pkgs.nextcloud-client}/bin/nextcloud --background"; }
{ command = "${pkgs.keepassxc}/bin/keepassxc"; }
{
command = ''
${pkgs.wl-clipboard}/bin/wl-paste -t text --watch ${pkgs.clipman}/bin/clipman store --no-persist
'';
}
{
command = "${pkgs.glib}/bin/gsettings set ${gnomeSchema} gtk-theme 'Nordic'";
always = true;
}
{
command = "${pkgs.glib}/bin/gsettings set ${gnomeSchema} cursor-theme 'Nordzy-cursors'";
always = true;
}
{
command = "${pkgs.glib}/bin/gsettings set ${gnomeSchema} font-name 'JetBrainsMono Nerd Font Mono'";
always = true;
}
];
modes = {
resize = {
"Left" = "resize shrink width 10px";
"Down" = "resize grow height 10px";
"Up" = "resize shrink height 10px";
"Right" = "resize grow width 10px";
"Return" = "mode default";
"Escape" = "mode default";
};
};
gaps = {
inner = 5;
smartGaps = true;
};
floating = {
modifier = "${modifier} normal";
};
bars = [{
command = "${pkgs.waybar}/bin/waybar";
}];
keybindings = {
"${modifier}+Return" = "exec ${terminal}";
"${modifier}+Shift+q" = "kill";
"${modifier}+d" = "exec ${menu}";
"${modifier}+Shift+r" = "reload";
"${modifier}+Shift+e" = "exec swaymsg exit";
"${modifier}+Shift+l" = "exec swaylock -f";
"${modifier}+Left" = "focus left";
"${modifier}+Down" = "focus down";
"${modifier}+Up" = "focus up";
"${modifier}+Right" = "focus right";
"${modifier}+Shift+Left" = "move left";
"${modifier}+Shift+Down" = "move down";
"${modifier}+Shift+Up" = "move up";
"${modifier}+Shift+Right" = "move right";
"${modifier}+1" = "workspace 1";
"${modifier}+2" = "workspace 2";
"${modifier}+3" = "workspace 3";
"${modifier}+4" = "workspace 4";
"${modifier}+5" = "workspace 5";
"${modifier}+6" = "workspace 6";
"${modifier}+7" = "workspace 7";
"${modifier}+8" = "workspace 8";
"${modifier}+9" = "workspace 9";
"${modifier}+0" = "workspace 10";
"${modifier}+ampersand" = "workspace 1";
"${modifier}+eacute" = "workspace 2";
"${modifier}+quotedbl" = "workspace 3";
"${modifier}+apostrophe" = "workspace 4";
"${modifier}+parenleft" = "workspace 5";
"${modifier}+minus" = "workspace 6";
"${modifier}+egrave" = "workspace 7";
"${modifier}+underscore" = "workspace 8";
"${modifier}+ccedilla" = "workspace 9";
"${modifier}+agrave" = "workspace 10";
"${modifier}+Shift+1" = "move container to workspace 1";
"${modifier}+Shift+2" = "move container to workspace 2";
"${modifier}+Shift+3" = "move container to workspace 3";
"${modifier}+Shift+4" = "move container to workspace 4";
"${modifier}+Shift+5" = "move container to workspace 5";
"${modifier}+Shift+6" = "move container to workspace 6";
"${modifier}+Shift+7" = "move container to workspace 7";
"${modifier}+Shift+8" = "move container to workspace 8";
"${modifier}+Shift+9" = "move container to workspace 9";
"${modifier}+Shift+0" = "move container to workspace 10";
"${modifier}+Shift+ampersand" = "move container to workspace 1";
"${modifier}+Shift+eacute" = "move container to workspace 2";
"${modifier}+Shift+quotedbl" = "move container to workspace 3";
"${modifier}+Shift+apostrophe" = "move container to workspace 4";
"${modifier}+Shift+parenleft" = "move container to workspace 5";
"${modifier}+Shift+minus" = "move container to workspace 6";
"${modifier}+Shift+egrave" = "move container to workspace 7";
"${modifier}+Shift+underscore" = "move container to workspace 8";
"${modifier}+Shift+ccedilla" = "move container to workspace 9";
"${modifier}+Shift+agrave" = "move container to workspace 10";
"${modifier}+h" = "splith";
"${modifier}+v" = "splitv";
"${modifier}+s" = "layout stacking";
"${modifier}+w" = "layout tabbed";
"${modifier}+e" = "layout toggle split";
"${modifier}+f" = "fullscreen";
"${modifier}+Shift+space" = "floating toggle";
"${modifier}+space" = "focus mode_toggle";
"${modifier}+a" = "focus parent";
"${modifier}+Shift+parenright" = "move scratchpad";
"${modifier}+parenright" = "scratchpad show";
"${modifier}+r" = "mode resize";
"XF86AudioRaiseVolume" = "exec --no-startup-id pactl set-sink-volume 0 +5%"; #increase sound volume
"XF86AudioLowerVolume" = "exec --no-startup-id pactl set-sink-volume 0 -5%"; #decrease sound volume
"XF86AudioMute" = "exec --no-startup-id pactl set-sink-mute 0 toggle"; # mute sound
"XF86MonBrightnessUp" = "exec --no-startup-id light -A 10";
"XF86MonBrightnessDown" = "exec --no-startup-id light -U 10";
"Control+XF86AudioMute" = "exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle";
"Print" = "exec grim -g \"$(${pkgs.slurp}/bin/slurp)\" -t png - | wl-copy --type image/png";
};
};
extraConfig = ''
default_border pixel
for_window [class=".*"] inhibit_idle fullscreen
for_window [app_id=".*"] inhibit_idle fullscreen
'';
extraSessionCommands = ''
export WLR_NO_HARDWARE_CURSORS=1
export XDG_CURRENT_DESKTOP=sway
export _JAVA_AWT_WM_NONREPARENTING=1
export NIXOS_OZONE_WL=1
export QT_QPA_PLATFORM=wayland
export QT_QPA_PLATFORMTHEME=qt5ct
export QT_WAYLAND_DISABLE_WINDOWDECORATION=1
export MOZ_ENABLE_WAYLAND=1
export SDL_VIDEODRIVER=wayland
'';
};
}

View file

@ -0,0 +1,52 @@
{ lib, config, ... }:
with lib;
{
programs.swaylock = mkIf config.desktop.enableSwayStack {
enable = true;
settings = {
scaling = "fill";
font = "JetBrainsMono";
font-size = 20;
show-keyboard-layout = true;
disable-caps-lock-text = true;
indicator-caps-lock = true;
ignore-empty-password = true;
show-failed-attempts = true;
line-uses-inside = true;
indicator-radius = 70;
indicator-thickness = 15;
color = "#00000000";
inside-color = "#2e3440a0";
inside-ver-color = "#4c566aa0";
inside-wrong-color = "#bf616aa0";
inside-clear-color = "#434c5ea0";
inside-caps-lock-color = "#d08770a0";
text-color = "#d8dee9d0";
text-clear-color = "#d8dee9d0";
text-ver-color = "#d8dee9d0";
text-wrong-color = "#d8dee9d0";
layout-bg-color = "#00000000";
layout-text-color = "#d8dee9d0";
line-color = "#2e3440e0";
line-clear-color = "#2e3440e0";
line-caps-lock-color = "#2e3440e0";
line-ver-color = "#2e3440e0";
line-wrong-color = "#2e3440e0";
separator-color = "#2e3440e0";
ring-color = "#5e81acf0";
ring-clear-color = "#5e81aca0";
ring-caps-lock-color = "#bf616af0";
ring-ver-color = "#81a1c1f0";
ring-wrong-color = "#d08770f0";
bs-hl-color = "#d08770a0";
key-hl-color = "#81a1c1a0";
};
};
}

View file

@ -0,0 +1,275 @@
{ config, lib, ... }:
with lib;
{
programs.waybar = mkIf config.desktop.enableSwayStack {
enable = true;
#systemd.enable = false;
settings = [{
layer = "top";
position = "top";
height = 30;
modules-left = [
"sway/workspaces"
"sway/mode"
];
modules-center = [
"sway/window"
];
modules-right = [
"memory"
"cpu"
"pulseaudio"
"network"
"battery"
"tray"
"sway/language"
"clock"
];
"sway/workspaces" = {
"disable-scroll" = true;
"all-outputs" = false;
"format" = "{icon}";
"format-icons" = {
"1:term" = "";
"2:web" = "";
"3:email" = "";
"4:im" = "";
"5:dev" = "";
"6:music" = "";
"7:graph" = "";
"8:any" = "";
"9:any" = "";
"10:aux" = "";
};
};
"tray" = {
"icon-size" = 18;
"spacing" = 12;
};
"memory" = {
"format" = "{percentage:3}% <big>󰍛</big>";
"states" = {
"warning" = 70;
"critical" = 90;
};
};
"cpu" = {
"format" = "{usage:3}% <big></big>";
"states" = {
"warning" = 70;
"critical" = 90;
};
};
"pulseaudio" = {
"format" = "{volume:3}% <big>{icon}</big>";
"format-bluetooth" = "<big>{icon}</big>";
"format-muted" = "<big>󰝟<\big>";
"format-icons" = {
"headphone" = "";
"hands-free" = "";
"headset" = "";
"phone" = "";
"portable" = "";
"car" = "";
"default" = [ "" ];
};
"on-click" = "pavucontrol";
"on-scroll-up" = "pamixer -ui 2 && pamixer --get-volume > $SWAYSOCK.wob";
"on-scroll-down" = "pamixer -ud 2 && pamixer --get-volume > $SWAYSOCK.wob";
};
"network" = {
"format-wifi" = "{essid} <big></big>";
"format-ethernet" = "<big></big>";
"format-disconnected" = "<big>󰌙</big>";
"format-linked" = "<big></big>";
"format-alt" = "{ifname}: {ipaddr}/{cidr}";
"tooltip-format-ethernet" = "<big></big> {bandwidthDownBits} <big></big> {bandwidthUpBits}";
"tooltip-format-wifi" = "<big></big>{bandwidthDownBits} <big></big> {bandwidthUpBits}";
};
"battery" = {
"states" = {
"5pct" = 5;
"10pct" = 10;
"20pct" = 20;
"30pct" = 30;
"40pct" = 40;
"50pct" = 50;
"60pct" = 60;
"70pct" = 70;
"80pct" = 80;
"90pct" = 90;
"full" = 100;
};
"format" = "{capacity:3}% <big>{icon}</big>";
"format-icons" = {
"5pct" = "󰂃";
"10pct" = "󰁺";
"20pct" = "󰁻";
"30pct" = "󰁼";
"40pct" = "󰁽";
"50pct" = "󰁾";
"60pct" = "󰁿";
"70pct" = "󰂀";
"80pct" = "󰂁";
"90pct" = "󰂂";
"full" = "󰁹";
};
"on-click" = "notify-send -u low -t 3000 'Battery Status' \"$(acpi)\"";
};
"clock" = {
"format-alt" = "{:%A, %B %d}";
"tooltip-format" = "<big>{:%Y %B}</big>\n<tt>{calendar}</tt>";
};
}];
style = ''
@keyframes blink-warning {
to {
background-color: #bf616a;
}
}
@keyframes blink-critical {
to {
color: #2e3440;
background-color: #bf616a;
}
}
* {
border: none;
border-radius: 0;
font-family: JetBrainsMono, JetBrainsMono Nerd Font Mono, monospace;
font-size: 14px;
min-height: 0;
box-shadow: none;
text-shadow: none;
}
window#waybar {
background-color: #3b4252;
color: #e5e9f0;
opacity: 0.9;
}
#window {
font-family: JetBrainsMono, JetBrainsMono Nerd Font Mono, sans-serif;
}
#workspaces {
background-color: #4c566a;
}
#workspaces button {
padding: 3px 9px 0px 9px;
background: transparent;
color: #e5e9f0;
border-bottom: 3px solid transparent;
font-weight: 900;
}
#workspaces button.focused {
background-color: #434c5e;
color: #eceff4;
border-bottom: 3px solid #ebcb8b;
}
#workspaces button:hover {
background-color: #5e81ac;
}
#mode {
padding: 0px 9px;
background-color: #a3be8c;
color: #3b4252;
font-family: JetBrains Mono, sans-serif;
font-size: 14px;
font-weight: bold;
}
#clock, #language, #pulseaudio, #tray, #memory, #cpu, #battery, #network {
padding: 0px 8px;
color: #d8dee9;
font-size: 14px;
}
#clock {
background-color: #4c566a;
font-weight: bold;
}
#language {
color: #d8dee9;
font-weight: bold;
}
#pulseaudio {
}
#pulseaudio.muted {
color: #d08770;
}
#tray {
margin-left: 10px;
}
#cpu {
padding-left: 0px;
font-size: 14px;
}
#cpu.warning {
color: #ebcb8b;
}
#cpu.critical {
color: #d08770;
}
#memory {
padding-left: 0px;
font-size: 14px;
}
#memory.warning {
color: #ebcb8b;
}
#memory.critical {
color: #d08770;
}
#battery {
font-size: 14px;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#battery.20pct.discharging {
animation-name: blink-warning;
animation-duration: 3s;
}
#battery.10pct.discharging {
animation-name: blink-critical;
animation-duration: 2s;
}
'';
};
}

View file

@ -0,0 +1,74 @@
{ pkgs, config, lib, ... }:
with lib;
{
programs.wofi = mkIf config.desktop.enableSwayStack {
enable = true;
settings = {
allow_images = true;
allow_markup = true;
insensitive = true;
hide_scroll = true;
no_actions = false;
term = "${pkgs.alacritty}/bin/alacritty";
width = "35%";
lines = 8;
always_parse_args = true;
};
style = ''
#window {
background-color: transparent;
border-radius: 15px;
font-family: sans-serif;
animation: fadeIn;
animation-duration: 0.2s;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
#outer-box {
margin: 15px;
border-radius: 15px;
background-color: #3b4252;
box-shadow: 0px 0px 5px 0 #0F0F0F;
}
#inner-box {
color: #d8dee9;
padding: 10px;
padding-top: 5px;
}
#input {
color: #e5e9f0;
border: 2px solid #5e81ac;
background-color: #4c566a;
padding: 6px;
margin: 15px;
margin-bottom: 0px;
font-size: 16px;
border-radius: 5px;
}
#entry {
border-radius: 5px;
padding: 7px;
margin: 0px 5px 0px 5px;
}
#text {
font-size: 16px;
padding: 7px;
color: #d8dee9;
}
#img {
padding: 4px;
}
'';
};
}

View file

@ -0,0 +1,35 @@
{ config, lib, pkgs, ... }:
with lib;
{
imports = [
./embedded.nix
];
options.development.enableGit = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Enable git and its configuration.
'';
};
config.programs.git = mkIf config.development.enableGit {
enable = true;
package = pkgs.gitAndTools.gitFull;
userName = "Victor Mignot";
userEmail = "dala@dalaran.fr";
signing = mkIf config.enableGPGKeyring {
key = "BEAFED3D";
signByDefault = true;
};
extraConfig = {
init = {
defaultBranch = "main";
};
core = {
editor = "${pkgs.neovim}/bin/nvim";
};
};
};
}

View file

@ -0,0 +1,22 @@
{ lib, config, pkgs, ... }:
with lib;
{
options.development.embedded.enableTools = mkOption {
type = types.bool;
default = false;
example = true;
description = ''
Enable embedded tools.
'';
};
options.development.embedded.toolsList = mkOption {
type = types.listOf types.package;
default = with pkgs; [
qemu
minicom
];
};
config.home.packages = lib.mkIf config.development.embedded.enableTools config.development.embedded.toolsList;
}

View file

@ -0,0 +1,31 @@
{ lib, pkgs, config, ... }:
with lib;
{
options.enableFishShell = mkOption {
type = types.bool;
};
config.programs.fish = mkIf config.enableFishShell {
enable = true;
plugins = [
{
name = "bobthefish";
src = pkgs.fetchFromGitHub {
owner = "oh-my-fish";
repo = "theme-bobthefish";
rev = "c2c47dc964a257131b3df2a127c2631b4760f3ec";
sha256 = "sha256-LB4g+EA3C7OxTuHfcxfgl8IVBe5NufFc+5z9VcS0Bt0=";
fetchSubmodules = true;
};
}
];
shellInit = ''
set -g theme_color_scheme nord
if [ -z $DISPLAY ] && [ "$(tty)" = /dev/tty1 ]
exec ${pkgs.sway}/bin/sway
end
'';
};
}

View file

@ -0,0 +1,24 @@
{ config, lib, ... }:
with lib;
{
options.enableGPGKeyring = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Add GPG keyring and GPG Agent configuration.
'';
};
config = mkIf config.enableGPGKeyring {
programs.gpg.enable = true;
services.gpg-agent = {
enable = true;
enableScDaemon = true;
enableSshSupport = true;
sshKeys = [ "40DE2FEE4D3C5E2C" ];
pinentryFlavor = "curses";
};
};
}

View file

@ -0,0 +1,125 @@
{ lib, pkgs, config, ... }:
with lib;
let
mailAccountModule = types.submodule {
isPrimary = mkOption {
type = types.bool;
default = false;
};
mailAddress = mkOption {
type = types.str;
};
mailPasswdEval = mkOption {
type = types.str;
};
imapHost = mkOption {
type = types.str;
};
smtpHost = mkOption {
type = types.str;
};
};
defaultExtraMailboxes = [
"Archive"
"Receipts"
"Junk"
"Drafts"
"Sent"
"Trash"
];
signature = {
text = ''
Victor Mignot
'';
showSignature = "append";
};
hasNoAddress = config.communication.mailAccounts == null;
in
{
options.communication.mailAccounts = mkOption {
type = types.nullOr (types.attrsOf mailAccountModule);
default = null;
};
config = mkIf (!hasNoAddress) {
accounts.email.accounts = builtins.mapAttrs
(name: value: {
primary = value.isPrimary;
address = value.mailAddress;
userName = value.mailAddress;
realName = "Victor Mignot";
imap.host = value.imapHost;
smtpHost = value.smtpHost;
passwordCommand = value.mailPasswdEval;
inherit signature;
mbsync = {
enable = true;
create = "both";
expunge = "both";
patterns = [ "*" ];
subFolders = "Verbatim";
};
msmtp.enable = true;
neomutt = {
enable = true;
mailboxName = "${name}/Inbox";
extraMailboxes = map
(mb: {
mailbox = mb;
name = "${name}/${mb}";
})
defaultExtraMailboxes;
};
})
config.communication.mailAccounts;
services.mbsync.enable = true;
programs.mbsync.enable = true;
accounts.email.maildirBasePath = "Mail";
programs.neomutt = {
enable = true;
sidebar.enable = true;
checkStatsInterval = 30;
sort = "reverse-date";
extraConfig = ''
set edit_headers = yes
set use_from = yes
set send_charset = "utf-8"
color body brightwhite default ^[[:space:]].*
color body yellow default ^(diff).*
color body brightwhite default ^(\s).*
color body cyan default ^(Signed-off-by).*
color body cyan default ^(Docker-DCO-1.1-Signed-off-by).*
color body brightwhite default ^(Cc)
color body yellow default "^diff \-.*"
color body brightwhite default "^index [a-f0-9].*"
color body brightblue default "^---$"
color body white default "^\-\-\- .*"
color body white default "^[\+]{3} .*"
color body green default "^[\+][^\+]+.*"
color body red default "^\-[^\-]+.*"
color body brightblue default "^@@ .*"
color body green default "LGTM"
color body brightmagenta default "-- Commit Summary --"
color body brightmagenta default "-- File Changes --"
color body brightmagenta default "-- Patch Links --"
color body green default "^Merged #.*"
color body red default "^Closed #.*"
color body brightblue default "^Reply to this email.*"
'';
};
};
}

View file

@ -0,0 +1,165 @@
{ lib, config, pkgs, ... }:
with lib;
{
options.desktop.enableNeovim = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Whether to use Neovim and its config.
'';
};
config.home.sessionVariables."EDITOR" = mkIf config.desktop.enableNeovim "${pkgs.neovim}/bin/nvim";
config.programs.neovim = mkIf config.desktop.enableNeovim {
enable = true;
viAlias = true;
vimAlias = true;
vimdiffAlias = true;
extraConfig = ''
luafile ${./luaconfig/settings.lua}
luafile ${./luaconfig/keybindings.lua}
luafile ${./luaconfig/lspconfig.lua}
'';
extraPackages = with pkgs; [
nixfmt
rnix-lsp
nil
ripgrep
entr
];
plugins = with pkgs.vimPlugins; [
# Theming
{
plugin = onenord-nvim;
type = "lua";
config = ''
require('onenord').setup()
'';
}
{
plugin = lualine-nvim;
type = "lua";
config = ''
require('lualine').setup()
'';
}
vim-devicons
# Utility plugins
{
plugin = nerdtree;
type = "lua";
config = ''
vim.g.NERDTreeShowHidden = 1
vim.keymap.set('n', '<C-t>', ':NERDTreeToggle<CR>', { desc = 'Toogle NERDTree pane' })
vim.keymap.set('n', '<C-s>', ':NERDTreeFind<CR>', { desc = 'Search file in NERDTree' })
vim.keymap.set('n', '<C-f>', ':NERDTreeFocus<CR>', { desc = 'Focus on the NERDTreePane' })
-- Keep the same NERDTree pane on each window
vim.api.nvim_create_autocmd("BufWinEnter", { pattern = "*", command = "if getcmdwintype() == \'\' | silent NERDTreeMirror | endif" })
'';
}
nerdtree-git-plugin
{
plugin = toggleterm-nvim;
type = "lua";
config = ''
require("toggleterm").setup{}
vim.keymap.set('n', 'tf', ':ToggleTerm direction=float<CR>', { desc = 'Open a new terminal in float buffer' })
vim.keymap.set('n', 'tt', ':ToggleTerm direction=tab<CR>', { desc = 'Open a new terminal in a new tab' })
vim.keymap.set('n', 'tv', ':ToggleTerm direction=vertical<CR>', { desc = 'Open in a vertical splitted buffer' })
vim.keymap.set('n', 'th', ':ToggleTerm<CR>', { desc = 'Open in a horizontal splitted buffer' })
'';
}
{
plugin = neogit;
type = "lua";
config = ''
require('neogit').setup {}
'';
}
{
plugin = gitsigns-nvim;
type = "lua";
config = ''
require('gitsigns').setup()
'';
}
vim-multiple-cursors
vim-sleuth
vim-commentary
{
plugin = telescope-nvim;
type = "lua";
config = ''
local telescope = require('telescope.builtin')
vim.keymap.set('n', 'ff', telescope.find_files, { desc = 'Search file with Telescope' })
vim.keymap.set('n', 'fg', telescope.live_grep, { desc = 'Live grep with Telescope'})
vim.keymap.set('n', 'fb', telescope.buffers, { desc = 'Search amongst current buffers (opened files)'})
vim.keymap.set('n', 'fh', telescope.help_tags, { desc = 'Search within nvim manual'})
vim.keymap.set('n', 'fs', telescope.lsp_workspace_symbols, { desc = 'Search symbol' })
'';
}
plenary-nvim
telescope-fzy-native-nvim
# Language support plugins
vim-nix
vim-nixhash
{
plugin = rust-vim;
type = "lua";
config = ''
vim.g.rustfmt_autosave = 1
'';
}
vim-markdown
markdown-preview-nvim
{
plugin = vimtex;
type = "viml";
config = ''
let g:vimtex_view_method = 'zathura'
let g:vimtex_compiler_method = 'tectonic'
let g:vimtex_compiler_tectonic = {
\'out_dir' : ' ',
\'hooks' : [],
\'options' : [
\ '--keep-logs',
\ '--synctex',
\ '-Zshell-escape',
\ '-Zshell-escape-cwd=$PWD'
\],
\}
'';
}
# Autocompletion and LSP server
nvim-lspconfig
nvim-cmp
cmp-path
cmp-cmdline
cmp-buffer
cmp-nvim-lsp
vim-vsnip
];
};
config.xdg.configFile.nvim = mkIf config.desktop.enableNeovim {
source = ./luaconfig;
recursive = true;
};
}

View file

@ -0,0 +1,11 @@
-- Navigate around panes
vim.keymap.set('n', '<C-Left>', '<C-w>h', { desc = 'Navigate to left pane' })
vim.keymap.set('n', '<C-Right>', '<C-w>l', { desc = 'Navigate to right pane' })
vim.keymap.set('n', '<C-Up>', '<C-w>k', { desc = 'Navigate to upper pane' })
vim.keymap.set('n', '<C-Down>', '<C-w>j', { desc = 'Toogle lower pane' })
-- Move panes position
vim.keymap.set('n', '<C-S-Left>', '<C-W>H', { desc = 'Navigate to left pane' })
vim.keymap.set('n', '<C-S-Right>', '<C-W>L', { desc = 'Navigate to right pane' })
vim.keymap.set('n', '<C-S-Up>', '<C-W>K', { desc = 'Navigate to upper pane' })
vim.keymap.set('n', '<C-S-Down>', '<C-W>J', { desc = 'Toogle lower pane' })

View file

@ -0,0 +1,94 @@
-- Nvim LSP Config
local map_opts = { noremap=true, silent=true }
vim.keymap.set('n', '<space>e', vim.diagnostic.open_float, map_opts)
vim.keymap.set('n', '<space>p', vim.diagnostic.goto_prev, map_opts)
vim.keymap.set('n', '<space>n', vim.diagnostic.goto_next, map_opts)
vim.keymap.set('n', '<space>l', vim.diagnostic.setloclist, map_opts)
-- Enable keybinds on LSP server attach
local on_attach = function(client, bufnr)
-- Enable completion triggered by <C-x><C-o>
vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
-- Mappings
local bufopts = { noremap=true, silent=true, buffer=bufnr }
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts)
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts)
vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts)
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts)
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, bufopts)
vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, bufopts)
vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, bufopts)
vim.keymap.set('n', '<space>wl', function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, bufopts)
vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, bufopts)
vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, bufopts)
vim.keymap.set('n', '<space>ca', vim.lsp.buf.code_action, bufopts)
vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts)
vim.keymap.set('n', '<space>f', function() vim.lsp.buf.format { async = true } end, bufopts)
end
-- Set-up autocompletion
local cmp = require('cmp')
vim.opt.completeopt = {'menu', 'menuone', 'noselect'}
cmp.setup({
snippet = {
-- Necessary snippet engine
expand = function (args)
vim.fn["vsnip#anonymous"](args.body)
end,
},
window = {
-- completion = cmp.config.window.bordered(),
-- documentation = cmp.config.window.bordered,
},
mapping = cmp.mapping.preset.insert({
['<C-u>'] = cmp.mapping.scroll_docs(4),
['<C-d>'] = cmp.mapping.scroll_docs(-4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.abort(),
['<CR>'] = cmp.mapping.confirm({select = true}),
}),
sources = cmp.config.sources({
{ name = 'nvim_lsp' },
{ name = 'vsnip' },
}, { { name = 'buffer' } }),
})
-- Language servers setup
local capabilities = require('cmp_nvim_lsp').default_capabilities()
require('lspconfig')['rust_analyzer'].setup {
on_attach = on_attach,
capabilities = capabilities,
}
require('lspconfig')['rnix'].setup {
on_attach = on_attach,
capabilities = capabilities
}
require('lspconfig')["nil_ls"].setup {
on_attach = on_attach,
capabilities = capabilities
}
require('lspconfig')['ltex'].setup {
on_attach = on_attach,
capabilities = capabilities
}
require('lspconfig')['texlab'].setup {
on_attach = on_attach,
capabilities = capabilities
}

View file

@ -0,0 +1,17 @@
-- Set line numbers
vim.opt.number = true
-- Replace tab with whitespaces
vim.opt.expandtab = true
-- Set tabs as 4 whitespaces
vim.opt.tabstop = 4
-- Set indentation adaptability
vim.opt.autoindent = true
-- Set default level of identation
vim.opt.shiftwidth = 4
-- Use the system clipboard
vim.opt.clipboard = 'unnamedplus'

View file

@ -0,0 +1,46 @@
{ lib, config, pkgs, ... }:
with lib;
let
tmuxExtraConfig = ''
set -ag terminal-overrides ",xterm-256color:RGB"
'';
in
{
options.enableTermux = mkOption {
type = types.bool;
default = true;
example = false;
description = ''
Enable termux and the associated config.
'';
};
config.programs.tmux = mkIf config.enableTermux {
enable = true;
# Make windows count start to 1
baseIndex = 1;
# Use 24h clock
clock24 = true;
shell = if config.enableFishShell then "${pkgs.fish}/bin/fish" else "${pkgs.bash}/bin/bash";
keyMode = "vi";
tmuxp.enable = true;
terminal = "tmux-256color";
plugins = with pkgs.tmuxPlugins; [
{
plugin = nord;
extraConfig = ''
set -g @plugin "arcticicestudio/nord-tmux"
'';
}
];
extraConfig = tmuxExtraConfig;
};
}

View file

@ -0,0 +1,11 @@
{ ... }:
{
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
programs.noisetorch.enable = true;
}