Compare commits

..

3 commits

Author SHA1 Message Date
777cc2f358
Remove static files 2024-07-23 18:05:03 +02:00
7b38456c37
Remove asahi overlay 2024-07-23 17:59:45 +02:00
509b44a31b
Remove macbook from repo 2024-07-23 17:58:52 +02:00
152 changed files with 4281 additions and 10462 deletions

View file

@ -4,8 +4,6 @@ keys:
- &nki_pc age1tt0peqg8zdfh74m5sdgwsczcqh036nhgmwvkqnvywll88uvmm9xs433rhm
- &nkagami_main age1n8tnmmgredzltzwkspag7aufhrn6034ny8ysjeulhkwdnf7vqqaqec4mg5
- &nkagami_do age1z2h24mjt80fryqupajkh3kg5r4sjgw65uqy489xeqxhqj8u2a9fsm3ff36
- &nki_yoga age1vhjhmxura35apu5zdwg5ur5r40xay45ld9szh07dy0ph9chgsu7shfm4h9
- &nki_framework age188tgu3psvywk6shq85mk2q0jdjwd0tcswzwlwu5pa5n3pndx75dq090z59
creation_rules:
- path_regex: kagami-air-m1/secrets\.yaml$
key_groups:
@ -18,20 +16,9 @@ creation_rules:
- *nki_pc
- *nkagami_main
- *nkagami_do
- *nki_framework
- path_regex: nki-home/secrets\.yaml$
- path_regex: nki-home/secrets/secrets\.yaml$
key_groups:
- age:
- *nki_pc
- *nkagami_main
- *nkagami_do
- path_regex: nki-yoga-g8/secrets\.yaml$
key_groups:
- age:
- *nki_yoga
- age1axvjllyv2gutngwmp3pvp4xtq2gqneldaq2c4nrzmaye0uwmk9lqsealdv # The machine itself
- path_regex: nki-framework/secrets\.yaml$
key_groups:
- age:
- *nki_framework
- age1vgh6kvee8lvxylm7z86fpl3xzjyjs4u3zdfkyf064rjvxk9fpumsew7n27 # The machine itself

View file

@ -1,3 +1,4 @@
# WARN: this file will get overwritten by $ cachix use <name>
{ pkgs, lib, ... }:
@ -6,8 +7,7 @@ let
toImport = name: value: folder + ("/" + name);
filterCaches = key: value: value == "regular" && lib.hasSuffix ".nix" key;
imports = lib.mapAttrsToList toImport (lib.filterAttrs filterCaches (builtins.readDir folder));
in
{
in {
inherit imports;
nix.settings.substituters = [ "https://cache.nixos.org/" ];
nix.settings.substituters = ["https://cache.nixos.org/"];
}

View file

@ -1,3 +1,4 @@
{
nix = {
settings = {

View file

@ -1,37 +1,18 @@
let
# Default shell
defaultShell =
{
lib,
pkgs,
config,
...
}:
with lib;
{
environment.shells = with pkgs; [
bash
fish
];
users.users = mkMerge [
{ nki.shell = pkgs.bash; }
# (mkIf (builtins.hasAttr "natsukagami" config.users.users) { natsukagami.shell = pkgs.fish; })
];
};
defaultShell = { lib, pkgs, config, ... }: with lib; {
environment.shells = with pkgs; [ bash fish ];
users.users = mkMerge [
{ nki.shell = pkgs.bash; }
# (mkIf (builtins.hasAttr "natsukagami" config.users.users) { natsukagami.shell = pkgs.fish; })
];
};
in
# Common stuff
{
lib,
pkgs,
config,
...
}:
with lib;
{
{ lib, pkgs, config, ... }:
with lib; {
imports = [
# defaultShell
./modules/services/nix-cache
./modules/services/nix-build-farm
];
## Packages

View file

@ -1,85 +0,0 @@
{
pkgs,
config,
lib,
...
}:
with lib;
{
homebrew.enable = true;
homebrew.brewPrefix = if pkgs.stdenv.isAarch64 then "/opt/homebrew/bin" else "/usr/local/bin";
homebrew.onActivation.cleanup = "zap";
homebrew.onActivation.upgrade = true;
# All needed taps
homebrew.taps = [
"homebrew/bundle"
"homebrew/cask"
"homebrew/core"
"homebrew/services"
];
homebrew.brews = [
# CLI tools
"pinentry-mac" # UI for Pin Entry on gpg Mac
{
name = "d-bus";
restart_service = "changed";
}
# U2F
"pam-u2f"
];
homebrew.casks = [
"blackhole-2ch"
"finicky"
"inkscape"
"yt-music"
"eloston-chromium"
# CLI, but doesn't yet work on Nix
# "sage"
];
# We don't really need to keep track of all these
homebrew.masApps = {
# # Safari Extensions
# "Keepa - Price Tracker" = 1533805339;
# "Vimari" = 1480933944;
# "Bitwarden" = 1352778147;
# "Save to Pocket" = 1477385213;
# "AdGuard for Safari" = 1440147259;
# "Refined GitHub" = 1519867270;
# # Productivity
# # "GoodNotes" = 1444383602;
# "Amphetamine" = 937984704; # Turns off auto display dimming and sleep for some time
# "Session Pal" = 1515213004;
# "Flow" = 1423210932;
# # "Taskheat" = 1431995750; # Always shown outdated!
# "Hidden Bar" = 1452453066;
# # Development
# "Developer" = 640199958;
# # "Xcode" = 497799835;
# # Chat
# "Messenger" = 1480068668;
# "LINE" = 539883307;
# "Slack" = 803453959;
# # Office
# "Keynote" = 409183694;
# "Microsoft Excel" = 462058435;
# "The Unarchiver" = 425424353;
# "Numbers" = 409203825;
# "Pages" = 409201541;
# ## Multimedia
# "DaVinci Resolve" = 571213070;
# "GarageBand" = 682658836;
# "iMovie" = 408981434;
};
}

View file

@ -1,77 +0,0 @@
{
config,
pkgs,
lib,
...
}:
{
imports = [
../modules/personal/fonts
./brew.nix
];
# List packages installed in system profile. To search by name, run:
# $ nix-env -qaP | grep wget
environment.systemPackages = with pkgs; [
podman
qemu
];
environment.shells = with pkgs; [ fish ];
# Use a custom configuration.nix location.
# $ darwin-rebuild switch -I darwin-config=$HOME/.config/nixpkgs/darwin/configuration.nix
# environment.darwinConfig = "$HOME/.config/nixpkgs/darwin/configuration.nix";
# Auto upgrade nix package and the daemon service.
# services.nix-daemon.enable = true;
# Create /etc/bashrc that loads the nix-darwin environment.
programs.zsh.enable = true; # default shell on catalina
programs.fish.enable = true;
## Networking related settings
networking.hostName = "nki-macbook";
environment.variables = {
EDITOR = ""; # don't set it by default
# Homebrew stuff
# LLVM!
# To use the bundled libc++ please add the following LDFLAGS:
LDFLAGS = lib.concatStringsSep " " [
"-L/opt/homebrew/opt/llvm/lib"
"-Wl,-rpath,/opt/homebrew/opt/llvm/lib"
"-L/opt/homebrew/opt/llvm/lib"
"$LDFLAGS"
];
CPPFLAGS = "-I/opt/homebrew/opt/llvm/include $CPPFLAGS";
};
environment.systemPath = lib.mkBefore [
# Missing from MacOS
"/usr/local/bin"
# LaTeX
"/usr/local/texlive/2021/bin/universal-darwin"
# Go
"/usr/local/go/bin"
# Ruby
"/opt/homebrew/opt/ruby@2.7/bin"
# .NET
"/usr/local/share/dotnet"
# LLVM!
"/opt/homebrew/opt/llvm/bin"
];
# Used for backwards compatibility, please read the changelog before changing.
# $ darwin-rebuild changelog
system.stateVersion = 4;
# Font configuration
users.users.nki = {
name = "nki";
home = "/Users/nki";
shell = "${config.home-manager.users.nki.programs.fish.package}/bin/fish";
};
}

910
flake.lock generated

File diff suppressed because it is too large Load diff

290
flake.nix
View file

@ -2,12 +2,10 @@
description = "nki's systems";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
nixos-hardware.url = "github:nixos/nixos-hardware";
darwin.url = "github:lnl7/nix-darwin/master";
darwin.inputs.nixpkgs.follows = "nixpkgs-unstable";
home-manager.url = "github:nix-community/home-manager/release-24.11";
home-manager.url = "github:nix-community/home-manager/release-24.05";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
home-manager-unstable.url = "github:nix-community/home-manager";
home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable";
@ -15,166 +13,113 @@
sops-nix.inputs.nixpkgs.follows = "nixpkgs-unstable";
sops-nix.inputs.nixpkgs-stable.follows = "nixpkgs";
deploy-rs.url = "github:Serokell/deploy-rs";
nur.url = "github:nix-community/NUR";
# --- Secure boot
lanzaboote = {
url = "github:nix-community/lanzaboote/v0.4.2";
url = github:nix-community/lanzaboote/v0.3.0;
inputs.nixpkgs.follows = "nixpkgs";
};
# --- Build tools
flake-utils.url = "github:numtide/flake-utils";
crane.url = "github:ipetkov/crane";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
arion.url = "github:hercules-ci/arion/v0.2.2.0";
flake-utils.url = github:numtide/flake-utils;
crane.url = github:ipetkov/crane;
arion.url = github:hercules-ci/arion;
lix-module = {
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.92.0.tar.gz";
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.90.0.tar.gz";
inputs.nixpkgs.follows = "nixpkgs";
};
# ---
# Imported apps
youmubot.url = "github:natsukagami/youmubot";
mpd-mpris = {
url = "github:natsukagami/mpd-mpris";
swayfx = {
url = github:WillPower3309/swayfx;
inputs.nixpkgs.follows = "nixpkgs";
};
dtth-phanpy.url = "git+ssh://gitea@git.dtth.ch/nki-dtth/phanpy?ref=dtth-fork";
conduit.url = "gitlab:famedly/conduit/v0.9.0";
nix-gaming.url = "github:fufexan/nix-gaming";
zen-browser.url = "github:youwen5/zen-browser-flake";
niri.url = "github:sodiboo/niri-flake";
mpd-mpris = {
url = github:natsukagami/mpd-mpris;
inputs.nixpkgs.follows = "nixpkgs";
};
dtth-phanpy.url = "git+ssh://gitea@git.dtth.ch/nki/phanpy?branch=dtth-fork";
conduit.url = "gitlab:famedly/conduit/v0.8.0";
nix-gaming.url = github:fufexan/nix-gaming;
# --- Sources
kakoune.url = "github:mawww/kakoune";
kakoune.url = github:mawww/kakoune;
kakoune.flake = false;
kak-lsp.url = "github:kakoune-lsp/kakoune-lsp/v18.1.3";
kak-lsp.url = github:kakoune-lsp/kakoune-lsp;
kak-lsp.flake = false;
nixos-m1.url = "github:tpwrules/nixos-apple-silicon";
nixos-m1.inputs.nixpkgs.follows = "nixpkgs";
# ---
# DEPLOYMENT ONLY! secrets
secrets.url = "git+ssh://git@github.com/natsukagami/nix-deploy-secrets";
};
outputs =
{
self,
darwin,
nixpkgs,
nixpkgs-unstable,
home-manager,
deploy-rs,
sops-nix,
...
}@inputs:
outputs = { self, nixpkgs, nixpkgs-unstable, home-manager, deploy-rs, sops-nix, nur, ... }@inputs:
let
overlays = import ./overlay.nix inputs;
lib = nixpkgs.lib;
applyOverlays =
{ ... }:
{
nixpkgs.overlays = lib.mkAfter overlays;
};
applyOverlays = { ... }: {
nixpkgs.overlays = lib.mkBefore overlays;
};
nixpkgsAsRegistry_ =
stable:
{ lib, ... }:
{
imports = [ applyOverlays ];
nix.registry.current-system.flake = self;
nix.registry.nixpkgs-unstable.flake = nixpkgs-unstable;
nixpkgs.config.allowUnfree = true;
nix.nixPath = lib.mkDefault [
"nixpkgs-unstable=${nixpkgs-unstable}"
];
};
nixpkgsAsRegistry_ = stable: { lib, ... }: {
imports = [ applyOverlays ];
nix.registry.current-system.flake = self;
nix.registry.nixpkgs-unstable.flake = nixpkgs-unstable;
nixpkgs.config.allowUnfree = true;
nix.nixPath = lib.mkDefault [
"nixpkgs-unstable=${nixpkgs-unstable}"
];
};
osuStable =
{ pkgs, ... }:
{
nix.settings = {
substituters = [ "https://nix-gaming.cachix.org" ];
trusted-public-keys = [ "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" ];
};
environment.systemPackages = [ inputs.nix-gaming.packages.${pkgs.hostPlatform.system}.osu-stable ];
programs.gamemode = {
enable = true;
enableRenice = true;
settings = {
general = {
renice = 10;
};
custom = {
start = "${pkgs.libnotify}/bin/notify-send 'GameMode started'";
end = "${pkgs.libnotify}/bin/notify-send 'GameMode ended'";
};
};
};
osuStable = { pkgs, ... }: {
nix.settings = {
substituters = [ "https://nix-gaming.cachix.org" ];
trusted-public-keys = [ "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" ];
};
environment.systemPackages = [ inputs.nix-gaming.packages.${pkgs.hostPlatform.system}.osu-stable ];
};
# Common Nix modules
common-nix =
stable:
{ ... }:
{
imports = [
(nixpkgsAsRegistry_ stable)
./common.nix
sops-nix.nixosModules.sops
inputs.lix-module.nixosModules.default
];
config.nix.settings.extra-deprecated-features = [ "url-literals" ]; # So lix won't complain
};
common-nixos =
stable:
{ ... }:
{
imports = [
./modules/my-tinc
./modules/common/linux
(common-nix stable)
inputs.secrets.nixosModules.common
inputs.nix-gaming.nixosModules.pipewireLowLatency
inputs.niri.nixosModules.niri
];
};
common-nix = stable: { ... }: {
imports = [
(nixpkgsAsRegistry_ stable)
./common.nix
sops-nix.nixosModules.sops
inputs.lix-module.nixosModules.default
];
};
common-nixos = stable: { ... }: {
imports = [
./modules/my-tinc
./modules/common/linux
(common-nix stable)
inputs.secrets.nixosModules.common
inputs.nix-gaming.nixosModules.pipewireLowLatency
];
};
mkPersonalSystem =
nixpkgs-module: system:
{
configuration,
homeManagerUsers ? { },
extraModules ? [ ],
includeCommonModules ? true,
}:
mkPersonalSystem = nixpkgs-module: system: { configuration
, homeManagerUsers ? { }
, extraModules ? [ ]
, includeCommonModules ? true
,
}:
let
home-manager-module =
if nixpkgs-module == inputs.nixpkgs then
inputs.home-manager
else if nixpkgs-module == inputs.nixpkgs-unstable then
inputs.home-manager-unstable
else
builtins.abort "Unknown nixpkgs module, use `nixpkgs` or `nixpkgs-unstable`";
if nixpkgs-module == inputs.nixpkgs then inputs.home-manager
else if nixpkgs-module == inputs.nixpkgs-unstable then inputs.home-manager-unstable
else builtins.abort "Unknown nixpkgs module, use `nixpkgs` or `nixpkgs-unstable`";
in
nixpkgs-module.lib.nixosSystem {
inherit system;
modules =
(
if includeCommonModules then
[
(common-nixos nixpkgs-module)
]
else
[ ]
)
++ [
(if includeCommonModules then [
(common-nixos nixpkgs-module)
] else [ ]) ++ [
configuration
# Home Manager
home-manager-module.nixosModules.home-manager
@ -183,63 +128,16 @@
home-manager.useUserPackages = true;
home-manager.users = homeManagerUsers;
}
]
++ extraModules;
};
kakoune-unwrapped-from-pkgs =
pkgs:
pkgs.kakoune-unwrapped.overrideAttrs (attrs: {
version = "r${builtins.substring 0 6 inputs.kakoune.rev}";
src = inputs.kakoune;
patches = [
# patches in the original package was already applied
];
});
nki-kakoune-from-pkgs =
pkgs:
pkgs.callPackage ./packages/common/nki-kakoune {
kakoune-unwrapped = kakoune-unwrapped-from-pkgs pkgs;
] ++ extraModules;
};
in
{
overlays = {
default = lib.composeManyExtensions overlays;
kakoune = final: prev: {
kakoune-unwrapped = kakoune-unwrapped-from-pkgs prev;
nki-kakoune = final.callPackage ./packages/common/nki-kakoune { };
};
};
overlays.default = lib.composeManyExtensions overlays;
packages.x86_64-linux.deploy-rs = deploy-rs.packages.x86_64-linux.default;
apps.x86_64-linux.deploy-rs = deploy-rs.apps.x86_64-linux.default;
packages.x86_64-linux.nki-kakoune = nki-kakoune-from-pkgs (
import nixpkgs-unstable { system = "x86_64-linux"; }
);
packages.aarch64-linux.nki-kakoune = nki-kakoune-from-pkgs (
import nixpkgs-unstable { system = "aarch64-linux"; }
);
packages.aarch64-darwin.nki-kakoune = nki-kakoune-from-pkgs (
import nixpkgs-unstable { system = "aarch64-darwin"; }
);
# MacBook configuration: nix-darwin + home-manager
darwinConfigurations."nki-macbook" = darwin.lib.darwinSystem rec {
system = "aarch64-darwin";
modules = [
(common-nix nixpkgs-unstable)
./darwin/configuration.nix
inputs.home-manager.darwinModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.nki = import ./home/macbook-home.nix;
}
];
};
# Home configuration
nixosConfigurations."kagamiPC" = mkPersonalSystem nixpkgs-unstable "x86_64-linux" {
configuration = ./nki-home/configuration.nix;
@ -252,17 +150,14 @@
homeManagerUsers.nki = import ./home/nki-x1c1.nix;
extraModules = [
inputs.lanzaboote.nixosModules.lanzaboote
(
{ ... }:
{
# Sets up secure boot
boot.loader.systemd-boot.enable = lib.mkForce false;
boot.lanzaboote = {
enable = true;
pkiBundle = "/etc/secureboot";
};
}
)
({ ... }: {
# Sets up secure boot
boot.loader.systemd-boot.enable = lib.mkForce false;
boot.lanzaboote = {
enable = true;
pkiBundle = "/etc/secureboot";
};
})
];
};
# framework configuration
@ -272,25 +167,16 @@
extraModules = [
inputs.lanzaboote.nixosModules.lanzaboote
inputs.nixos-hardware.nixosModules.framework-13-7040-amd
(
{ ... }:
{
# Sets up secure boot
boot.loader.systemd-boot.enable = lib.mkForce false;
boot.lanzaboote = {
enable = true;
pkiBundle = "/etc/secureboot";
};
}
)
({ ... }: {
# Sets up secure boot
boot.loader.systemd-boot.enable = lib.mkForce false;
boot.lanzaboote = {
enable = true;
pkiBundle = "/etc/secureboot";
};
})
];
};
# macbook nixos
nixosConfigurations."kagami-air-m1" = mkPersonalSystem nixpkgs "aarch64-linux" {
configuration = ./kagami-air-m1/configuration.nix;
homeManagerUsers.nki = import ./home/macbook-nixos.nix;
extraModules = [ inputs.nixos-m1.nixosModules.apple-silicon-support ];
};
# DigitalOcean node
nixosConfigurations."nki-personal-do" = mkPersonalSystem nixpkgs "x86_64-linux" {
@ -312,8 +198,8 @@
# This is highly advised, and will prevent many possible mistakes
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
}
// (inputs.flake-utils.lib.eachDefaultSystem (system: {
formatter = nixpkgs.legacyPackages.${system}.nixfmt-rfc-style;
} // (inputs.flake-utils.lib.eachDefaultSystem (system: {
formatter = nixpkgs.legacyPackages.${system}.nixpkgs-fmt;
}));
}

View file

@ -1,70 +1,57 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
kwallet =
{ pkgs, lib, ... }:
{
home.packages = with pkgs; [
kdePackages.kwallet
kdePackages.ksshaskpass
];
home.sessionVariables = {
# https://wiki.archlinux.org/title/KDE_Wallet#Using_the_KDE_Wallet_to_store_ssh_key_passphrases
SSH_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass;
SSH_ASKPASS_REQUIRE = "prefer";
};
# Enable this for sway
wayland.windowManager.sway.config.startup = [
{ command = "${pkgs.kdePackages.kwallet-pam}/libexec/pam_kwallet_init"; }
];
# Automatic dbus activation
xdg.dataFile."dbus-1/services/org.freedesktop.secrets.service".text = ''
[D-BUS Service]
Name=org.freedesktop.secrets
Exec=${pkgs.kdePackages.kwallet}/bin/kwalletd6
'';
kwallet = { pkgs, lib, ... }: {
home.packages = with pkgs; [ kdePackages.kwallet kdePackages.ksshaskpass ];
home.sessionVariables = {
# https://wiki.archlinux.org/title/KDE_Wallet#Using_the_KDE_Wallet_to_store_ssh_key_passphrases
SSH_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass;
SSH_ASKPASS_REQUIRE = "prefer";
};
# Enable this for sway
wayland.windowManager.sway.config.startup = [
{ command = "${pkgs.kdePackages.kwallet-pam}/libexec/pam_kwallet_init"; }
];
# Automatic dbus activation
xdg.dataFile."dbus-1/services/org.freedesktop.secrets.service".text = ''
[D-BUS Service]
Name=org.freedesktop.secrets
Exec=${pkgs.kdePackages.kwallet}/bin/kwalletd6
'';
};
in
{
imports = [
./modules/monitors.nix
./modules/linux/graphical
./modules/X11/xfce4-notifyd.nix
./modules/programs/discord.nix
kwallet
];
config = (
mkIf pkgs.stdenv.isLinux {
home.packages = with pkgs; [
psmisc # killall and friends
file # Query file type
zip
python3
config = (mkIf pkgs.stdenv.isLinux {
home.packages = with pkgs; [
psmisc # killall and friends
file # Query file type
pinentry-gnome3 # until pinentry-qt introduces caching
];
pinentry-gnome3 # until pinentry-qt introduces caching
];
systemd.user.startServices = "sd-switch";
systemd.user.startServices = "sd-switch";
# Audio stuff!
# services.easyeffects.enable = true;
# Audio stuff!
services.easyeffects.enable = true;
# Bluetooth controls
# services.mpris-proxy.enable = true;
# Bluetooth controls
# services.mpris-proxy.enable = true;
# Owncloud
services.owncloud-client.enable = true;
services.owncloud-client.package = pkgs.owncloud-client.overrideAttrs (attrs: {
buildInputs = attrs.buildInputs ++ [ pkgs.qt6.qtwayland ];
});
systemd.user.services.owncloud-client.Unit.After = [ "graphical-session.target" ];
# Owncloud
services.owncloud-client.enable = true;
services.owncloud-client.package = pkgs.owncloud-client.overrideAttrs (attrs: {
buildInputs = attrs.buildInputs ++ [ pkgs.qt6.qtwayland ];
});
# UDisks automounter
services.udiskie.enable = true;
}
);
# UDisks automounter
services.udiskie.enable = true;
});
}

View file

@ -1,18 +1,11 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, ... }:
{
imports = [
./kakoune.nix
./kakoune/kak.nix
./fish/fish.nix
./modules/programs/my-broot.nix
./modules/programs/my-waybar.nix
./modules/programs/my-sway
./modules/programs/my-niri.nix
./modules/programs/my-kitty
./modules/programs/openconnect-epfl.nix
./common-linux.nix
@ -21,9 +14,8 @@
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
# Temporarily disable the manuals
manual.html.enable = false;
# manual.manpage.enable = false;
# Enable the manual so we don't have to load it
manual.html.enable = true;
# Packages that are not in programs section
home.packages = with pkgs; [
@ -33,16 +25,11 @@
ripgrep
openssh
tea # gitea CLI (gh-like)
glab # gitlab CLI
fx # JSON viewer
glow # Markdown viewer
nix-output-monitor # Nice nix output formatting
unstable.scala-next
## PDF Processors
poppler_utils
# TeX
texlive.combined.scheme-full
inkscape # for TeX svg
## htop replacement
htop-vim
## Bitwarden
@ -53,9 +40,6 @@
zstd
atool
];
home.file.".latexmkrc".text = ''
$pdf_previewer = '${lib.getExe' pkgs.xdg-utils "xdg-open"}';
'';
home.sessionVariables = {
# Bat theme
@ -119,7 +103,7 @@
.kakrc
''}";
safe.directory = "*";
merge.conflictstyle = "zdiff3";
merge.conflictstyle = "diff3";
};
};

View file

@ -1,3 +1,8 @@
{
allowUnfree = true;
packageOverrides = pkgs: {
nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") {
inherit pkgs;
};
};
}

View file

@ -1,10 +1,4 @@
{
config,
options,
pkgs,
lib,
...
}:
{ config, options, pkgs, lib, ... }:
with lib;
let
@ -19,9 +13,6 @@ let
if which sway &>/dev/null
set -a CHOICES "sway"
end
if which niri-session &>/dev/null
set -a CHOICES "Niri"
end
if which startplasma-wayland &>/dev/null
set -a CHOICES "KDE Plasma"
end
@ -31,8 +22,6 @@ let
case "sway"
systemctl --user unset-environment NIXOS_OZONE_WL
exec sway
case "Niri"
exec niri-session
case "KDE Plasma"
exec ${pkgs.kdePackages.plasma-workspace}/libexec/plasma-dbus-run-session-if-needed startplasma-wayland
case '*'
@ -64,7 +53,8 @@ in
functions = {
rebuild = {
body = ''
pls nixos-rebuild --flake ~/.config/nixpkgs -L --log-format internal-json -v $argv \
command sudo -v && \
command sudo nixos-rebuild --flake ~/.config/nixpkgs -L --log-format internal-json -v $argv \
&| ${pkgs.nix-output-monitor}/bin/nom --json
'';
wraps = "nixos-rebuild";
@ -72,18 +62,19 @@ in
# Simplify nix usage!
nx = {
body = ''
argparse -s 'h/help' 'impure' 'u/unstable' 'g/git' -- $argv
if set -q _flag_help || test (count $argv) -eq 0
echo "nx [--impure] [-u/--unstable/-g/--git] {package} [args...]"
return 1
set impure
if test $argv[1] = "--impure"
set impure "--impure"
set argv $argv[2..]
end
if test (count $argv) -gt 0
nix run $impure nixpkgs#$argv[1] -- $argv[2..]
else
set -q _flag_impure && set impure "--impure"
set nixpkgs "nixpkgs"
set -q _flag_unstable && set nixpkgs "nixpkgs-unstable"
set -q _flag_git && set nixpkgs "github:nixOS/nixpkgs/nixpkgs-unstable"
nix run $impure $nixpkgs"#"$argv[1] -- $argv[2..]
echo "nx [--impure] {package} [args...]"
return 1
end
'';
wraps = "nix run";
description = "Runs an app from the nixpkgs store.";
};
@ -91,35 +82,25 @@ in
description = "Spawns a shell from the given nixpkgs packages";
wraps = "nix shell";
body = ''
function help
echo "nsh [--impure] [--impure] [-u/--unstable/-g/--git] {package}* [-c command args...]"
set impure
if test $argv[1] = "--impure"
set impure "--impure"
set argv $argv[2..]
end
argparse -s 'h/help' 'impure' 'u/unstable' 'g/git' -- $argv
if set -q _flag_help || test (count $argv) -eq 0
help
return 0
end
set packages $argv
set minusc (contains -i -- "-c" $argv)
if test -n "$minusc"
if test $minusc -eq 1
help
if test (count $argv) -gt 0
set minusc (contains -i -- "-c" $argv)
if test -z $minusc
nix shell $impure nixpkgs#$argv -c fish
else if test $minusc -eq (count $argv)
echo "nsh [--impure] {packages} [-c command args...]"
return 1
else
nix shell $impure nixpkgs#$argv[..(math $minusc - 1)] $argv[$minusc..]
end
set packages $argv[..(math $minusc - 1)]
set argv $argv[(math $minusc + 1)..]
else
set argv "fish" "-i"
end
if test (count $packages) -eq 0
help
echo "nsh [--impure] {packages} [-c command args...]"
return 1
end
set -q _flag_impure && set impure "--impure"
set nixpkgs "nixpkgs"
set -q _flag_unstable && set nixpkgs "nixpkgs-unstable"
set -q _flag_git && set nixpkgs "github:nixOS/nixpkgs/nixpkgs-unstable"
nix shell $impure $nixpkgs"#"$packages --command $argv
'';
};
# Grep stuff
@ -137,32 +118,9 @@ in
};
echo-today = "date +%F";
newfile = "mkdir -p (dirname $argv[-1]) && touch $argv";
# pls
pls = {
wraps = "sudo";
body = ''
set -l cmd "`"(string join " " -- $argv)"`"
echo "I-It's not like I'm gonna run "$cmd" for you or a-anything! Baka >:C" >&2
# Send a notification on password prompt
if command sudo -vn 2>/dev/null
# nothing to do, user already authenticated
else
# throw a notification
set notif_id (kitten notify -P \
-p ${./haruka.png} \
-a "pls" \
-u critical \
"A-a command requires your p-password" \
(printf "I-I need your p-password to r-run the following c-command:\n\n%s" $cmd))
command sudo -v -p "P-password please: "
kitten notify -i $notif_id ""
end
command sudo $argv
'';
};
};
tide = {
enable = true;
leftItems = options.programs.fish.tide.leftItems.default;
@ -173,12 +131,14 @@ in
cat = "bat --theme=GitHub ";
catp = "bat --theme=GitHub -p ";
l = "exa -l --color=always ";
e = "$EDITOR";
"cp+" = "rsync -avzP";
};
everywhereAbbrs = {
lsports = if pkgs.stdenv.isDarwin then "lsof -i -P | grep LISTEN" else "ss -tulp";
lsports =
if pkgs.stdenv.isDarwin
then "lsof -i -P | grep LISTEN"
else "ss -tulp";
};
shellInit = ''
@ -208,6 +168,13 @@ in
echo (__original_fish_title) - fish
end
# Set up an editor alias
if test -n "$EDITOR"
alias e="$EDITOR"
else
alias e="kak"
end
# Source iTerm2 integration
if test -e ~/.iterm2_shell_integration.fish; and test $__CFBundleIdentifier = "com.googlecode.iterm2"
source ~/.iterm2_shell_integration.fish
@ -230,11 +197,11 @@ in
bind -M default gl end-of-line
# Everywhere abbrs
${concatStringsSep "\n" (
mapAttrsToList (
k: v: "abbr --add --position anywhere -- ${k} ${escapeShellArg v}"
) config.programs.fish.everywhereAbbrs
)}
${
concatStringsSep "\n"
(mapAttrsToList (k: v: "abbr --add --position anywhere -- ${k} ${escapeShellArg v}")
config.programs.fish.everywhereAbbrs)
}
# Replace today with actual today
abbr --add --position anywhere today -f echo-today
@ -286,8 +253,8 @@ in
target = ".config/fish/conf.d/change_cmd.fish";
};
"fish/pls.fish" = {
source = ./pls_extra.fish;
target = ".config/fish/conf.d/pls_extra.fish";
source = ./. + "/pls.fish";
target = ".config/fish/conf.d/pls.fish";
};
};
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

155
home/fish/pls.fish Normal file
View file

@ -0,0 +1,155 @@
alias sue="pls -e"
function pls
set -l cmd "`"(string join " " -- $argv)"`"
echo "I-It's not like I'm gonna run "$cmd" for you or a-anything! Baka >:C" >&2
# Send a notification on password prompt
if command sudo -vn 2>/dev/null
# nothing to do, user already authenticated
else
# throw a notification
# notify-send -t 3000 -u critical -i ~/Downloads/harukablush.jpg -h "STRING:command:"$cmd "A-a command requires your p-password" (printf "I-I need your p-password to r-run the following c-command: %s" $cmd)
end
command sudo $argv
end
function sudo
echo "Not polite enough."
end
function __fish_prepend_pls -d "Prepend 'pls ' to the beginning of the current commandline"
# If there is no commandline, insert the last item from history
# and *then* toggle
if not commandline | string length -q
commandline -r "$history[1]"
end
set -l cmd (commandline -po)
set -l cursor (commandline -C)
if test "$cmd[1]" = e
commandline -C 0
commandline -i "su"
commandline -C (math $cursor + 2)
else if test "$cmd[1]" = sue
commandline -r (string sub --start=3 (commandline -p))
commandline -C -- (math $cursor - 2)
else if test "$cmd[1]" != pls
commandline -C 0
commandline -i "pls "
commandline -C (math $cursor + 4)
else
commandline -r (string sub --start=5 (commandline -p))
commandline -C -- (math $cursor - 4)
end
end
bind --preset -e -M insert \es
bind -M insert \es __fish_prepend_pls
function __fish_man_page
# Get all commandline tokens not starting with "-"
set -l args (commandline -po | string match -rv '^-')
# If commandline is empty, exit.
if not set -q args[1]
printf \a
return
end
#Skip `pls` and display then manpage of following command
while set -q args[2]
and string match -qr -- '^(pls|.*=.*)$' $args[1]
set -e args[1]
end
# If there are at least two tokens not starting with "-", the second one might be a subcommand.
# Try "man first-second" and fall back to "man first" if that doesn't work out.
set -l maincmd (basename $args[1])
if set -q args[2]
# HACK: If stderr is not attached to a terminal `less` (the default pager)
# wouldn't use the alternate screen.
# But since we don't know what pager it is, and because `man` is totally underspecified,
# the best we can do is to *try* the man page, and assume that `man` will return false if it fails.
# See #7863.
if man "$maincmd-$args[2]" &>/dev/null
man "$maincmd-$args[2]"
else if man "$maincmd" &>/dev/null
man "$maincmd"
else
printf \a
end
else
if man "$maincmd" &>/dev/null
man "$maincmd"
else
printf \a
end
end
commandline -f repaint
end
#
# Completion for pls
#
function __fish_pls_print_remaining_args
set -l tokens (commandline -opc) (commandline -ct)
set -e tokens[1]
# These are all the options mentioned in the man page for Todd Miller's "pls.ws" pls (in that order).
# If any other implementation has different options, this should be harmless, since they shouldn't be used anyway.
set -l opts A/askpass b/background C/close-from= E/preserve-env='?'
# Note that "-h" is both "--host" (which takes an option) and "--help" (which doesn't).
# But `-h` as `--help` only counts when it's the only argument (`pls -h`),
# so any argument completion after that should take it as "--host".
set -a opts e/edit g/group= H/set-home h/host= 1-help
set -a opts i/login K/remove-timestamp k/reset-timestamp l/list n/non-interactive
set -a opts P/preserve-groups p/prompt= S/stdin s/shell U/other-user=
set -a opts u/user= T/command-timeout= V/version v/validate
argparse -s $opts -- $tokens 2>/dev/null
# The remaining argv is the subcommand with all its options, which is what
# we want.
if test -n "$argv"
and not string match -qr '^-' $argv[1]
string join0 -- $argv
return 0
else
return 1
end
end
function __fish_pls_no_subcommand
not __fish_pls_print_remaining_args >/dev/null
end
function __fish_complete_pls_subcommand
set -l args (__fish_pls_print_remaining_args | string split0)
set -lx -a PATH /usr/local/sbin /sbin /usr/sbin
__fish_complete_subcommand --commandline $args
end
# All these options should be valid for GNU and OSX pls
complete -c pls -n __fish_no_arguments -s h -d "Display help and exit"
complete -c pls -n __fish_no_arguments -s V -d "Display version information and exit"
complete -c pls -n __fish_pls_no_subcommand -s A -d "Ask for password via the askpass or \$SSH_ASKPASS program"
complete -c pls -n __fish_pls_no_subcommand -s C -d "Close all file descriptors greater or equal to the given number" -xa "0 1 2 255"
complete -c pls -n __fish_pls_no_subcommand -s E -d "Preserve environment"
complete -c pls -n __fish_pls_no_subcommand -s H -d "Set home"
complete -c pls -n __fish_pls_no_subcommand -s K -d "Remove the credential timestamp entirely"
complete -c pls -n __fish_pls_no_subcommand -s P -d "Preserve group vector"
complete -c pls -n __fish_pls_no_subcommand -s S -d "Read password from stdin"
complete -c pls -n __fish_pls_no_subcommand -s b -d "Run command in the background"
complete -c pls -n __fish_pls_no_subcommand -s e -rF -d Edit
complete -c pls -n __fish_pls_no_subcommand -s g -a "(__fish_complete_groups)" -x -d "Run command as group"
complete -c pls -n __fish_pls_no_subcommand -s i -d "Run a login shell"
complete -c pls -n __fish_pls_no_subcommand -s k -d "Reset or ignore the credential timestamp"
complete -c pls -n __fish_pls_no_subcommand -s l -d "List the allowed and forbidden commands for the given user"
complete -c pls -n __fish_pls_no_subcommand -s n -d "Do not prompt for a password - if one is needed, fail"
complete -c pls -n __fish_pls_no_subcommand -s p -d "Specify a custom password prompt"
complete -c pls -n __fish_pls_no_subcommand -s s -d "Run the given command in a shell"
complete -c pls -n __fish_pls_no_subcommand -s u -a "(__fish_complete_users)" -x -d "Run command as user"
complete -c pls -n __fish_pls_no_subcommand -s v -n __fish_no_arguments -d "Validate the credentials, extending timeout"
# Complete the command we are executed under pls
complete -c pls -x -n 'not __fish_seen_argument -s e' -a "(__fish_complete_pls_subcommand)"

View file

@ -1,47 +0,0 @@
alias sue="pls -e"
function sudo
echo "Not polite enough."
end
bind --preset -M visual \es 'fish_commandline_prepend pls'
bind -M insert \es 'fish_commandline_prepend pls'
function __fish_man_page
# Get all commandline tokens not starting with "-", up to and including the cursor's
set -l args (string match -rv '^-|^$' -- (commandline -cpx && commandline -t))
# If commandline is empty, exit.
if not set -q args[1]
printf \a
return
end
# Skip leading commands and display the manpage of following command
while set -q args[2]
and string match -qr -- '^(and|begin|builtin|caffeinate|command|doas|entr|env|exec|if|mosh|nice|not|or|pipenv|prime-run|setsid|sudo|pls|systemd-nspawn|time|watch|while|xargs|.*=.*)$' $args[1]
set -e args[1]
end
# If there are at least two tokens not starting with "-", the second one might be a subcommand.
# Try "man first-second" and fall back to "man first" if that doesn't work out.
set -l maincmd (path basename $args[1])
# HACK: If stderr is not attached to a terminal `less` (the default pager)
# wouldn't use the alternate screen.
# But since we don't know what pager it is, and because `man` is totally underspecified,
# the best we can do is to *try* the man page, and assume that `man` will return false if it fails.
# See #7863.
if set -q args[2]
and not string match -q -- '*/*' $args[2]
and man "$maincmd-$args[2]" &>/dev/null
man "$maincmd-$args[2]"
else
if man "$maincmd" &>/dev/null
man "$maincmd"
else
printf \a
end
end
commandline -f repaint
end

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib;
let
@ -47,38 +42,25 @@ in
leftItems = mkOption {
type = types.listOf types.str;
description = "The list of left-items. Note that `newline` and `character` is not included here and will always appear last";
default = [
"os"
"context"
"pwd"
"git"
];
default = [ "os" "context" "pwd" "git" ];
};
};
config.programs.fish =
let
tideItems = attrsets.mapAttrs' (
name: def: {
name = "_tide_item_${name}";
value = def;
}
);
tideItems = attrsets.mapAttrs' (name: def: { name = "_tide_item_${name}"; value = def; });
in
mkIf cfg.enable {
functions = tideItems (
{
nix_shell = ''
# In a Nix Shell
if set -qx DIRENV_FILE && test -f $DIRENV_FILE && rg -q "^use flake" $DIRENV_FILE
set -U tide_nix_shell_color "FFA500"
set -U tide_nix_shell_bg_color normal
_tide_print_item nix_shell ""
end
'';
}
// cfg.items
);
functions = tideItems ({
nix_shell = ''
# In a Nix Shell
if set -qx DIRENV_FILE && test -f $DIRENV_FILE && rg -q "^use flake" $DIRENV_FILE
set -U tide_nix_shell_color "FFA500"
set -U tide_nix_shell_bg_color normal
_tide_print_item nix_shell ""
end
'';
} // cfg.items);
plugins = [
{
name = "tide";
@ -96,9 +78,7 @@ in
config.xdg.configFile."fish/tide/init.fish" = {
text = ''
# Configure tide items
set -U tide_left_prompt_items ${
concatMapStringsSep " " escapeShellArg cfg.leftItems
} newline character
set -U tide_left_prompt_items ${concatMapStringsSep " " escapeShellArg cfg.leftItems} newline character
set -U tide_right_prompt_items ${concatMapStringsSep " " escapeShellArg cfg.rightItems} time
'';

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

View file

@ -1,16 +1,11 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
{
imports = [
# Common configuration
./common.nix
# osu!
./osu
./osu.nix
];
# Home Manager needs a bit of information about you and the
@ -19,59 +14,61 @@
home.homeDirectory = "/home/nki";
# More packages
home.packages = (
with pkgs;
[
# Gaming stuff
wineWowPackages.full
# wine-lol
winetricks
lutris
steam
home.packages = (with pkgs; [
# CLI stuff
zip
# TeX
texlive.combined.scheme-full
inkscape # for TeX svg
# Manage tlmc
flacon
ttaenc
picard
]
);
# Gaming stuff
wineWowPackages.full
# wine-lol
winetricks
lutris
steam
# Manage tlmc
flacon
ttaenc
picard
]);
# Enable X11 configuration
linux.graphical.type = "wayland";
linux.graphical.wallpaper = ./images/pixiv_18776904.png;
linux.graphical.defaults.webBrowser.package = pkgs.zen-browser-bin;
linux.graphical.defaults.webBrowser.desktopFile = "zen.desktop";
programs.my-niri.enable = true;
programs.my-niri.enableLaptop = false;
linux.graphical.defaults.webBrowser = "librewolf.desktop";
programs.my-sway.enable = true;
programs.my-sway.fontSize = 15.0;
programs.my-sway.enableLaptop = false;
programs.my-waybar.fontSize = 15.0;
programs.my-waybar.enableMpd = true;
programs.my-sway.enableLaptopBars = false;
programs.my-sway.enableMpd = true;
# Keyboard options
wayland.windowManager.sway.config.input."type:keyboard".xkb_layout = "jp";
wayland.windowManager.sway.config.input."type:pointer".accel_profile = "flat";
# 144hz adaptive refresh ON!
wayland.windowManager.sway.config.output =
let
scale = 1.5;
top_x = builtins.ceil (3840 / scale);
top_y = 0;
in
with config.common.monitors; {
${home_4k.name} = {
scale = toString scale;
position = "0 0";
};
${home_1440.name} = {
position = "${toString top_x} ${toString top_y}";
};
};
nki.programs.kitty.enable = true;
nki.programs.kitty.fontSize = 14;
programs.my-waybar.makeBars =
with config.common.monitors;
barWith: [
# For primary
(barWith {
extraSettings = {
output = [ home_4k.meta.connection ];
};
})
# For secondary, hide mpd
(barWith {
showMedia = false;
showConnectivity = false;
extraSettings = {
output = [ home_1440.meta.connection ];
};
})
];
programs.my-sway.waybar.makeBars = with config.common.monitors; barWith: [
# For primary
(barWith { extraSettings = { output = [ home_4k.name ]; }; })
# For secondary, hide mpd
(barWith { showMedia = false; showConnectivity = false; extraSettings = { output = [ home_1440.name ]; }; })
];
# Yellow light!
services.wlsunset = {
@ -92,28 +89,10 @@
# ncmpcpp
programs.ncmpcpp.enable = true;
programs.ncmpcpp.bindings = [
{
key = "j";
command = "scroll_down";
}
{
key = "k";
command = "scroll_up";
}
{
key = "J";
command = [
"select_item"
"scroll_down"
];
}
{
key = "K";
command = [
"select_item"
"scroll_up"
];
}
{ key = "j"; command = "scroll_down"; }
{ key = "k"; command = "scroll_up"; }
{ key = "J"; command = [ "select_item" "scroll_down" ]; }
{ key = "K"; command = [ "select_item" "scroll_up" ]; }
];
programs.ncmpcpp.settings = {
# General
@ -171,3 +150,4 @@
# changes in each release.
home.stateVersion = "21.05";
}

View file

@ -1,184 +0,0 @@
{ pkgs, lib, ... }:
let
in
{
imports = [ ./modules/programs/my-kakoune ];
home.packages = with pkgs; [
# ctags for peneira
universal-ctags
# tree-sitter for kak
kak-tree-sitter
];
# xdg.configFile."kak-tree-sitter/config.toml".source = ./kak-tree-sitter.toml;
# Enable the kakoune package.
programs.my-kakoune.enable = true;
programs.my-kakoune.enable-fish-session = true;
programs.my-kakoune.tree-sitter.extraAliases = {
# Scala stuff
method = "function";
module = "namespace";
function_call = "function";
method_call = "method";
boolean = "constant_builtin_boolean";
number = "constant_numeric";
float = "constant_numeric_float";
type_qualifier = "keyword_special";
storageclass = "keyword_storage_modifier";
conditional = "keyword_conditional";
include = "keyword_control_import";
};
programs.my-kakoune.tree-sitter.languages =
let
tree-sitter-go = pkgs.fetchFromGitHub {
owner = "tree-sitter";
repo = "tree-sitter-go";
rev = "v0.20.0";
hash = "sha256-G7d8CHCyKDAb9j6ijRfHk/HlgPqSI+uvkuRIRRvjkHI=";
};
in
{
scala =
let
src = pkgs.fetchFromGitHub {
owner = "tree-sitter";
repo = "tree-sitter-scala";
rev = "70afdd5632d57dd63a960972ab25945e353a52f6";
hash = "sha256-bi0Lqo/Zs2Uaz1efuKAARpEDg5Hm59oUe7eSXgL1Wow=";
};
in
{
grammar.src = src;
queries.src = src;
queries.path = "queries/scala";
};
haskell =
let
src = pkgs.fetchFromGitHub {
owner = "tree-sitter";
repo = "tree-sitter-haskell";
rev = "ba0bfb0e5d8e9e31c160d287878c6f26add3ec08";
hash = "sha256-ZSOF0CLOn82GwU3xgvFefmh/AD2j5zz8I0t5YPwfan0=";
};
in
{
grammar.src = src;
grammar.compile.args = [
"-c"
"-fpic"
"../parser.c"
"../scanner.c"
"../unicode.h"
"-I"
".."
];
queries.src = src;
queries.path = "queries";
};
yaml = {
grammar.src = pkgs.fetchFromGitHub {
owner = "ikatyang";
repo = "tree-sitter-yaml";
rev = "0e36bed171768908f331ff7dff9d956bae016efb";
hash = "sha256-bpiT3FraOZhJaoiFWAoVJX1O+plnIi8aXOW2LwyU23M=";
};
grammar.compile.args = [
"-c"
"-fpic"
"../scanner.cc"
"../parser.c"
"-I"
".."
];
grammar.link.args = [
"-shared"
"-fpic"
"scanner.o"
"parser.o"
];
grammar.link.flags = [
"-O3"
"-lstdc++"
];
queries.src = pkgs.fetchFromGitHub {
owner = "helix-editor";
repo = "helix";
rev = "dbd248fdfa680373d94fbc10094a160aafa0f7a7";
hash = "sha256-wk8qVUDFXhAOi1Ibc6iBMzDCXb6t+YiWZcTd0IJybqc=";
};
queries.path = "runtime/queries/yaml";
};
templ =
let
src = pkgs.fetchFromGitHub {
owner = "vrischmann";
repo = "tree-sitter-templ";
rev = "4519e3ec9ca92754ca25659bb1fd410d5e0f8d88";
hash = "sha256-ic5SlqDEZoYakrJFe0H9GdzravqovlL5sTaHjyhe74M=";
};
in
{
grammar.src = src;
queries.src = pkgs.runCommandLocal "templ-tree-sitter-queries" { } ''
mkdir -p $out/queries
# copy most stuff from tree-sitter-templ
install -m644 ${src}/queries/templ/* $out/queries
# override inherited files
cat ${tree-sitter-go}/queries/highlights.scm ${src}/queries/templ/highlights.scm > $out/queries/highlights.scm
'';
queries.path = "queries";
};
go = {
grammar.src = tree-sitter-go;
grammar.compile.args = [
"-c"
"-fpic"
"../parser.c"
"-I"
".."
];
grammar.link.args = [
"-shared"
"-fpic"
"parser.o"
];
queries.src = tree-sitter-go;
queries.path = "queries";
};
hylo =
let
src = pkgs.fetchFromGitHub {
owner = "natsukagami";
repo = "tree-sitter-hylo";
rev = "494cbdff0d13cbc67348316af2efa0286dbddf6f";
hash = "sha256-R5UeoglCTl0do3VDJ/liCTeqbxU9slvmVKNRA/el2VY=";
};
in
{
grammar.src = src;
grammar.compile.args = [
"-c"
"-fpic"
"../parser.c"
"-I"
".."
];
grammar.link.args = [
"-shared"
"-fpic"
"parser.o"
];
queries.src = src;
queries.path = "queries";
};
};
}

515
home/kakoune/kak.nix Normal file
View file

@ -0,0 +1,515 @@
{ pkgs, lib, ... }:
let
kak-lsp-frontend = { pkgs, lib, ... }:
let
langserver = name: {
name = "vscode-${name}-language-server";
value = {
args = [ "--stdio" ];
command = "vscode-${name}-language-server";
filetypes = [ name ];
roots = [ "package.json" ".git" ];
};
package = pkgs.nodePackages.vscode-langservers-extracted;
};
tailwind = {
command = "tailwindcss-language-server";
args = [ "--stdio" ];
filetypes = [ "html" "css" "javascript" "typescript" "templ" ];
roots = [ "tailwind.config.{js,cjs,mjs,ts}" "package.json" ".git" ];
settings_section = "tailwindCSS";
settings.tailwindCSS = {
validate = "warning";
userLanguages.templ = "html";
};
package = pkgs.tailwindcss-language-server;
};
templModule = { pkgs, lib, ... }: {
programs.kak-lsp.languageServers."vscode-html-language-server".filetypes = [ "templ" ];
programs.kak-lsp.languageServers."tailwindcss-language-server".filetypes = [ "templ" ];
programs.kak-lsp.languageServers.templ = {
command = "templ";
args = [ "lsp" ];
filetypes = [ "templ" ];
roots = [ "go.mod" ".git" ];
package = pkgs.unstable.templ;
};
};
in
{
imports = [ templModule ];
programs.kak-lsp.languageServers = (builtins.listToAttrs (map langserver [ "html" "css" "json" ])) // {
tailwindcss-language-server = tailwind;
};
};
ltexLsp = { pkgs, lib, ... }: {
programs.kak-lsp.languageServers.ltex-ls = {
command = "ltex-ls";
args = [ "--log-file=/tmp" ];
filetypes = [ "latex" "typst" ];
roots = [ "main.tex" "main.typ" ".git" ];
package = pkgs.ltex-ls;
};
};
in
{
imports = [ ../modules/programs/my-kakoune ./kaktex.nix kak-lsp-frontend ltexLsp ];
home.packages = with pkgs; [
# ctags for peneira
universal-ctags
# tree-sitter for kak
kak-tree-sitter
];
# xdg.configFile."kak-tree-sitter/config.toml".source = ./kak-tree-sitter.toml;
# Enable the kakoune package.
programs.my-kakoune.enable = true;
programs.my-kakoune.enable-fish-session = true;
programs.kak-lsp.enable = true;
programs.kak-lsp.semanticTokens.additionalFaces = [
# Typst
{ face = "header"; token = "heading"; }
{ face = "ts_markup_link_url"; token = "link"; }
{ face = "ts_markup_link_uri"; token = "ref"; }
{ face = "ts_markup_link_label"; token = "label"; }
{ face = "ts_property"; token = "pol"; }
{ face = "ts_markup_list_checked"; token = "marker"; }
{ face = "ts_constant_builtin_boolean"; token = "bool"; }
{ face = "ts_keyword_control"; token = "delim"; }
{ face = "ts_number"; token = "text"; modifiers = [ "math" ]; }
{ face = "ts_markup_bold"; token = "text"; modifiers = [ "strong" ]; }
{ face = "ts_markup_italic"; token = "text"; modifiers = [ "emph" ]; }
];
programs.kak-lsp.languageServers.elixir-ls = {
args = [ ];
command = "elixir-ls";
filetypes = [ "elixir" ];
roots = [ "mix.exs" ];
};
programs.kak-lsp.languageServers.typescript-language-server = {
args = [ "--stdio" ];
command = "typescript-language-server";
filetypes = [ "typescript" "javascript" ];
roots = [ "package.json" ];
package = pkgs.nodePackages.typescript-language-server;
};
programs.kak-lsp.languageServers.fsautocomplete = {
args = [ "--adaptive-lsp-server-enabled" "--project-graph-enabled" "--source-text-factory" "RoslynSourceText" ];
command = "fsautocomplete";
filetypes = [ "fsharp" ];
roots = [ "*.fsproj" ];
settings_section = "FSharp";
settings.FSharp = {
AutomaticWorkspaceInit = true;
};
};
programs.kak-lsp.languageServers.metals = {
command = "metals";
filetypes = [ "scala" ];
roots = [ "build.sbt" "build.sc" ];
settings_section = "metals";
settings.metals = {
enableSemanticHighlighting = true;
showInferredType = true;
decorationProvider = true;
inlineDecorationProvider = true;
# From kakoune-lsp's own options
icons = "unicode";
isHttpEnabled = true;
statusBarProvider = "log-message";
compilerOptions = { overrideDefFormat = "unicode"; };
};
package = pkgs.metals;
};
programs.kak-lsp.languageServers.texlab = {
command = "texlab";
filetypes = [ "latex" ];
roots = [ "main.tex" "all.tex" ".git" ];
settings_section = "texlab";
settings.texlab = {
build.executable = "latexmk";
build.args = [ "-pdf" "-shell-escape" "-interaction=nonstopmode" "-synctex=1" "%f" ];
build.forwardSearchAfter = true;
build.onSave = true;
forwardSearch =
(if pkgs.stdenv.isDarwin then {
executable = "/Applications/Skim.app/Contents/SharedSupport/displayline";
args = [ "-r" "-g" "%l" "%p" "%f" ];
} else
{
executable = "${pkgs.zathura}/bin/zathura";
args = [ "--synctex-forward" "%l:1:%f" "%p" "-x" "${./kaktex} jump %%{input} %%{line} %%{column}" ];
});
};
package = pkgs.texlab;
};
programs.kak-lsp.languageServers.typst-lsp = {
command = "typst-lsp";
filetypes = [ "typst" ];
roots = [ "main.typ" ".git" ];
settings_section = "typst-lsp";
settings.typst-lsp = {
experimentalFormatterMode = "on";
};
};
programs.kak-lsp.languageServers.marksman = {
command = "marksman";
filetypes = [ "markdown" ];
roots = [ ".marksman.toml" ".git" ];
package = pkgs.marksman;
};
programs.kak-lsp.languageServers.rust-analyzer = {
args = [ ];
command = "rust-analyzer";
filetypes = [ "rust" ];
roots = [ "Cargo.toml" ];
package = pkgs.rust-analyzer;
};
programs.my-kakoune.tree-sitter.extraAliases = {
# Scala stuff
method = "function";
module = "namespace";
function_call = "function";
method_call = "method";
boolean = "constant_builtin_boolean";
number = "constant_numeric";
float = "constant_numeric_float";
type_qualifier = "keyword_special";
storageclass = "keyword_storage_modifier";
conditional = "keyword_conditional";
include = "keyword_control_import";
};
programs.my-kakoune.tree-sitter.languages =
let
tree-sitter-go = pkgs.fetchFromGitHub {
owner = "tree-sitter";
repo = "tree-sitter-go";
rev = "v0.20.0";
hash = "sha256-G7d8CHCyKDAb9j6ijRfHk/HlgPqSI+uvkuRIRRvjkHI=";
};
in
{
scala =
let
src = pkgs.fetchFromGitHub {
owner = "tree-sitter";
repo = "tree-sitter-scala";
rev = "70afdd5632d57dd63a960972ab25945e353a52f6";
hash = "sha256-bi0Lqo/Zs2Uaz1efuKAARpEDg5Hm59oUe7eSXgL1Wow=";
};
in
{
grammar.src = src;
queries.src = src;
queries.path = "queries/scala";
};
haskell =
let
src = pkgs.fetchFromGitHub {
owner = "tree-sitter";
repo = "tree-sitter-haskell";
rev = "ba0bfb0e5d8e9e31c160d287878c6f26add3ec08";
hash = "sha256-ZSOF0CLOn82GwU3xgvFefmh/AD2j5zz8I0t5YPwfan0=";
};
in
{
grammar.src = src;
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "../scanner.c" "../unicode.h" "-I" ".." ];
queries.src = src;
queries.path = "queries";
};
yaml = {
grammar.src = pkgs.fetchFromGitHub {
owner = "ikatyang";
repo = "tree-sitter-yaml";
rev = "0e36bed171768908f331ff7dff9d956bae016efb";
hash = "sha256-bpiT3FraOZhJaoiFWAoVJX1O+plnIi8aXOW2LwyU23M=";
};
grammar.compile.args = [ "-c" "-fpic" "../scanner.cc" "../parser.c" "-I" ".." ];
grammar.link.args = [ "-shared" "-fpic" "scanner.o" "parser.o" ];
grammar.link.flags = [ "-O3" "-lstdc++" ];
queries.src = pkgs.fetchFromGitHub {
owner = "helix-editor";
repo = "helix";
rev = "dbd248fdfa680373d94fbc10094a160aafa0f7a7";
hash = "sha256-wk8qVUDFXhAOi1Ibc6iBMzDCXb6t+YiWZcTd0IJybqc=";
};
queries.path = "runtime/queries/yaml";
};
templ =
let
src = pkgs.fetchFromGitHub {
owner = "vrischmann";
repo = "tree-sitter-templ";
rev = "044ad200092170727650fa6d368df66a8da98f9d";
hash = "sha256-hJuB3h5pp+LLfP0/7bAYH0uLVo+OQk5jpzJb3J9BNkY=";
};
in
{
grammar.src = src;
queries.src = pkgs.runCommandLocal "templ-tree-sitter-queries" { } ''
mkdir -p $out/queries
# copy most stuff from tree-sitter-templ
install -m644 ${src}/queries/templ/* $out/queries
# override inherited files
cat ${tree-sitter-go}/queries/highlights.scm ${src}/queries/templ/highlights.scm > $out/queries/highlights.scm
'';
queries.path = "queries";
};
go = {
grammar.src = tree-sitter-go;
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "-I" ".." ];
grammar.link.args = [ "-shared" "-fpic" "parser.o" ];
queries.src = tree-sitter-go;
queries.path = "queries";
};
hylo =
let
src = pkgs.fetchFromGitHub {
owner = "natsukagami";
repo = "tree-sitter-hylo";
rev = "494cbdff0d13cbc67348316af2efa0286dbddf6f";
hash = "sha256-R5UeoglCTl0do3VDJ/liCTeqbxU9slvmVKNRA/el2VY=";
};
in
{
grammar.src = src;
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "-I" ".." ];
grammar.link.args = [ "-shared" "-fpic" "parser.o" ];
queries.src = src;
queries.path = "queries";
};
};
programs.my-kakoune.package = pkgs.kakoune;
programs.my-kakoune.rc =
builtins.readFile ./kakrc + ''
# Source any settings in the current working directory,
# recursive upwards
evaluate-commands %sh{
${pkgs.writeScript "source-pwd" (builtins.readFile ./source-pwd)}
}
'';
programs.my-kakoune.extraFaces = {
Default = "%opt{text},%opt{base}";
BufferPadding = "%opt{base},%opt{base}";
MenuForeground = "%opt{blue},white+bF";
MenuBackground = "%opt{sky},white+F";
Information = "%opt{sky},white";
# Markdown help color scheme
InfoDefault = "Information";
InfoBlock = "@block";
InfoBlockQuote = "+i@block";
InfoBullet = "@bullet";
InfoHeader = "@header";
InfoLink = "@link";
InfoLinkMono = "+b@mono";
InfoMono = "@mono";
InfoRule = "+b@Information";
InfoDiagnosticError = "@DiagnosticError";
InfoDiagnosticHint = "@DiagnosticHint";
InfoDiagnosticInformation = "@Information";
InfoDiagnosticWarning = "@DiagnosticWarning";
# Extra faces
macro = "+u@function";
method = "@function";
format_specifier = "+i@string";
mutable_variable = "+i@variable";
class = "+b@variable";
};
programs.my-kakoune.autoload = [
# My own scripts
{
name = "latex.kak";
src = ./autoload/latex.kak;
}
{
name = "markdown.kak";
src = ./autoload/markdown.kak;
}
# Plugins
{
name = "luar";
src = pkgs.fetchFromGitHub {
owner = "gustavo-hms";
repo = "luar";
rev = "2f430316f8fc4d35db6c93165e2e77dc9f3d0450";
sha256 = "sha256-vHn/V3sfzaxaxF8OpA5jPEuPstOVwOiQrogdSGtT6X4=";
};
activationScript = ''
# Enable luar
require-module luar
# Use luajit
set-option global luar_interpreter ${pkgs.luajit}/bin/luajit
'';
}
{
name = "peneira";
src = pkgs.fetchFromGitHub {
owner = "natsukagami";
repo = "peneira";
rev = "743b9971472853a752475e7c070ce99089c6840c";
sha256 = "sha256-E4ndbF9YC1p0KrvSuGgwmG1Y2IGTuGKJo/AuMixhzlM=";
};
activationScript = ''
require-module peneira
# Change selection color
set-face global PeneiraSelected @PrimarySelection
# Buffers list
define-command -hidden peneira-buffers %{
peneira 'buffers: ' %{ printf '%s\n' $kak_quoted_buflist } %{
buffer %arg{1}
}
}
# Grep in the current location
define-command peneira-grep %{
peneira 'line: ' "rg -n ." %{
lua %arg{1} %{
local file, line = arg[1]:match("([^:]+):(%d+):")
kak.edit(file, line)
}
}
}
# A peneira menu
declare-user-mode fuzzy-match-menu
map -docstring "Switch to buffer" global fuzzy-match-menu b ": peneira-buffers<ret>"
map -docstring "Symbols" global fuzzy-match-menu s ": peneira-symbols<ret>"
map -docstring "Lines" global fuzzy-match-menu l ": peneira-lines<ret>"
map -docstring "Lines in the current directory" global fuzzy-match-menu g ": peneira-grep<ret>"
map -docstring "Files in project" global fuzzy-match-menu f ": peneira-files<ret>"
map -docstring "Files in currently opening file's directory" global fuzzy-match-menu F ": peneira-local-files<ret>"
# Bind menu to user mode
map -docstring "Fuzzy matching" global user f ": enter-user-mode fuzzy-match-menu<ret>"
'';
}
{
name = "kakoune-focus";
src = pkgs.fetchFromGitHub {
owner = "caksoylar";
repo = "kakoune-focus";
rev = "949c0557cd4c476822acfa026ca3c50f3d38a3c0";
sha256 = "sha256-ZV7jlLJQyL420YG++iC9rq1SMjo3WO5hR9KVvJNUiCs=";
};
activationScript = ''
map global user <space> ': focus-toggle<ret>' -docstring "toggle selections focus"
'';
}
{
name = "kakoune-inc-dec";
src = pkgs.fetchFromGitLab {
owner = "Screwtapello";
repo = "kakoune-inc-dec";
rev = "7bfe9c51";
sha256 = "0f33wqxqbfygxypf348jf1fiscac161wf2xvnh8zwdd3rq5yybl0";
};
}
{
name = "racket.kak";
src = (builtins.fetchTree {
type = "git";
url = "https://bitbucket.org/KJ_Duncan/kakoune-racket.kak.git";
rev = "e397042009b46916ff089d79166ec0e8ca813a18";
narHash = "sha256-IcxFmvG0jqpMCG/dT9crVRgPgMGKkic6xwrnW5z4+bc=";
}) + "/rc";
}
# {
# name = "kakoune-discord";
# src = (builtins.getFlake "github:natsukagami/kakoune-discord/03f95e40d6efd8fd3de7bca31653d43de2dcfc5f").packages.${pkgs.system}.kakoune-discord-rc + "/rc";
# }
rec {
name = "kakoune-mirror";
src = pkgs.fetchFromGitHub
{
owner = "Delapouite";
repo = "kakoune-mirror";
rev = "5710635f440bcca914d55ff2ec1bfcba9efe0f15";
sha256 = "sha256-uslx4zZhvjUylrPWvTOugsKYKKpF0EEz1drc1Ckrpjk=";
} + "/mirror.kak";
wrapAsModule = true;
activationScript = ''
require-module ${name}
# Bind <a-w> to ${name}
map global normal <a-w> ': enter-user-mode -lock mirror<ret>'
'';
}
{
name = "unicode-math";
src = pkgs.fetchFromGitHub {
owner = "natsukagami";
repo = "kakoune-unicode-math";
rev = "08dff25da2b86ee0b0777091992bc7fb28c3cb1d";
# sha256 = lib.fakeSha256;
sha256 = "sha256-j0L1ARex1i2ma8sGLYwgkfAbh0jWKh/6QGHFaxPXIKc=";
fetchSubmodules = true;
};
activationScript = ''
require-module unicode-math
# Bind <c-s> to the menu
map global insert <c-s> '<a-;>: insert-unicode '
'';
}
{
name = "kakoune-buffers";
src = pkgs.fetchFromGitHub {
owner = "Delapouite";
repo = "kakoune-buffers";
rev = "6b2081f5b7d58c72de319a5cba7bf628b6802881";
sha256 = "sha256-jOSrzGcLJjLK1GiTSsl2jLmQMPbPxjycR0pwF5t/eV0=";
};
activationScript = ''
# Suggested hook
hook global WinDisplay .* info-buffers
# Suggested mappings
map global user b ':enter-buffers-mode<ret>' -docstring 'buffers'
map global normal ^ ':enter-buffers-mode<ret>' -docstring 'buffers'
map global user B ':enter-user-mode -lock buffers<ret>' -docstring 'buffers (lock)'
# Suggested aliases
alias global bd delete-buffer
alias global bf buffer-first
alias global bl buffer-last
alias global bo buffer-only
alias global bo! buffer-only-force
'';
}
];
programs.my-kakoune.themes = {
catppuccin-latte = ./catppuccin-latte.kak;
};
}

View file

@ -1,3 +1,6 @@
# Enable kak-tree-sitter
eval %sh{test -z "$WE_STARTED_KAK" && kak-tree-sitter --kakoune -d --server --init $kak_session}
map global normal <c-t> ": enter-user-mode tree-sitter<ret>"
# ## Set some color overrides
# set global kts_yellow "rgb:e2b75e"
# set global kts_teal "rgb:008080"
@ -5,7 +8,6 @@
# set global kts_sky "rgb:6aa622"
# Color scheme
colorscheme catppuccin-latte
set-face global module "%opt{sapphire}"
set global base "default"
# Set indentation guides
@ -60,13 +62,7 @@ map global normal D ": delete-current-brackets<ret>"
# Tab sizes
hook global InsertChar \t %{ exec -draft -itersel h@ }
set global tabstop 2
set global indentwidth 2
# Language-specific tabstop with override
hook global WinSetOption filetype=(rust) %{
set window tabstop 4
set window indentwidth 4
}
set global indentwidth 2
# Ctrl + a in insert mode = esc
map global insert <c-a> '<esc>'
@ -88,6 +84,47 @@ hook global InsertCompletionHide .* %{
unmap window insert <s-tab> <c-p>
}
# Enable LSP
try %{
eval %sh{test -z "$WE_STARTED_KAK" && kak-lsp --kakoune -s $kak_session}
set-option global lsp_cmd "kak-lsp -s %val{session}"
}
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|fsharp|ocaml|haskell|nix|scala|typst|html|css|json|markdown|templ|elixir) %{
lsp-enable-window
map window lsp N -docstring "Display the next message request" ": lsp-show-message-request-next<ret>"
map window normal <c-l> ": enter-user-mode lsp<ret>"
map window normal <c-h> ": lsp-hover<ret>"
map window normal <c-s-h> ": lsp-hover-buffer<ret>"
# lsp-auto-hover-insert-mode-enable
set window lsp_hover_anchor true
map global insert <tab> '<a-;>:try lsp-snippets-select-next-placeholders catch %{ execute-keys -with-hooks <lt>tab> }<ret>' -docstring 'Select next snippet placeholder'
map global object a '<a-semicolon>lsp-object<ret>' -docstring 'LSP any symbol'
map global object <a-a> '<a-semicolon>lsp-object<ret>' -docstring 'LSP any symbol'
map global object f '<a-semicolon>lsp-object Function Method<ret>' -docstring 'LSP function or method'
map global object t '<a-semicolon>lsp-object Class Interface Struct<ret>' -docstring 'LSP class interface or struct'
map global object d '<a-semicolon>lsp-diagnostic-object --include-warnings<ret>' -docstring 'LSP errors and warnings'
map global object D '<a-semicolon>lsp-diagnostic-object<ret>' -docstring 'LSP errors'
}
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|haskell|nix|fsharp|templ) %{
# Format the document if possible
hook window BufWritePre .* %{ lsp-formatting-sync }
}
hook global WinSetOption filetype=(rust|scala|fsharp) %{
# Enable inlay hints
lsp-inlay-hints-enable window
}
hook global WinSetOption filetype=(rust|go|fsharp|typst|scala) %{
hook window -group semantic-tokens BufReload .* lsp-semantic-tokens
hook window -group semantic-tokens NormalIdle .* lsp-semantic-tokens
hook window -group semantic-tokens InsertIdle .* lsp-semantic-tokens
hook -once -always window WinSetOption filetype=.* %{
remove-hooks window semantic-tokens
}
}
# <a-a> in Insert mode moves to end of line.
map global insert <a-a> '<esc>A'
@ -112,6 +149,14 @@ hook global WinSetOption filetype=(rust) %{
set-option buffer makecmd "cargo check"
}
hook global WinSetOption filetype=(scala) %{
# Format the document if possible
hook -group scala-fmt window BufWritePre .* %{ lsp-formatting-sync }
set window tabstop 2
set window indentwidth 2
}
hook global WinSetOption filetype=(typst) %{
set-option window comment_line "//"
set-option window comment_block_begin "/*"
@ -126,6 +171,15 @@ hook global WinSetOption filetype=(typst) %{
hook -once -always window WinSetOption filetype=.* %{ remove-hooks window markdown-.+ }
}
define-command -params 0 -docstring "Set up build" scala-build-connect %{
lsp-execute-command 'build-connect' '"[]"'
}
define-command -params 0 -docstring "Import build" scala-build-import %{
lsp-execute-command 'build-import' '"[]"'
}
def -hidden insert-c-n %{
try %{
lsp-snippets-select-next-placeholders
@ -149,7 +203,7 @@ hook global BufCreate .*[.]md %{
add-highlighter buffer/ wrap
}
hook global BufCreate .*[.](sc|sbt|mill) %{
hook global BufCreate .*[.](sc|sbt) %{
set-option buffer filetype scala
}

View file

@ -1,3 +1,5 @@
#!/usr/bin/env fish
function usage
echo "Usage: "
echo " kaktex set [client] [session]"

14
home/kakoune/kaktex.nix Normal file
View file

@ -0,0 +1,14 @@
{ config, pkgs, lib, ... }:
{
# Source kaktex whenever we have a tex file
programs.my-kakoune.rc = ''
hook global WinSetOption filetype=(tex|latex) %{
hook window WinDisplay '.*' %{
eval %sh{
${./kaktex} set $kak_client $kak_session
}
}
}
'';
}

View file

@ -1,3 +1,5 @@
#!/usr/bin/env fish
if test (pwd) = "/home/natsukagami/.config/kak"
exit 0
end

View file

@ -1,83 +0,0 @@
{
config,
pkgs,
lib,
...
}:
{
imports = [ ./common.nix ];
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
# Home Manager needs a bit of information about you and the
# paths it should manage.
home.username = "nki";
home.homeDirectory = "/Users/nki";
# Additional packages to be used only on this MacBook.
home.packages = with pkgs; [
anki-bin
];
# Additional settings for programs
programs.fish.shellAliases = {
brew64 = "arch -x86_64 /usr/local/bin/brew";
};
nki.programs.kitty.enable = true;
nki.programs.kitty.package = pkgs.hello; # We install kitty for ourselves
nki.programs.kitty.background = ./images/chise-bg.png;
home.sessionPath = [
# Personal .bin
"$HOME/.bin"
"$HOME/.local/bin"
# Rust
"$HOME/.cargo/bin"
# Haskell
"$HOME/.cabal/bin"
"$HOME/.ghcup/bin"
# Go
"$HOME/go/bin"
# Node.js
"$HOME/.local/opt/node/bin"
# Ruby
"$HOME/.gem/bin"
"$HOME/.gem/ruby/2.7.0/bin"
];
home.sessionVariables = {
VISUAL = "$EDITOR";
# Other C++ stuff
LIBRARY_PATH = lib.concatStringsSep ":" [
"$LIBRARY_PATH"
"$HOME/.local/share/lib"
];
CPATH = lib.concatStringsSep ":" [
"$CPATH"
"$HOME/.local/share/include"
];
# Ruby
GEM_HOME = "$HOME/.gem";
# .NET
DOTNET_CLI_TELEMETRY_OPTOUT = "true";
# Override home-manager package path to first
PATH = "/etc/profiles/per-user/${config.home.username}/bin:$PATH";
};
# This value determines the Home Manager release that your
# configuration is compatible with. This helps avoid breakage
# when a new Home Manager release introduces backwards
# incompatible changes.
#
# You can update Home Manager without changing this value. See
# the Home Manager release notes for a list of state version
# changes in each release.
home.stateVersion = "21.11";
}

View file

@ -1,135 +0,0 @@
{
pkgs,
config,
lib,
...
}:
let
discord = pkgs.armcord.override { nss = pkgs.nss_latest; };
in
{
imports = [
# Common configuration
./common.nix
# We use our own firefox
# ./firefox.nix
# osu!
# ./osu
];
# Home Manager needs a bit of information about you and the
# paths it should manage.
home.username = "nki";
home.homeDirectory = "/home/nki";
nki.programs.kitty.enable = true;
nki.programs.kitty.fontSize = 16;
programs.fish.shellInit = lib.mkAfter ''
set -eg MESA_GL_VERSION_OVERRIDE
set -eg MESA_GLSL_VERSION_OVERRIDE
# export GNOME_KEYRING_CONTROL=/run/user/1001/keyring
# export SSH_AUTH_SOCK=/run/user/1001/keyring/ssh
'';
# More packages
home.packages = (
with pkgs;
[
mate.mate-terminal
firefox-wayland
discord
typora
]
);
# Graphical set up
linux.graphical.type = "wayland";
linux.graphical.wallpaper = ./images/wallpaper-macbook.jpg;
# Enable sway
programs.my-sway.enable = true;
programs.my-sway.fontSize = 14.0;
programs.my-sway.enableLaptop = true;
programs.my-waybar.enableMpd = false;
programs.my-sway.discord = "${discord}/bin/armcord";
# Keyboard options
wayland.windowManager.sway.config.input."type:keyboard".xkb_layout = "jp";
wayland.windowManager.sway.config.output."eDP-1" = {
mode = "2560x1600@60Hz";
scale = "1.25";
subpixel = "vrgb";
};
wayland.windowManager.sway.config.input."1452:641:Apple_Internal_Keyboard_/_Trackpad" = {
# Keyboard stuff
xkb_layout = "jp";
repeat_delay = "300";
repeat_rate = "15";
# Trackpad stuff
accel_profile = "adaptive";
drag = "enabled";
dwt = "enabled";
middle_emulation = "enabled";
natural_scroll = "enabled";
scroll_factor = "2.5";
pointer_accel = "0.5";
tap = "disabled";
};
# Kitty
# nki.programs.kitty = {
# enable = true;
# fontSize = 22;
# enableTabs = false;
# };
# Yellow light!
services.wlsunset = {
enable = true;
# # Waterloo
# latitude = "43.3";
# longitude = "-80.3";
# Lausanne
latitude = "46.31";
longitude = "6.38";
};
home.file.".gnupg/gpg-agent.conf" = {
text = ''
pinentry-program ${pkgs.pinentry-gnome3}/bin/pinentry-gnome3
'';
onChange = ''
echo "Reloading gpg-agent"
echo RELOADAGENT | gpg-connect-agent
'';
};
# Autostart
xdg.configFile."autostart/input-remapper-autoload.desktop".source =
"${pkgs.input-remapper}/share/applications/input-remapper-autoload.desktop";
# Multiple screen setup
# services.kanshi = {
# enable = true;
# profiles.undocked.outputs = [{ criteria = "LVDS-1"; }];
# profiles.docked-hdmi.outputs = [
# { criteria = "LVDS-1"; status = "disable"; }
# { criteria = "HDMI-A-1"; }
# ];
# };
# This value determines the Home Manager release that your
# configuration is compatible with. This helps avoid breakage
# when a new Home Manager release introduces backwards
# incompatible changes.
#
# You can update Home Manager without changing this value. See
# the Home Manager release notes for a list of state version
# changes in each release.
home.stateVersion = "21.05";
}

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
@ -33,10 +28,7 @@ in
};
shell = {
program = "/bin/sh";
args = [
"-ic"
"${config.programs.fish.package}/bin/fish"
];
args = [ "-ic" "${config.programs.fish.package}/bin/fish" ];
};
colors = {
# Default colors
@ -65,11 +57,7 @@ in
};
key_bindings = [
{
key = "C";
mods = "Alt|Control";
action = "SpawnNewInstance";
}
{ key = "C"; mods = "Alt|Control"; action = "SpawnNewInstance"; }
];
};
};

View file

@ -1,9 +1,4 @@
{
pkgs,
lib,
config,
...
}:
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.linux.graphical;
@ -21,126 +16,80 @@ let
echo $wifi_output
end
'';
mkPackageWithDesktopOption =
opts:
mkOption (
{
type = types.submodule {
options = {
package = mkOption {
type = types.package;
description = "The package for " + description;
};
desktopFile = mkOption {
type = types.nullOr types.str;
default = null;
description = "The desktop file name for " + description + ", defaults to [packagename].desktop";
};
};
};
}
// opts
);
desktopFileOf =
cfg:
if cfg.desktopFile == null then
"${cfg.package}/share/applications/${cfg.package.pname}.desktop"
else
cfg.desktopFile;
in
{
imports = [
./x11.nix
./wayland.nix
./alacritty.nix
];
imports = [ ./x11.nix ./wayland.nix ./alacritty.nix ];
options.linux.graphical = {
type = mkOption {
type = types.nullOr (
types.enum [
"x11"
"wayland"
]
);
type = types.nullOr (types.enum [ "x11" "wayland" ]);
description = "Enable linux graphical configurations, with either 'x11' or 'wayland'";
default = null;
};
wallpaper = mkOption {
type = types.oneOf [
types.str
types.path
];
type = types.oneOf [ types.str types.path ];
description = "Path to the wallpaper file";
default = "";
};
startup = mkOption {
type = types.listOf types.package;
description = "List of packages to include in ~/.config/autostart";
default = [
cfg.defaults.webBrowser.package
pkgs.thunderbird
cfg.defaults.discord.package
default = with pkgs; [
librewolf
thunderbird
vesktop
premid
];
};
defaults = {
webBrowser = mkPackageWithDesktopOption { description = "default web browser"; };
terminal = mkPackageWithDesktopOption {
description = "default terminal";
default.package = pkgs.kitty;
};
discord = mkPackageWithDesktopOption {
description = "Discord client";
default.package = pkgs.vesktop;
};
defaults.webBrowser = mkOption {
type = types.str;
default = "librewolf.desktop";
description = "Desktop file of the default web browser";
};
};
config = mkIf (cfg.type != null) {
# Packages
home.packages = (
with pkgs;
[
cfg.defaults.webBrowser.package
cfg.defaults.terminal.package
home.packages = (with pkgs; [
## GUI stuff
evince # PDF reader
gparted
vscode
feh # For images?
deluge # Torrent client
pavucontrol # PulseAudio control panel
cinnamon.nemo # File manager
thunderbird # Email
sublime-music # For navidrome
cinny-desktop
gajim
vivaldi
# Audio
qpwgraph # Pipewire graph
## GUI stuff
evince # PDF reader
gparted
vscode
feh # For images?
deluge # Torrent client
pavucontrol # PulseAudio control panel
sublime-music # For navidrome
# cinny-desktop
gajim
vivaldi
# Audio
qpwgraph # Pipewire graph
audacity
vlc
zotero_7
libreoffice
unstable.zotero
libreoffice
mpv # for anki
anki-bin
mpv # for anki
anki-bin
tdesktop
whatsapp-for-linux
# Chat stuff
tdesktop
whatsapp-for-linux
slack
zoom-us
librewolf
## CLI stuff
dex # .desktop file management, startup
# sct # Display color temperature
xdg-utils # Open stuff
wifi-indicator
]
++ cfg.startup
);
## CLI stuff
dex # .desktop file management, startup
# sct # Display color temperature
xdg-utils # Open stuff
wifi-indicator
] ++ (if pkgs.stdenv.isAarch64 then [ ] else [
gnome.cheese # Webcam check, expensive
# Chat stuff
slack
]));
nki.programs.discord.enable = pkgs.stdenv.isx86_64;
nki.programs.discord.package = pkgs.vesktop;
# OBS
programs.obs-studio = {
@ -152,6 +101,15 @@ in
];
};
# Yellow light!
services.wlsunset = {
enable = true;
# Lausanne
latitude = "46.31";
longitude = "6.38";
};
# Cursor
home.pointerCursor = {
package = pkgs.suwako-cursors;
@ -165,10 +123,7 @@ in
xdg.mimeApps.enable = true;
xdg.mimeApps.associations.added = {
"x-scheme-handler/mailto" = [
"thunderbird.desktop"
"org.gnome.Evolution.desktop"
];
"x-scheme-handler/mailto" = [ "thunderbird.desktop" "org.gnome.Evolution.desktop" ];
"application/pdf" = [ "org.gnome.Evince.desktop" ];
"text/plain" = [ "kakoune.desktop" ];
@ -180,23 +135,10 @@ in
"x-scheme-handler/feed" = [ "thunderbird.desktop" ];
"application/rss+xml" = [ "thunderbird.desktop" ];
"application/x-extension-rss" = [ "thunderbird.desktop" ];
"x-scheme-handler/tg2" = [ "org.telegram.desktop.desktop" ];
"x-scheme-handler/tonsite2" = [ "org.telegram.desktop.desktop" ];
# Other browser stuff
"application/x-extension-htm" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"application/x-extension-html" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"application/x-extension-shtml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"application/xhtml+xml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"application/x-extension-xhtml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"application/x-extension-xht" = [ (desktopFileOf cfg.defaults.webBrowser) ];
};
xdg.mimeApps.defaultApplications = {
# Email
"x-scheme-handler/mailto" = [
"thunderbird.desktop"
"org.gnome.Evolution.desktop"
];
"x-scheme-handler/mailto" = [ "thunderbird.desktop" "org.gnome.Evolution.desktop" ];
"x-scheme-handler/webcal" = [ "thunderbird.desktop" ];
"x-scheme-handler/webcals" = [ "thunderbird.desktop" ];
@ -210,21 +152,14 @@ in
"application/x-extension-rss" = [ "thunderbird.desktop" ];
# Default web browser stuff
"text/html" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"x-scheme-handler/chrome" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"x-scheme-handler/about" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"x-scheme-handler/unknown" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"x-scheme-handler/http" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"x-scheme-handler/https" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"x-scheme-handler/ftp" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"x-scheme-handler/ftps" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"x-scheme-handler/file" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"application/x-extension-htm" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"application/x-extension-html" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"application/x-extension-shtml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"application/xhtml+xml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"application/x-extension-xhtml" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"application/x-extension-xht" = [ (desktopFileOf cfg.defaults.webBrowser) ];
"text/html" = [ cfg.defaults.webBrowser ];
"x-scheme-handler/about" = [ cfg.defaults.webBrowser ];
"x-scheme-handler/unknown" = [ cfg.defaults.webBrowser ];
"x-scheme-handler/http" = [ cfg.defaults.webBrowser ];
"x-scheme-handler/https" = [ cfg.defaults.webBrowser ];
"x-scheme-handler/ftp" = [ cfg.defaults.webBrowser ];
"x-scheme-handler/ftps" = [ cfg.defaults.webBrowser ];
"x-scheme-handler/file" = [ cfg.defaults.webBrowser ];
# Torrent
"application/x-bittorrent" = [ "deluge.desktop" ];
@ -236,20 +171,13 @@ in
# Files
"inode/directory" = [ "dolphin.desktop" ];
# Telegram
"x-scheme-handler/tg2" = "org.telegram.desktop.desktop";
"x-scheme-handler/tonsite2" = "org.telegram.desktop.desktop";
# Discord
"x-scheme-handler/discord" = [ (desktopFileOf cfg.defaults.discord) ];
};
# Add one for kakoune
xdg.desktopEntries."kakoune" = {
name = "Kakoune";
genericName = "Text Editor";
exec = ''${lib.getExe pkgs.kitty} --class kitty-float -o initial_window_width=150c -o initial_window_height=40c ${pkgs.writeShellScript "editor.sh" ''
exec = ''kitty --class kitty-float -o initial_window_width=150c -o initial_window_height=40c ${pkgs.writeShellScript "editor.sh" ''
$EDITOR "$@"
''} %U'';
# exec = "kakoune %U";
@ -288,13 +216,11 @@ in
## Qt
qt.enable = true;
qt.platformTheme.name = "kde";
qt.platformTheme.package = with pkgs.kdePackages; [
plasma-integration
systemsettings
];
qt.platformTheme.package = with pkgs.kdePackages; [ plasma-integration systemsettings ];
qt.style.package = [ pkgs.kdePackages.breeze ];
qt.style.name = "Breeze";
xdg.configFile =
let
f = pkg: {
@ -312,8 +238,7 @@ in
};
autoStartup = listToAttrs (map f cfg.startup);
in
autoStartup
// {
autoStartup // {
## Polkit UI
"autostart/polkit.desktop".text = ''
${builtins.readFile "${pkgs.pantheon.pantheon-agent-polkit}/etc/xdg/autostart/io.elementary.desktop.agent-polkit.desktop"}
@ -328,25 +253,7 @@ in
# dconf.settings."desktop/ibus/general/hotkey" = {
# triggers = hm.gvariant.mkArray hm.gvariant.type.string [ "<Super>z" ];
# };
# Some graphical targets
systemd.user.targets = {
# For system trays, usually after graphical-session and graphical-session-pre
tray = {
Unit.Description = lib.mkDefault "System tray";
Unit.After = [ "graphical-session-pre.target" ];
Unit.Before = [ "graphical-session.target" ];
Unit.BindsTo = [ "graphical-session.target" ];
Install.WantedBy = [ "graphical-session.target" ];
};
# XWayland target
xwayland = {
Unit.Description = "XWayland support";
Unit.After = [ "graphical-session-pre.target" ];
Unit.Before = [ "graphical-session.target" ];
Unit.BindsTo = [ "graphical-session.target" ];
Install.WantedBy = [ "graphical-session.target" ];
};
};
};
}

View file

@ -1,60 +1,42 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
let
notificationModule =
{
config,
pkgs,
lib,
...
}:
notificationModule = { config, pkgs, lib, ... }:
let
swaync = pkgs.swaynotificationcenter;
in
with lib;
mkIf (config.linux.graphical.type == "wayland") {
with lib; mkIf (config.linux.graphical.type == "wayland") {
services.swaync = {
enable = true;
settings.widgets = [
"inhibitors"
"title"
"dnd"
"mpris"
"notifications"
];
settings.widgets = [ "inhibitors" "title" "dnd" "mpris" "notifications" ];
style = ./swaync.css;
};
systemd.user.services.swaync.Install.WantedBy = lib.mkForce [ "sway-session.target" ];
systemd.user.services.swaync.Unit.PartOf = lib.mkForce [ "sway-session.target" ];
programs.my-waybar = {
extraSettings = [
{
modules-right = mkAfter [ "custom/swaync" ];
modules."custom/swaync" = {
tooltip = false;
format = "{icon} {}";
format-icons = {
notification = "<span foreground='red'><sup></sup></span>";
none = "";
dnd-notification = "<span foreground='red'><sup></sup></span>";
dnd-none = "";
inhibited-notification = "<span foreground='red'><sup></sup></span>";
inhibited-none = "";
dnd-inhibited-notification = "<span foreground='red'><sup></sup></span>";
dnd-inhibited-none = "";
};
return-type = "json";
# exec-if = "which swaync-client";
exec = "${swaync}/bin/swaync-client -swb";
on-click = "${swaync}/bin/swaync-client -t -sw";
on-click-right = "${swaync}/bin/swaync-client -d -sw";
escape = true;
programs.my-sway.waybar = {
extraSettings = {
modules-right = mkAfter [ "custom/swaync" ];
modules."custom/swaync" = {
tooltip = false;
format = "{icon} {}";
format-icons = {
notification = "<span foreground='red'><sup></sup></span>";
none = "";
dnd-notification = "<span foreground='red'><sup></sup></span>";
dnd-none = "";
inhibited-notification = "<span foreground='red'><sup></sup></span>";
inhibited-none = "";
dnd-inhibited-notification = "<span foreground='red'><sup></sup></span>";
dnd-inhibited-none = "";
};
}
];
return-type = "json";
# exec-if = "which swaync-client";
exec = "${swaync}/bin/swaync-client -swb";
on-click = "${swaync}/bin/swaync-client -t -sw";
on-click-right = "${swaync}/bin/swaync-client -d -sw";
escape = true;
};
};
extraStyle = mkAfter ''
#custom-swaync {
background: #F0FFFF;
@ -64,55 +46,29 @@ let
};
};
plasmaModule =
{ pkgs, ... }:
{
home.packages = with pkgs.kdePackages; [
discover
kmail
kontact
akonadi
kdepim-runtime
kmail-account-wizard
akonadi-import-wizard
];
xdg.configFile."plasma-workspace/env/wayland.sh".source =
pkgs.writeScript "plasma-wayland-env.sh" ''
export NIXOS_OZONE_WL=1
'';
xdg.dataFile."dbus-1/services/org.freedesktop.Notifications.service".source =
"${pkgs.kdePackages.plasma-workspace}/share/dbus-1/services/org.kde.plasma.Notifications.service";
};
rofi-rbw-script = pkgs.writeTextFile rec {
name = "rofi-rbw-script";
text = ''
#!/usr/bin/env fish
set -a PATH ${
lib.concatMapStringsSep " " (p: "${lib.getBin p}/bin") [
config.programs.rofi.package
pkgs.ydotool
pkgs.rofi-rbw
]
}
rofi-rbw
plasmaModule = { pkgs, ... }: {
home.packages = with pkgs.kdePackages; [
discover
kmail
kontact
akonadi
kdepim-runtime
kmail-account-wizard
akonadi-import-wizard
];
xdg.configFile."plasma-workspace/env/wayland.sh".source = pkgs.writeScript "plasma-wayland-env.sh" ''
export NIXOS_OZONE_WL=1
'';
executable = true;
destination = "/bin/${name}";
meta.mainProgram = name;
xdg.dataFile."dbus-1/services/org.freedesktop.Notifications.service".source = "${pkgs.kdePackages.plasma-workspace}/share/dbus-1/services/org.kde.plasma.Notifications.service";
};
in
with lib;
{
imports = [
notificationModule
plasmaModule
];
imports = [ notificationModule plasmaModule ];
config = mkIf (config.linux.graphical.type == "wayland") {
# Additional packages
home.packages = with pkgs; [
wl-clipboard # Clipboard management
rofi-rbw-script
# Mimic the clipboard stuff in MacOS
(pkgs.writeShellScriptBin "pbcopy" ''
@ -123,34 +79,10 @@ with lib;
'')
];
programs.rofi = {
enable = true;
package = pkgs.rofi-wayland;
cycle = true;
font = "monospace";
terminal = "${lib.getExe config.programs.kitty.package}";
theme = "Paper";
plugins = with pkgs; [
rofi-bluetooth
rofi-calc
rofi-rbw
rofi-power-menu
];
};
home.sessionVariables = {
ANKI_WAYLAND = "1";
};
# Yellow light!
services.wlsunset = {
enable = true;
# Lausanne
latitude = "46.31";
longitude = "6.38";
};
# Notification system
# services.dunst = {
# enable = true;
@ -170,5 +102,9 @@ with lib;
# settings.experimental.per_monitor_dpi = "true";
# };
# Forward wallpaper settings to sway
programs.my-sway.wallpaper = config.linux.graphical.wallpaper;
};
}

View file

@ -1,18 +1,10 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
let
cfg = config.linux.graphical;
in
with lib;
{
imports = [
./x11/hidpi.nix
./x11/i3.nix
];
imports = [ ./x11/hidpi.nix ./x11/i3.nix ];
options.linux.graphical.hasDE = mkOption {
type = types.bool;
description = "When enabled, disable stuff that already comes with a DE";
@ -51,3 +43,4 @@ with lib;
};
};
}

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
@ -23,14 +18,12 @@ let
"10: 10"
];
wsAttrs = builtins.listToAttrs (
map (i: {
name = toString (remainder i 10);
value = builtins.elemAt workspaces (i - 1);
}) (range 1 11)
map
(i: { name = toString (remainder i 10); value = builtins.elemAt workspaces (i - 1); })
(range 1 11)
);
remainder = x: y: x - (builtins.div x y) * y;
range =
from: to:
range = from: to:
let
f = cur: if cur == to then [ ] else [ cur ] ++ f (cur + 1);
in
@ -47,55 +40,27 @@ in
xsession.windowManager.i3 = {
enable = true;
config.assigns = {
"${wsAttrs."1"}" = [ { class = "^firefox$"; } ];
"${wsAttrs."2"}" = [ { class = "^discord$"; } ];
"${wsAttrs."1"}" = [{ class = "^firefox$"; }];
"${wsAttrs."2"}" = [{ class = "^discord$"; }];
};
config.bars = [
{
command = "${pkgs.i3-gaps}/bin/i3bar -t";
statusCommand = "${pkgs.i3status-rust}/bin/i3status-rs ~/.config/i3status-rust/config-default.toml";
position = "top";
colors = {
background = "#00000080";
statusline = "#ffffff";
separator = "#666666";
config.bars = [{
command = "${pkgs.i3-gaps}/bin/i3bar -t";
statusCommand = "${pkgs.i3status-rust}/bin/i3status-rs ~/.config/i3status-rust/config-default.toml";
position = "top";
colors = {
background = "#00000080";
statusline = "#ffffff";
separator = "#666666";
focusedWorkspace = {
background = "#4c7899";
border = "#285577";
text = "#ffffff";
};
activeWorkspace = {
background = "#333333";
border = "#5f676a";
text = "#ffffff";
};
inactiveWorkspace = {
background = "#333333";
border = "#222222";
text = "#888888";
};
urgentWorkspace = {
background = "#2f343a";
border = "#900000";
text = "#ffffff";
};
bindingMode = {
background = "#2f343a";
border = "#900000";
text = "#ffffff";
};
};
}
];
focusedWorkspace = { background = "#4c7899"; border = "#285577"; text = "#ffffff"; };
activeWorkspace = { background = "#333333"; border = "#5f676a"; text = "#ffffff"; };
inactiveWorkspace = { background = "#333333"; border = "#222222"; text = "#888888"; };
urgentWorkspace = { background = "#2f343a"; border = "#900000"; text = "#ffffff"; };
bindingMode = { background = "#2f343a"; border = "#900000"; text = "#ffffff"; };
};
}];
config.focus.newWindow = "none";
config.fonts = {
names = [
"FantasqueSansMono Nerd Font Mono"
"monospace"
];
size = 11.0;
};
config.fonts = { names = [ "FantasqueSansMono Nerd Font Mono" "monospace" ]; size = 11.0; };
config.gaps.outer = 5;
config.gaps.inner = 5;
config.gaps.smartGaps = true;
@ -104,57 +69,53 @@ in
config.window.titlebar = false;
# Keybindings
config.keybindings = lib.mkOptionDefault (
{
## vim-style movements
"${mod}+h" = "focus left";
"${mod}+j" = "focus down";
"${mod}+k" = "focus up";
"${mod}+l" = "focus right";
"${mod}+Shift+h" = "move left";
"${mod}+Shift+j" = "move down";
"${mod}+Shift+k" = "move up";
"${mod}+Shift+l" = "move right";
## Splits
"${mod}+v" = "split v";
"${mod}+Shift+v" = "split h";
## Run
"${mod}+r" = "exec ${pkgs.dmenu}/bin/dmenu_run";
"${mod}+d" = "exec i3-dmenu-desktop --dmenu='${pkgs.dmenu}/bin/dmenu -i'";
}
// (builtins.listToAttrs (
lib.flatten (
map (key: [
{
name = "${mod}+${key}";
value = "workspace ${builtins.getAttr key wsAttrs}";
}
{
name = "${mod}+Shift+${key}";
value = "move to workspace ${builtins.getAttr key wsAttrs}";
}
]) (builtins.attrNames wsAttrs)
)
))
);
config.keybindings = lib.mkOptionDefault ({
## vim-style movements
"${mod}+h" = "focus left";
"${mod}+j" = "focus down";
"${mod}+k" = "focus up";
"${mod}+l" = "focus right";
"${mod}+Shift+h" = "move left";
"${mod}+Shift+j" = "move down";
"${mod}+Shift+k" = "move up";
"${mod}+Shift+l" = "move right";
## Splits
"${mod}+v" = "split v";
"${mod}+Shift+v" = "split h";
## Run
"${mod}+r" = "exec ${pkgs.dmenu}/bin/dmenu_run";
"${mod}+d" = "exec i3-dmenu-desktop --dmenu='${pkgs.dmenu}/bin/dmenu -i'";
} // (
builtins.listToAttrs (lib.flatten (map
(key: [
{
name = "${mod}+${key}";
value = "workspace ${builtins.getAttr key wsAttrs}";
}
{
name = "${mod}+Shift+${key}";
value = "move to workspace ${builtins.getAttr key wsAttrs}";
}
])
(builtins.attrNames wsAttrs))
)));
# Workspace
config.defaultWorkspace = "workspace ${builtins.getAttr "1" wsAttrs}";
config.startup =
[
{ command = "firefox"; }
{ command = "discord"; }
{ command = "dex -ae i3"; }
{ command = "ibus-daemon -drxR"; }
]
++ (
if (config.linux.graphical.wallpaper != "") then
[ { command = "${pkgs.feh}/bin/feh --bg-fill ${config.linux.graphical.wallpaper}"; } ]
else
[ ]
);
config.startup = [
{ command = "firefox"; }
{ command = "discord"; }
{ command = "dex -ae i3"; }
{ command = "ibus-daemon -drxR"; }
] ++
(
if (config.linux.graphical.wallpaper != "")
then [{ command = "${pkgs.feh}/bin/feh --bg-fill ${config.linux.graphical.wallpaper}"; }]
else [ ]
);
};
# i3status
programs.i3status-rust.enable = true;
programs.i3status-rust.bars.default = {
@ -193,3 +154,5 @@ in
};
};
}

View file

@ -1,14 +1,9 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
{
xsession.windowManager.i3.config = mkIf (config.linux.graphical.x11.enablei3) {
startup = [ { command = "${pkgs.flameshot}/bin/flameshot"; } ];
startup = [{ command = "${pkgs.flameshot}/bin/flameshot"; }];
keybindings = mkOptionDefault { "Print" = "exec ${pkgs.flameshot}/bin/flameshot gui"; };
};
}

View file

@ -1,87 +1,36 @@
# A monitor list and common sway set up
{
config,
pkgs,
lib,
...
}:
with lib;
{ config, pkgs, lib, ... }: with lib;
let
monitors = {
# Internal
"framework" = {
name = "BOE 0x0BCA Unknown";
meta.mode = {
width = 2256;
height = 1504;
refresh = 60.0;
};
mode = "2256x1504@60Hz";
scale = 1.25;
};
"yoga" = {
name = "AU Optronics 0xD291 Unknown";
meta.connection = "eDP-1";
meta.mode = {
width = 1920;
height = 1080;
refresh = 60.026;
};
scale = 1;
};
# External
## Work @ EPFL
"work" = {
name = "LG Electronics LG ULTRAFINE 301MAXSGHD10";
meta.mode = {
width = 3840;
height = 2160;
refresh = 60.0;
};
mode = "3840x2160@60Hz";
scale = 1.25;
};
"home_4k" = {
name = "AOC U28G2G6B PPYP2JA000013";
mode = "3840x2160@60Hz";
scale = 1.5;
adaptive_sync = "on";
meta = {
connection = "DP-2";
mode = {
width = 3840;
height = 2160;
refresh = 60.0;
};
fixedPosition = {
x = 0;
y = 0;
};
niriName = "PNP(AOC) U28G2G6B PPYP2JA000013";
};
# render_bit_depth = "10";
};
"home_1440" = {
name = "AOC Q27G2G3R3B VXJP6HA000442";
mode = "2560x1440@165Hz";
adaptive_sync = "on";
meta = {
connection = "DP-3";
mode = {
width = 2560;
height = 1440;
refresh = 165.0;
};
fixedPosition = {
x = 2560;
y = 0;
};
niriName = "PNP(AOC) Q27G2G3R3B VXJP6HA000442";
};
};
"viewsonic_1080" = {
name = "ViewSonic Corporation XG2402 SERIES V4K182501054";
meta.mode = {
width = 1920;
height = 1080;
refresh = 144.0;
};
mode = "1920x1080@144Hz";
adaptive_sync = "on";
};
@ -89,21 +38,9 @@ let
eachMonitor = _name: monitor: {
name = monitor.name;
value =
builtins.removeAttrs monitor [
"scale"
"name"
"meta"
]
// (lib.optionalAttrs (monitor ? scale) {
scale = toString monitor.scale;
})
// {
mode = with monitor.meta.mode; "${toString width}x${toString height}@${toString refresh}Hz";
}
// (lib.optionalAttrs (monitor.meta ? fixedPosition) {
position = with monitor.meta.fixedPosition; "${toString x} ${toString y}";
});
value = builtins.removeAttrs monitor [ "scale" "name" ] // (if monitor ? scale then {
scale = toString monitor.scale;
} else { });
};
in
{
@ -117,3 +54,4 @@ in
mapAttrs' eachMonitor config.common.monitors
);
}

View file

@ -0,0 +1,27 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.nki.programs.discord;
in
{
options.nki.programs.discord = {
enable = mkEnableOption "Enable discord";
basePackage = mkOption {
type = types.package;
default = pkgs.discord;
description = "The base Discord package that will get patched";
};
package = mkOption {
type = types.package;
default = cfg.basePackage.override { nss = pkgs.nss_latest; };
description = "The actual package to use";
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
};
}

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib;
let
@ -96,13 +91,10 @@ in
# Add an extra syntax_color config
xdg.configFile."broot/conf.toml".source = mkOverride 1 (
tomlFormat.generate "broot-config" (
with config.programs.broot;
{
inherit (settings) verbs modal skin;
syntax_theme = "base16-ocean.light";
}
)
tomlFormat.generate "broot-config" (with config.programs.broot; {
inherit (settings) verbs modal skin;
syntax_theme = "base16-ocean.light";
})
);
};
}

View file

@ -1,26 +1,40 @@
{
config,
options,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.programs.my-kakoune;
autoloadModule = types.submodule {
options = {
name = mkOption {
type = types.str;
description = "Name of the autoload script/folder. It might affect kakoune's load order.";
};
src = mkOption {
type = types.path;
description = "Path to the autoload script/folder.";
};
wrapAsModule = mkOption {
type = types.bool;
default = false;
description = "Wrap the given source file in a `provide-module` command. Fails if the `src` is not a single file.";
};
activationScript = mkOption {
type = types.nullOr types.lines;
default = null;
description = "Add an activation script to the module. It will be wrapped in a `hook global KakBegin .*` wrapper.";
};
};
};
in
{
imports = [
./fish-session.nix
./tree-sitter.nix
];
imports = [ ./kak-lsp.nix ./fish-session.nix ./tree-sitter.nix ];
options.programs.my-kakoune = {
enable = mkEnableOption "My version of the kakoune configuration";
package = mkOption {
type = types.package;
default = pkgs.nki-kakoune;
default = pkgs.kakoune;
description = "The kakoune package to be installed";
};
rc = mkOption {
@ -28,16 +42,22 @@ in
default = "";
description = "Content of the kakrc file. A line-concatenated string";
};
autoload = mkOption {
type = types.listOf autoloadModule;
default = [ ];
description = "Sources to autoload";
};
themes = mkOption {
type = types.attrsOf types.path;
default = { };
description = "Themes to load";
};
extraFaces = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Extra faces to include";
};
autoloadFile = mkOption {
type = options.xdg.configFile.type;
default = { };
description = "Extra autoload files";
};
};
config = mkIf cfg.enable {
@ -45,18 +65,44 @@ in
xdg.configFile =
let
kakouneAutoload = { name, src, wrapAsModule ? false, activationScript ? null }:
[
(if !wrapAsModule then {
name = "kak/autoload/${name}";
value.source = src;
} else {
name = "kak/autoload/${name}/module.kak";
value.text = ''
provide-module ${name} %
${readFile src}
'';
})
] ++ (if activationScript == null then [ ] else [{
name = "kak/autoload/on-load/${name}.kak";
value.text = ''
hook global KakBegin .* %{
${activationScript}
}
'';
}]);
kakouneThemes = builtins.listToAttrs (builtins.attrValues (
builtins.mapAttrs
(name: src: {
name = "kak/colors/${name}.kak";
value.source = src;
})
cfg.themes
));
kakouneFaces =
let
txt = strings.concatStringsSep "\n" (
builtins.attrValues (
builtins.mapAttrs (name: face: "face global ${name} \"${face}\"") cfg.extraFaces
)
);
txt = strings.concatStringsSep "\n" (builtins.attrValues (builtins.mapAttrs (name: face: "face global ${name} \"${face}\"") cfg.extraFaces));
in
pkgs.writeText "faces.kak" txt;
in
{
"kak/autoload/builtin".source = "${cfg.package}/share/kak/autoload";
# kakrc
"kak/kakrc".text = ''
${cfg.rc}
@ -64,13 +110,15 @@ in
# Load faces
source ${kakouneFaces}
'';
}
// lib.mapAttrs' (name: attrs: {
name = "kak/autoload/${name}";
value = attrs // {
target = "kak/autoload/${name}";
};
}) cfg.autoloadFile;
xdg.dataFile."kak".source = "${cfg.package}/share/kak";
} //
(builtins.listToAttrs (lib.lists.flatten (map kakouneAutoload ([
# include the original autoload files
{
name = "rc";
src = "${cfg.package}/share/kak/autoload/rc";
}
] ++ cfg.autoload))))
// kakouneThemes;
};
}

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib;
let
@ -32,6 +27,7 @@ in
# Rebind $VISUAL, $EDITOR and e command
set -gx VISUAL "kak -c $kak_session"
set -gx EDITOR "kak -c $kak_session"
alias e="kak -c $kak_session"
'';
kill-kak-session = ''
@ -46,6 +42,7 @@ in
# Rebind $VISUAL, $EDITOR and e command
set -gx VISUAL "kak"
set -gx EDITOR "kak"
alias e="kak"
'';
};
programs.fish.tide = {

View file

@ -0,0 +1,213 @@
{ config, pkgs, lib, ... }:
with lib;
let
lspConfig =
{
language_ids = {
c = "c_cpp";
cpp = "c_cpp";
javascript = "javascriptreact";
typescript = "typescriptreact";
protobuf = "proto";
sh = "shellscript";
};
language_servers = {
ccls = {
args = [ "-v=2" "-log-file=/tmp/ccls.log" ];
command = "ccls";
filetypes = [ "c" "cpp" ];
roots = [ "compile_commands.json" ".cquery" ".git" ];
};
gopls = {
command = "gopls";
filetypes = [ "go" ];
offset_encoding = "utf-8";
roots = [ "Gopkg.toml" "go.mod" ".git" ".hg" ];
settings = { gopls = { hoverKind = "SynopsisDocumentation"; semanticTokens = true; }; };
settings_section = "gopls";
};
haskell-language-server = {
args = [ "--lsp" ];
command = "haskell-language-server-wrapper";
filetypes = [ "haskell" ];
roots = [ "Setup.hs" "stack.yaml" "*.cabal" "package.yaml" ];
settings_section = "haskell";
};
nil = {
command = "${pkgs.nil}/bin/nil";
filetypes = [ "nix" ];
roots = [ "flake.nix" "shell.nix" ".git" ];
settings.nil = {
formatting.command = [ "${getExe pkgs.nixpkgs-fmt}" ];
};
};
pyls = {
command = "pyls";
filetypes = [ "python" ];
offset_encoding = "utf-8";
roots = [ "requirements.txt" "setup.py" ".git" ".hg" ];
};
};
semantic_tokens.faces = [
## Items
# (Rust) Macros
{ face = "attribute"; token = "attribute"; }
{ face = "attribute"; token = "derive"; }
{ face = "macro"; token = "macro"; } # Function-like Macro
# Keyword and Fixed Tokens
{ face = "keyword"; token = "keyword"; }
{ face = "operator"; token = "operator"; }
# Functions and Methods
{ face = "function"; token = "function"; }
{ face = "method"; token = "method"; }
# Constants
{ face = "string"; token = "string"; }
{ face = "format_specifier"; token = "formatSpecifier"; }
# Variables
{ face = "variable"; token = "variable"; modifiers = [ "readonly" ]; }
{ face = "mutable_variable"; token = "variable"; }
{ face = "module"; token = "namespace"; }
{ face = "variable"; token = "type_parameter"; }
{ face = "class"; token = "enum"; }
{ face = "class"; token = "struct"; }
{ face = "class"; token = "trait"; }
{ face = "class"; token = "union"; }
{ face = "class"; token = "class"; }
## Comments
{ face = "documentation"; token = "comment"; modifiers = [ "documentation" ]; }
{ face = "comment"; token = "comment"; }
];
server = { timeout = 1800; };
snippet_support = false;
verbosity = 255;
};
languageServerOption = types.submodule {
options = {
filetypes = mkOption {
type = types.listOf types.str;
description = "The list of filetypes to assign the language to";
};
roots = mkOption {
type = types.listOf types.str;
description = "The list of root filenames that are used to determine the project root";
};
command = mkOption {
type = types.str;
description = "The LSP server command to be called.";
};
args = mkOption {
type = types.listOf types.str;
default = [ ];
description = "The arguments passed onto the LSP server.";
};
offset_encoding = mkOption {
type = types.nullOr (types.enum [ "utf-8" ]);
default = null;
description = "The offset encoding used by the LSP server.";
};
settings_section = mkOption {
type = types.nullOr types.str;
default = null;
description = "The settings section to be sent to LSP server.";
};
settings = mkOption {
type = types.nullOr (types.attrsOf types.anything);
default = null;
description = "Additional settings to be passed to the LSP server.";
};
package = mkOption {
type = types.nullOr types.package;
default = null;
description = "The default package of the language server. Will be appended as the ending segments of the PATH to kak-lsp";
};
};
};
cfg = config.programs.kak-lsp;
serverPackages =
filter (v: v != null)
(lib.mapAttrsToList (_: serv: serv.package) cfg.languageServers);
wrappedPackage = pkgs.symlinkJoin {
name = "kak-lsp-wrapped";
nativeBuildInputs = [ pkgs.makeWrapper ];
paths = [ cfg.package ];
postBuild = ''
wrapProgram $out/bin/kak-lsp --suffix PATH ":" ${lib.makeBinPath serverPackages}
'';
};
in
{
options.programs.kak-lsp = {
enable = mkEnableOption "Enable kak-lsp support";
package = mkOption {
type = types.package;
default = pkgs.kak-lsp;
};
enableSnippets = mkOption {
type = types.bool;
default = false;
description = "Enable snippet support";
};
semanticTokens.faces = mkOption {
type = types.listOf types.anything;
default = lspConfig.semantic_tokens.faces;
description = "The semantic tokens faces mapping given to kak";
};
semanticTokens.additionalFaces = mkOption {
type = types.listOf types.anything;
default = [ ];
description = "The semantic tokens faces mapping given to kak";
};
serverTimeout = mkOption {
type = types.int;
default = 1000;
description = "Server timeout";
};
languageServers = mkOption {
type = types.attrsOf languageServerOption;
default = { };
description = "The language options";
};
languageIds = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Language IDs to be sent to the LSP";
};
};
config = mkIf cfg.enable
{
home.packages = [ wrappedPackage ];
# Configurations
xdg.configFile."kak-lsp/kak-lsp.toml" =
let
toml = pkgs.formats.toml { };
toLspConfig = lib.filterAttrsRecursive (n: v: n != "package" && v != null);
in
{
source = toml.generate "config.toml"
{
semantic_tokens.faces = cfg.semanticTokens.faces ++ cfg.semanticTokens.additionalFaces;
server.timeout = cfg.serverTimeout;
snippet_support = cfg.enableSnippets;
verbosity = 255;
language_server = toLspConfig (lspConfig.language_servers // cfg.languageServers);
language_ids = lspConfig.language_ids // cfg.languageIds;
};
};
};
}

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.programs.my-kakoune.tree-sitter;
@ -19,44 +14,14 @@ let
default = "src";
};
grammar.compile = {
command = mkOption {
type = types.str;
default = "${pkgs.gcc}/bin/gcc";
};
args = mkOption {
type = types.listOf types.str;
default = [
"-c"
"-fpic"
"../parser.c"
"../scanner.c"
"-I"
".."
];
};
flags = mkOption {
type = types.listOf types.str;
default = [ "-O3" ];
};
command = mkOption { type = types.str; default = "${pkgs.gcc}/bin/gcc"; };
args = mkOption { type = types.listOf types.str; default = [ "-c" "-fpic" "../parser.c" "../scanner.c" "-I" ".." ]; };
flags = mkOption { type = types.listOf types.str; default = [ "-O3" ]; };
};
grammar.link = {
command = mkOption {
type = types.str;
default = "${pkgs.gcc}/bin/gcc";
};
args = mkOption {
type = types.listOf types.str;
default = [
"-shared"
"-fpic"
"parser.o"
"scanner.o"
];
};
flags = mkOption {
type = types.listOf types.str;
default = [ "-O3" ];
};
command = mkOption { type = types.str; default = "${pkgs.gcc}/bin/gcc"; };
args = mkOption { type = types.listOf types.str; default = [ "-shared" "-fpic" "parser.o" "scanner.o" ]; };
flags = mkOption { type = types.listOf types.str; default = [ "-O3" ]; };
};
queries.src = mkOption {
type = types.package;
@ -68,42 +33,6 @@ let
};
};
};
mkGrammarPackage =
{
name,
src,
grammarPath ? "src",
grammarCompileArgs ? [
"-O3"
"-c"
"-fpic"
"../parser.c"
"../scanner.c"
"-I"
".."
],
grammarLinkArgs ? [
"-shared"
"-fpic"
"parser.o"
"scanner.o"
],
}:
pkgs.stdenv.mkDerivation {
inherit src;
name = "kak-tree-sitter-grammar-${name}.so";
version = "latest";
buildPhase = ''
mkdir ${grammarPath}/build
cd ${grammarPath}/build
$CC ${lib.concatStringsSep " " grammarCompileArgs}
$CC ${lib.concatStringsSep " " grammarLinkArgs} -o ${name}.so
'';
installPhase = ''
cp ${name}.so $out
'';
};
in
{
options.programs.my-kakoune.tree-sitter = {
@ -265,54 +194,53 @@ in
toTs = name: "ts_${strings.concatStringsSep "_" (strings.splitString "." name)}";
toScm = name: strings.concatStringsSep "." (strings.splitString "_" name);
definedFaces = attrsets.mapAttrs' (name: value: {
inherit value;
name = toTs name;
}) allGroups;
aliasFaces = attrsets.mapAttrs' (name: value: {
name = toTs name;
value = "@${toTs value}";
}) aliases;
definedFaces = attrsets.mapAttrs' (name: value: { inherit value; name = toTs name; }) allGroups;
aliasFaces = attrsets.mapAttrs' (name: value: { name = toTs name; value = "@${toTs value}"; }) aliases;
faces = attrsets.recursiveUpdate definedFaces aliasFaces;
toml = pkgs.formats.toml { };
toLanguageConf =
name: lang: with lang; {
grammar = {
source.local.path = mkGrammarPackage {
inherit name;
src = grammar.src;
grammarPath = grammar.path;
grammarCompileArgs = grammar.compile.flags ++ grammar.compile.args;
grammarLinkArgs = grammar.link.flags ++ grammar.link.args;
};
compile = grammar.compile.command;
compile_args = grammar.compile.args;
compile_flags = grammar.compile.flags;
link = grammar.link.command;
link_args = grammar.link.args ++ [
"-o"
"${name}.so"
];
link_flags = grammar.link.flags;
};
queries = rec {
path = if queries.path == null then "runtime/queries/${name}" else queries.path;
source.local.path = "${queries.src}/${path}";
};
srcName = src: lib.removePrefix "/nix/store/" src.outPath;
mkGitRepo = src: pkgs.runCommandLocal "${src.name}-git" { } ''
cp -r --no-preserve=all ${src} $out
cd $out
if ! test -d $out/.git; then
${lib.getExe pkgs.git} init -b ${srcName src}
${lib.getExe pkgs.git} config user.email "a@b.com"
${lib.getExe pkgs.git} config user.name "a"
${lib.getExe pkgs.git} add .
${lib.getExe pkgs.git} commit -m "Just making a git commit"
fi
'';
toLanguageConf = name: lang: with lang; {
grammar = {
inherit (grammar) path;
source.git.url = "${mkGitRepo grammar.src}";
source.git.pin = "${srcName grammar.src}";
compile = grammar.compile.command;
compile_args = grammar.compile.args;
compile_flags = grammar.compile.flags;
link = grammar.link.command;
link_args = grammar.link.args ++ [ "-o" "${name}.so" ];
link_flags = grammar.link.flags;
};
queries = {
source.git.url = "${mkGitRepo queries.src}";
source.git.pin = "${srcName queries.src}";
path = if queries.path == null then "runtime/queries/${name}" else queries.path;
};
};
in
mkIf cfg.enable {
assertions =
with lib.asserts;
(
[ ]
++ attrsets.mapAttrsToList (name: _: {
assertion = (!(builtins.hasAttr name allGroups));
message = "${name} was both defined and aliased";
}) aliases
);
assertions = with lib.asserts; ([ ]
++ attrsets.mapAttrsToList
(name: _: {
assertion = (! (builtins.hasAttr name allGroups));
message = "${name} was both defined and aliased";
})
aliases
);
home.packages = [ cfg.package ];
xdg.configFile."kak-tree-sitter/config.toml" = {
@ -321,14 +249,15 @@ in
features = cfg.features;
language = builtins.mapAttrs toLanguageConf cfg.languages;
};
onChange = ''
export PATH=$PATH:${lib.getBin pkgs.gcc}
${cfg.package}/bin/ktsctl sync -a
'';
};
programs.my-kakoune.extraFaces = faces;
programs.my-kakoune.autoloadFile."kak-tree-sitter.kak".text = ''
# Enable kak-tree-sitter
eval %sh{kak-tree-sitter --kakoune -d --server --init $kak_session}
map global normal <c-t> ": enter-user-mode tree-sitter<ret>"
'';
};
}

View file

@ -1,32 +0,0 @@
{
pkgs,
config,
lib,
...
}:
let
cfg = config.nki.programs.kitty;
cmd = "cmd";
in
with lib;
{
programs.kitty = mkIf (cfg.enable && pkgs.stdenv.isDarwin) {
# Darwin-specific setup
darwinLaunchOptions = [
"--single-instance"
"--start-as=fullscreen"
];
# Tabs and layouts keybindings
keybindings = {
# Backslash
"0x5d" = "send_text all \\u005c";
};
settings = {
# MacOS specific
macos_option_as_alt = "left";
};
};
}

View file

@ -1,49 +1,14 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
let
cfg = config.nki.programs.kitty;
theme =
{
lib,
options,
config,
...
}:
{
programs.kitty = lib.mkIf config.nki.programs.kitty.enable (
if builtins.hasAttr "themeFile" options.programs.kitty then
{
themeFile = "ayu_light";
}
else
{
theme = "Ayu Light";
}
);
};
in
with lib;
{
imports = [
theme
./darwin.nix
./linux.nix
./tabs.nix
];
imports = [ ./linux.nix ./tabs.nix ];
options.nki.programs.kitty = {
enable = mkEnableOption "Enable kitty";
setDefault = mkOption {
type = types.bool;
description = "Set kitty as default terminal";
default = true;
};
package = mkOption {
type = types.package;
@ -76,106 +41,69 @@ with lib;
};
};
config = mkIf cfg.enable {
linux.graphical = mkIf cfg.setDefault {
defaults.terminal.package = cfg.package;
};
programs.kitty = {
enable = true;
config.programs.kitty = mkIf cfg.enable {
enable = true;
package = cfg.package;
package = cfg.package;
font.package = pkgs.fantasque-sans-mono;
font.name = "Fantasque Sans Mono";
font.size = cfg.fontSize;
font.package = pkgs.fantasque-sans-mono;
font.name = "Fantasque Sans Mono";
font.size = cfg.fontSize;
settings =
let
# Background color and transparency
background =
if isNull cfg.background then
{
background_opacity = "0.93";
dynamic_background_opacity = true;
}
else
{
background_image = "${cfg.background}";
background_image_layout = "scaled";
background_tint = "0.85";
};
in
mkMerge [
background
{
# Scrollback (128MBs)
scrollback_pager_history_size = 128;
theme = "Ayu Light";
# Disable Shell integration (leave it for Nix)
shell_integration = "no-rc";
# Allow remote control (for kakoune integration)
allow_remote_control = true;
# Mouse focus
focus_follows_mouse = true;
}
];
keybindings = {
"${cfg.cmd}+shift+equal" = "no_op"; # Not possible with a JIS keyboard
"${cfg.cmd}+shift+^" = "change_font_size all +2.0"; # ... so use ^ instead
## Clear screen
"${cfg.cmd}+backspace" = "clear_terminal to_cursor active";
"${cfg.cmd}+shift+backspace" = "clear_terminal reset active";
## Command scrolling
"${cfg.cmd}+shift+j" = "scroll_to_prompt 1";
"${cfg.cmd}+shift+k" = "scroll_to_prompt -1";
};
extraConfig =
let
# Nerd Fonts glyph map
glyphMap = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/Sharparam/dotfiles/main/kitty/.config/kitty/font-nerd-symbols.conf";
hash = "sha256-1OaDWLC3y8ASD2ttRWWgPEpRnfKXu6H6vS3cFVpzT0o=";
settings =
let
# Background color and transparency
background =
if isNull cfg.background then {
background_opacity = "0.85";
dynamic_background_opacity = true;
} else {
background_image = "${cfg.background}";
background_image_layout = "scaled";
background_tint = "0.85";
};
in
''
include ${glyphMap}
'';
in
mkMerge [
background
{
# Scrollback (128MBs)
scrollback_pager_history_size = 128;
# Disable Shell integration (leave it for Nix)
shell_integration = "no-rc";
# Allow remote control (for kakoune integration)
allow_remote_control = true;
# Mouse focus
focus_follows_mouse = true;
}
];
keybindings = {
"${cfg.cmd}+shift+equal" = "no_op"; # Not possible with a JIS keyboard
"${cfg.cmd}+shift+^" = "change_font_size all +2.0"; # ... so use ^ instead
## Clear screen
"${cfg.cmd}+backspace" = "clear_terminal to_cursor active";
"${cfg.cmd}+shift+backspace" = "clear_terminal reset active";
## Hints
"${cfg.cmd}+shift+p>n" = "kitten hints --type=linenum --linenum-action=tab kak {path} +{line}";
};
# Open protocol
xdg.configFile."kitty/open-actions.conf".text = ''
protocol file
fragment_matches [0-9]+
action launch --type=overlay --cwd=current -- $\{EDITOR} +$\{FRAGMENT} -- $\{FILE_PATH}
# Open HTML files with xdg-open
protocol file
mime text/html
action launch xdg-open $\{FILE_PATH}
# Open text files without fragments in the editor
protocol file
mime text/*
action launch --type=overlay --cwd=current -- $\{EDITOR} -- $\{FILE_PATH}
# Open other files with xdg-open
protocol file
action launch xdg-open $\{FILE_PATH}
'';
programs.fish.shellAliases = {
e = lib.mkForce "kitten edit-in-kitty";
"ssh+" = "kitten ssh";
"clip" = "kitten clipboard";
"eg" = "kitten hyperlinked-grep";
"icat" = "kitten icat";
"notify" = "kitten notify";
};
extraConfig =
let
# Nerd Fonts glyph map
glyphMap = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/Sharparam/dotfiles/main/kitty/.config/kitty/font-nerd-symbols.conf";
hash = "sha256-1OaDWLC3y8ASD2ttRWWgPEpRnfKXu6H6vS3cFVpzT0o=";
};
in
''
include ${glyphMap}
'';
};
}

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
let
cfg = config.nki.programs.kitty;
in

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
let
cfg = config.nki.programs.kitty;
@ -12,33 +7,33 @@ in
with lib;
{
programs.kitty = mkIf cfg.enableTabs {
keybindings =
{
"${cmd}+t" = "new_tab_with_cwd";
"${cmd}+shift+t" = "new_tab";
"${cmd}+shift+o" = "launch --cwd=current --location=vsplit";
"${cmd}+o" = "launch --cwd=current --location=hsplit";
"${cmd}+r" = "start_resizing_window";
"${cmd}+shift+r" = "layout_action rotate";
## Move the active window in the indicated direction
"${cmd}+shift+h" = "move_window left";
"${cmd}+shift+k" = "move_window up";
"${cmd}+shift+j" = "move_window down";
"${cmd}+shift+l" = "move_window right";
## Switch focus to the neighboring window in the indicated direction
"${cmd}+h" = "neighboring_window left";
"${cmd}+k" = "neighboring_window up";
"${cmd}+j" = "neighboring_window down ";
"${cmd}+l" = "neighboring_window right";
## Detach window to its own tab
"${cmd}+shift+d" = "detach_window new-tab";
## Change layout to fullscreen (stack) and back
"${cmd}+f" = "toggle_layout stack";
}
# Tab bindings
// builtins.listToAttrs (
map (x: attrsets.nameValuePair "${cmd}+${toString x}" "goto_tab ${toString x}") (lists.range 1 9)
);
keybindings = {
"${cmd}+t" = "new_tab_with_cwd";
"${cmd}+shift+t" = "new_tab";
"${cmd}+shift+o" = "launch --cwd=current --location=vsplit";
"${cmd}+o" = "launch --cwd=current --location=hsplit";
"${cmd}+r" = "start_resizing_window";
"${cmd}+shift+r" = "layout_action rotate";
## Move the active window in the indicated direction
"${cmd}+shift+h" = "move_window left";
"${cmd}+shift+k" = "move_window up";
"${cmd}+shift+j" = "move_window down";
"${cmd}+shift+l" = "move_window right";
## Switch focus to the neighboring window in the indicated direction
"${cmd}+h" = "neighboring_window left";
"${cmd}+k" = "neighboring_window up";
"${cmd}+j" = "neighboring_window down ";
"${cmd}+l" = "neighboring_window right";
## Detach window to its own tab
"${cmd}+shift+d" = "detach_window new-tab";
## Change layout to fullscreen (stack) and back
"${cmd}+f" = "toggle_layout stack";
}
# Tab bindings
// builtins.listToAttrs
(map
(x: attrsets.nameValuePair "${cmd}+${toString x}" "goto_tab ${toString x}")
(lists.range 1 9));
settings = {
# Tab settings
tab_bar_edge = "top";

View file

@ -1,583 +0,0 @@
{
config,
osConfig,
lib,
pkgs,
...
}:
let
cfg = config.programs.my-niri;
sh = config.lib.niri.actions.spawn "sh" "-c";
playerctl = lib.getExe pkgs.playerctl;
amixer = lib.getExe' pkgs.alsa-utils "amixer";
brightnessctl = lib.getExe pkgs.brightnessctl;
app-menu = "${pkgs.dmenu}/bin/dmenu_path | ${pkgs.bemenu}/bin/bemenu | ${pkgs.findutils}/bin/xargs niri msg action spawn --";
wallpaper = config.linux.graphical.wallpaper;
xwayland-display = ":0";
# Override for lack of per-keyboard layout
ydotool-en = pkgs.writeScriptBin "ydotool" ''
#!/usr/bin/env sh
niri msg action switch-layout 1 && fcitx5-remote -c # us
${lib.getExe pkgs.ydotool} "$@"
niri msg action switch-layout 0 # ja
'';
in
{
options.programs.my-niri = {
enable = lib.mkEnableOption "My own niri configuration";
enableLaptop = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable laptop options";
};
lock-command = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "The command to lock the screen";
default =
[ "${pkgs.swaylock}/bin/swaylock" ]
++ (
if wallpaper == "" then
[ "" ]
else
[
"-i"
"${wallpaper}"
"-s"
"fill"
]
)
++ [
"-l"
"-k"
];
};
workspaces = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule {
options = {
name = lib.mkOption {
type = lib.types.str;
description = "workspace name";
};
fixed = lib.mkOption {
type = lib.types.bool;
default = true;
description = "whether workspace always exists";
};
monitor = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "Default monitor to spawn workspace in";
};
};
}
);
description = "A mapping of ordering to workspace names, for fixed workspaces";
};
};
config = lib.mkIf cfg.enable {
home.packages = [ ydotool-en ];
programs.my-niri.workspaces = {
# Default workspaces, always there
"01" = {
name = "🌏 web";
};
"02" = {
name = "💬 chat";
};
"03" = {
name = " code";
};
"04" = {
name = "🎶 music";
};
"05" = {
name = "🔧 extra";
};
"06" = {
name = "🧰 6";
};
"07" = {
name = "🔩 7";
};
"08" = {
name = "🛠 8";
};
"09" = {
name = "🔨 9";
};
"10" = {
name = "🎲 misc";
};
"99" = {
name = "📧 Email";
};
};
systemd.user.services.swaync.Install.WantedBy = [ "niri.service" ];
systemd.user.services.swaync.Unit.After = [ "niri.service" ];
systemd.user.targets.tray.Unit.After = [ "niri.service" ];
systemd.user.targets.xwayland.Unit.After = [ "niri.service" ];
programs.my-waybar = {
enable = true;
enableLaptopBars = lib.mkDefault cfg.enableLaptop;
};
systemd.user.services.waybar.Unit.After = [ "niri.service" ];
systemd.user.services.waybar.Install.WantedBy = [ "niri.service" ];
# xwayland-satellite
systemd.user.services.niri-xwayland-satellite = lib.mkIf cfg.enable {
Unit = {
Description = "XWayland Client for niri";
PartOf = [ "xwayland.target" ];
Before = [
"xwayland.target"
"xdg-desktop-autostart.target"
];
After = [ "niri.service" ];
};
Install.WantedBy = [ "niri.service" ];
Install.UpheldBy = [ "niri.service" ];
Service.Slice = "session.slice";
Service.Type = "notify";
Service.ExecStart = "${lib.getExe pkgs.xwayland-satellite} ${xwayland-display}";
Service.ExecStartPost = [ "systemctl --user set-environment DISPLAY=${xwayland-display}" ];
Service.ExecStopPost = [ "systemctl --user unset-environment" ];
};
programs.niri.settings = {
environment =
{
QT_QPA_PLATFORM = "wayland";
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
QT_IM_MODULE = "fcitx";
# export NIXOS_OZONE_WL=1 # Until text-input is merged
DISPLAY = xwayland-display;
}
// lib.optionalAttrs osConfig.services.desktopManager.plasma6.enable {
XDG_MENU_PREFIX = "plasma-";
};
input.keyboard.xkb = {
layout = "jp,us";
};
input.touchpad = lib.mkIf cfg.enableLaptop {
tap = true;
dwt = true;
natural-scroll = true;
middle-emulation = true;
};
input.mouse = {
accel-profile = "flat";
};
input.warp-mouse-to-focus = true;
input.focus-follows-mouse = {
enable = true;
max-scroll-amount = "0%";
};
outputs =
let
eachMonitor = _: monitor: {
name = monitor.meta.niriName or monitor.name; # Niri might not find the monitor by name
value = {
mode = monitor.meta.mode;
position = monitor.meta.fixedPosition or null;
scale = monitor.scale or 1;
variable-refresh-rate = (monitor.adaptive_sync or "off") == "on";
};
};
in
lib.mapAttrs' eachMonitor config.common.monitors;
spawn-at-startup = [
# Wallpaper
{
command = [
(lib.getExe pkgs.swaybg)
"-i"
"${wallpaper}"
"-m"
"fill"
];
}
# Waybar
{
command = [
"systemctl"
"--user"
"start"
"xdg-desktop-portal-gtk.service"
"xdg-desktop-portal.service"
];
}
];
layout = {
gaps = 16;
preset-column-widths = [
{ proportion = 1. / 3.; }
{ proportion = 1. / 2.; }
{ proportion = 2. / 3.; }
];
default-column-width.proportion = 1. / 2.;
focus-ring = {
width = 4;
active.gradient = {
from = "#00447AFF";
to = "#71C4FFAA";
angle = 45;
};
inactive.color = "#505050";
};
border.enable = false;
struts =
let
v = 8;
in
{
left = v;
right = v;
bottom = v;
top = v;
};
};
prefer-no-csd = true;
workspaces =
let
fixedWorkspaces = lib.filterAttrs (_: w: w.fixed) cfg.workspaces;
workspaceConfig = lib.mapAttrs (
_: w:
{
inherit (w) name;
}
// (lib.optionalAttrs (w.monitor != null) {
open-on-output = w.monitor;
})
) fixedWorkspaces;
in
workspaceConfig;
window-rules = [
# Rounded Corners
{
geometry-corner-radius =
let
v = 8.0;
in
{
bottom-left = v;
bottom-right = v;
top-left = v;
top-right = v;
};
clip-to-geometry = true;
}
# Workspace assignments
{
open-on-workspace = cfg.workspaces."01".name;
open-maximized = true;
matches = [
{
at-startup = true;
app-id = "^firefox$";
}
{
at-startup = true;
app-id = "^librewolf$";
}
{
at-startup = true;
app-id = "^zen$";
}
];
}
{
open-on-workspace = cfg.workspaces."02".name;
open-maximized = true;
matches = [
{ title = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; }
{ title = "VencordDesktop"; }
{ app-id = "VencordDesktop"; }
{ title = "vesktop"; }
{ app-id = "vesktop"; }
{ title = "Slack"; }
];
}
{
open-on-workspace = cfg.workspaces."99".name;
open-maximized = true;
matches = [
{ app-id = "thunderbird"; }
{ app-id = "evolution"; }
];
}
# Floating
{
open-floating = true;
matches = [
{ app-id = ".*float.*"; }
{ app-id = "org\\.freedesktop\\.impl\\.portal\\.desktop\\..*"; }
{ title = ".*float.*"; }
{ title = "Extension: .*Bitwarden.*"; }
{ app-id = "Rofi"; }
];
}
# xwaylandvideobridge
{
matches = [ { app-id = "^xwaylandvideobridge$"; } ];
open-floating = true;
focus-ring.enable = false;
opacity = 0.0;
default-floating-position = {
x = 0;
y = 0;
relative-to = "bottom-right";
};
min-width = 1;
max-width = 1;
min-height = 1;
max-height = 1;
}
# Kitty dimming
{
matches = [ { app-id = "kitty"; } ];
excludes = [ { is-focused = true; } ];
opacity = 0.95;
}
];
layer-rules = [
{
matches = [ { namespace = "^swaync-.*"; } ];
block-out-from = "screen-capture";
}
];
binds = with config.lib.niri.actions; {
# Mod-Shift-/, which is usually the same as Mod-?,
# shows a list of important hotkeys.
"Mod+Shift+Slash".action = show-hotkey-overlay;
# Some basic spawns
"Mod+Return".action = spawn (lib.getExe config.linux.graphical.defaults.terminal.package);
"Mod+Space".action = spawn "rofi" "-show" "drun";
"Mod+R".action = sh app-menu;
"Mod+Semicolon".action = spawn cfg.lock-command;
"Mod+Shift+P".action = spawn "rofi-rbw-script";
# Audio and Volume
"XF86AudioPrev" = {
action = spawn playerctl "previous";
allow-when-locked = true;
};
"XF86AudioPlay" = {
action = spawn playerctl "play-pause";
allow-when-locked = true;
};
"Shift+XF86AudioPlay" = {
action = spawn playerctl "stop";
allow-when-locked = true;
};
"XF86AudioNext" = {
action = spawn playerctl "next";
allow-when-locked = true;
};
"XF86AudioRecord" = {
action = spawn amixer "-q" "set" "Capture" "toggle";
allow-when-locked = true;
};
"XF86AudioMute" = {
action = spawn amixer "-q" "set" "Master" "toggle";
allow-when-locked = true;
};
"XF86AudioLowerVolume" = {
action = spawn amixer "-q" "set" "Master" "3%-";
allow-when-locked = true;
};
"XF86AudioRaiseVolume" = {
action = spawn amixer "-q" "set" "Master" "3%+";
allow-when-locked = true;
};
# Backlight
"XF86MonBrightnessDown".action = spawn brightnessctl "s" "10%-";
"XF86MonBrightnessUp".action = spawn brightnessctl "s" "10%+";
"Shift+XF86MonBrightnessDown".action = spawn brightnessctl "-d" "kbd_backlight" "s" "25%-";
"Shift+XF86MonBrightnessUp".action = spawn brightnessctl "-d" "kbd_backlight" "s" "25%+";
"Mod+Shift+Q".action = close-window;
"Mod+Left".action = focus-column-or-monitor-left;
"Mod+Right".action = focus-column-or-monitor-right;
"Mod+Up".action = focus-window-or-workspace-up;
"Mod+Down".action = focus-window-or-workspace-down;
"Mod+H".action = focus-column-or-monitor-left;
"Mod+L".action = focus-column-or-monitor-right;
"Mod+K".action = focus-window-or-workspace-up;
"Mod+J".action = focus-window-or-workspace-down;
"Mod+Shift+Left".action = move-column-left-or-to-monitor-left;
"Mod+Shift+Right".action = move-column-right-or-to-monitor-right;
"Mod+Shift+Up".action = move-window-up-or-to-workspace-up;
"Mod+Shift+Down".action = move-window-down-or-to-workspace-down;
"Mod+Shift+H".action = move-column-left-or-to-monitor-left;
"Mod+Shift+L".action = move-column-right-or-to-monitor-right;
"Mod+Shift+K".action = move-window-up-or-to-workspace-up;
"Mod+Shift+J".action = move-window-down-or-to-workspace-down;
"Mod+Bracketleft".action = focus-column-first;
"Mod+Bracketright".action = focus-column-last;
"Mod+Shift+Bracketleft".action = move-column-to-first;
"Mod+Shift+Bracketright".action = move-column-to-last;
# For compat with my current sway
"Mod+Ctrl+H".action = move-workspace-to-monitor-left;
"Mod+Ctrl+L".action = move-workspace-to-monitor-right;
"Mod+I".action = focus-workspace-down;
"Mod+O".action = focus-workspace-up;
"Mod+Shift+I".action = move-column-to-workspace-down;
"Mod+Shift+O".action = move-column-to-workspace-up;
"Mod+Ctrl+I".action = move-workspace-down;
"Mod+Ctrl+O".action = move-workspace-up;
# Mouse bindings
"Mod+WheelScrollDown" = {
action = focus-workspace-down;
cooldown-ms = 150;
};
"Mod+WheelScrollUp" = {
action = focus-workspace-up;
cooldown-ms = 150;
};
"Mod+Ctrl+WheelScrollDown" = {
action = move-column-to-workspace-down;
cooldown-ms = 150;
};
"Mod+Ctrl+WheelScrollUp" = {
action = move-column-to-workspace-up;
cooldown-ms = 150;
};
"Mod+WheelScrollRight".action = focus-column-right;
"Mod+WheelScrollLeft".action = focus-column-left;
"Mod+Ctrl+WheelScrollRight".action = move-column-right;
"Mod+Ctrl+WheelScrollLeft".action = move-column-left;
# You can refer to workspaces by index. However, keep in mind that
# niri is a dynamic workspace system, so these commands are kind of
# "best effort". Trying to refer to a workspace index bigger than
# the current workspace count will instead refer to the bottommost
# (empty) workspace.
#
# For example, with 2 workspaces + 1 empty, indices 3, 4, 5 and so on
# will all refer to the 3rd workspace.
"Mod+1" = lib.mkIf cfg.workspaces."01".fixed {
action = focus-workspace (cfg.workspaces."01".name);
};
"Mod+2" = lib.mkIf cfg.workspaces."02".fixed {
action = focus-workspace (cfg.workspaces."02".name);
};
"Mod+3" = lib.mkIf cfg.workspaces."03".fixed {
action = focus-workspace (cfg.workspaces."03".name);
};
"Mod+4" = lib.mkIf cfg.workspaces."04".fixed {
action = focus-workspace (cfg.workspaces."04".name);
};
"Mod+5" = lib.mkIf cfg.workspaces."05".fixed {
action = focus-workspace (cfg.workspaces."05".name);
};
"Mod+6" = lib.mkIf cfg.workspaces."06".fixed {
action = focus-workspace (cfg.workspaces."06".name);
};
"Mod+7" = lib.mkIf cfg.workspaces."07".fixed {
action = focus-workspace (cfg.workspaces."07".name);
};
"Mod+8" = lib.mkIf cfg.workspaces."08".fixed {
action = focus-workspace (cfg.workspaces."08".name);
};
"Mod+9" = lib.mkIf cfg.workspaces."09".fixed {
action = focus-workspace (cfg.workspaces."09".name);
};
"Mod+0" = lib.mkIf cfg.workspaces."10".fixed {
action = focus-workspace (cfg.workspaces."10".name);
};
"Mod+Shift+1" = lib.mkIf cfg.workspaces."01".fixed {
action = move-column-to-workspace (cfg.workspaces."01".name);
};
"Mod+Shift+2" = lib.mkIf cfg.workspaces."02".fixed {
action = move-column-to-workspace (cfg.workspaces."02".name);
};
"Mod+Shift+3" = lib.mkIf cfg.workspaces."03".fixed {
action = move-column-to-workspace (cfg.workspaces."03".name);
};
"Mod+Shift+4" = lib.mkIf cfg.workspaces."04".fixed {
action = move-column-to-workspace (cfg.workspaces."04".name);
};
"Mod+Shift+5" = lib.mkIf cfg.workspaces."05".fixed {
action = move-column-to-workspace (cfg.workspaces."05".name);
};
"Mod+Shift+6" = lib.mkIf cfg.workspaces."06".fixed {
action = move-column-to-workspace (cfg.workspaces."06".name);
};
"Mod+Shift+7" = lib.mkIf cfg.workspaces."07".fixed {
action = move-column-to-workspace (cfg.workspaces."07".name);
};
"Mod+Shift+8" = lib.mkIf cfg.workspaces."08".fixed {
action = move-column-to-workspace (cfg.workspaces."08".name);
};
"Mod+Shift+9" = lib.mkIf cfg.workspaces."09".fixed {
action = move-column-to-workspace (cfg.workspaces."09".name);
};
"Mod+Shift+0" = lib.mkIf cfg.workspaces."10".fixed {
action = move-column-to-workspace (cfg.workspaces."10".name);
};
"Mod+asciicircum".action = focus-workspace (cfg.workspaces."99".name);
"Mod+Shift+asciicircum".action = move-column-to-workspace (cfg.workspaces."99".name);
"Mod+Tab".action = focus-workspace-previous;
"Mod+Comma".action = consume-or-expel-window-left;
"Mod+Period".action = consume-or-expel-window-right;
"Mod+W".action = switch-preset-column-width;
"Mod+Shift+W".action = switch-preset-window-height;
"Mod+Ctrl+W".action = reset-window-height;
"Mod+F".action = maximize-column;
"Mod+Shift+F".action = fullscreen-window;
"Mod+E".action = center-column;
"Mod+Minus".action = set-column-width "-10%";
"Mod+At".action = set-column-width "+10%";
"Mod+Shift+Minus".action = set-window-height "-10%";
"Mod+Shift+At".action = set-window-height "+10%";
"Mod+V".action = switch-focus-between-floating-and-tiling;
"Mod+Shift+V".action = toggle-window-floating;
"Mod+Shift+Space".action = toggle-window-floating; # Sway compat
"Print".action = screenshot;
"Ctrl+Print".action.screenshot-screen = [ ];
"Shift+Print".action = screenshot-window;
"Mod+Shift+E".action = quit;
};
};
};
}

View file

@ -1,11 +1,4 @@
{
pkgs,
lib,
options,
config,
osConfig,
...
}:
{ pkgs, lib, options, config, ... }:
with lib;
let
cfg = config.programs.my-sway;
@ -29,14 +22,12 @@ let
mail = "📧 Email";
};
wsAttrs = builtins.listToAttrs (
map (i: {
name = toString (remainder i 10);
value = builtins.elemAt workspaces (i - 1);
}) (range 1 11)
map
(i: { name = toString (remainder i 10); value = builtins.elemAt workspaces (i - 1); })
(range 1 11)
);
remainder = x: y: x - (builtins.div x y) * y;
range =
from: to:
range = from: to:
let
f = cur: if cur == to then [ ] else [ cur ] ++ f (cur + 1);
in
@ -53,16 +44,22 @@ let
${pkgs.grim}/bin/grim -g (${pkgs.slurp}/bin/slurp) - | ${pkgs.swappy}/bin/swappy -f -
'';
playerctl = "${pkgs.playerctl}/bin/playerctl";
terminalCmd = lib.getExe config.linux.graphical.defaults.terminal.package;
rofi-rbw-script = pkgs.writeShellApplication {
name = "rofi-rbw-script";
runtimeInputs = with pkgs; [ rofi wtype rofi-rbw ];
text = "rofi-rbw";
};
ignored-devices = [ "Surface_Headphones" ];
playerctl = "${pkgs.playerctl}/bin/playerctl --ignore-player=${strings.concatStringsSep "," ignored-devices}";
in
{
# imports = [ ./ibus.nix ];
options.programs.my-sway = {
enable = mkEnableOption "Enable the sway configuration";
package = mkPackageOption pkgs "swayfx" { };
fontSize = mkOption {
type = types.float;
description = "The default font size";
@ -73,72 +70,69 @@ in
default = true;
};
wallpaper = mkOption {
type = types.oneOf [
types.path
types.str
];
type = types.oneOf [ types.path types.str ];
description = "Path to the wallpaper to be used";
default = config.linux.graphical.wallpaper;
default = "";
};
terminal = mkOption {
type = types.str;
description = "The command to the terminal emulator to be used";
default = "${config.programs.kitty.package}/bin/kitty";
};
browser = mkOption {
type = types.str;
description = "The command for the browser";
default = lib.getExe config.linux.graphical.defaults.webBrowser.package;
};
enableLaptop = lib.mkOption {
type = lib.types.bool;
description = "Whether to enable laptop-specific stuff";
default = true;
default = "${pkgs.firefox-wayland}/bin/firefox";
};
lockCmd = mkOption {
type = types.str;
description = "The screen lock command";
default =
"${pkgs.swaylock}/bin/swaylock"
default = "${pkgs.swaylock}/bin/swaylock"
+ (if cfg.wallpaper == "" then "" else " -i ${cfg.wallpaper} -s fill")
+ " -l -k";
};
};
enableLaptopBars = mkOption {
type = types.bool;
description = "Whether to enable laptop-specific bars (battery)";
default = true;
};
enableMpd = mkOption {
type = types.bool;
description = "Whether to enable mpd on waybar";
default = false;
};
config.systemd.user.targets.sway-session = mkIf cfg.enable {
Unit.Before = [
"tray.target"
"xwayland.target"
"xdg-desktop-portal.service"
"xdg-desktop-autostart.target"
];
Unit.Upholds = [ "waybar.service" ];
Unit.Wants = [ "xdg-desktop-autostart.target" ];
waybar = {
makeBars = mkOption {
type = types.raw;
description = "Create bars with the barWith function, return a list of bars";
default = barWith: [ (barWith { }) ];
};
extraSettings = mkOption {
type = types.raw;
description = "Extra settings to be included with every default bar";
default = { };
};
extraStyle = mkOption {
type = types.str;
description = "Additional style for the default waybar";
default = "";
};
};
};
# Enable waybar
config.programs.my-waybar = mkIf cfg.enable {
enable = true;
fontSize = mkDefault cfg.fontSize;
enableLaptopBars = mkDefault cfg.enableLaptop;
};
config.systemd.user.services.swaync.Install.WantedBy = mkIf cfg.enable [ "sway-session.target" ];
config.wayland.windowManager.sway = mkIf cfg.enable {
enable = true;
package = cfg.package;
systemd.enable = true;
systemd.variables =
options.wayland.windowManager.sway.systemd.variables.default
++ [
"PATH" # for portals
"XDG_DATA_DIRS" # For extra icons
"XDG_DATA_HOME" # For extra icons
]
++ lib.optionals osConfig.services.desktopManager.plasma6.enable [
"XDG_MENU_PREFIX"
];
# systemd.extraCommands = options.wayland.windowManager.sway.systemd.extraCommands.default
# ++ [
# "systemctl --user restart xdg-desktop-portal.service"
# ];
systemd.variables = options.wayland.windowManager.sway.systemd.variables.default ++ [
"PATH" # for portals
"XDG_DATA_DIRS" # For extra icons
"XDG_DATA_HOME" # For extra icons
];
systemd.extraCommands = options.wayland.windowManager.sway.systemd.extraCommands.default ++ [
"systemctl --user restart xdg-desktop-portal.service"
];
checkConfig = false; # Not working atm
config = {
@ -158,20 +152,19 @@ in
### Seats
#
# Cursor
seat."*".xcursor_theme =
"${config.home.pointerCursor.name} ${toString config.home.pointerCursor.size}";
seat."*".xcursor_theme = "${config.home.pointerCursor.name} ${toString config.home.pointerCursor.size}";
### Programs
#
# Terminal
terminal = terminalCmd;
terminal = cfg.terminal;
menu = "${pkgs.dmenu}/bin/dmenu_path | ${pkgs.bemenu}/bin/bemenu | ${pkgs.findutils}/bin/xargs swaymsg exec --";
# Startup
startup = [
# # Dex for autostart
# { command = "${pkgs.dex}/bin/dex -ae sway"; }
# # Waybar
# { command = "systemctl --user restart waybar"; always = true; }
# Dex for autostart
{ command = "${pkgs.dex}/bin/dex -ae sway"; }
# Waybar
{ command = "systemctl --user restart waybar"; always = true; }
# IME
{ command = "fcitx5"; }
];
@ -180,120 +173,110 @@ in
#
# Main modifier
modifier = mod;
keybindings =
{
### Default Bindings
#
## App management
"${mod}+Return" = "exec ${swayCfg.config.terminal}";
"${mod}+Shift+q" = "kill";
"${mod}+d" = "exec ${swayCfg.config.menu}";
## Windowing
# Focus
"${mod}+${swayCfg.config.left}" = "focus left";
"${mod}+${swayCfg.config.down}" = "focus down";
"${mod}+${swayCfg.config.up}" = "focus up";
"${mod}+${swayCfg.config.right}" = "focus right";
"${mod}+Left" = "focus left";
"${mod}+Down" = "focus down";
"${mod}+Up" = "focus up";
"${mod}+Right" = "focus right";
# Move
"${mod}+Shift+${swayCfg.config.left}" = "move left";
"${mod}+Shift+${swayCfg.config.down}" = "move down";
"${mod}+Shift+${swayCfg.config.up}" = "move up";
"${mod}+Shift+${swayCfg.config.right}" = "move right";
"${mod}+Shift+Left" = "move left";
"${mod}+Shift+Down" = "move down";
"${mod}+Shift+Up" = "move up";
"${mod}+Shift+Right" = "move right";
# Toggles
"${mod}+f" = "fullscreen toggle";
"${mod}+a" = "focus parent";
# Layouts
"${mod}+s" = "layout stacking";
"${mod}+w" = "layout tabbed";
"${mod}+e" = "layout toggle split";
# Floating
"${mod}+Shift+space" = "floating toggle";
# Scratchpad
"${mod}+Shift+minus" = "move scratchpad";
# Resize
"${mod}+r" = "mode resize";
"${mod}+minus" = "scratchpad show";
## Reload and exit
"${mod}+Shift+c" = "reload";
"${mod}+Shift+e" =
"exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'";
# Launcher
"${mod}+space" = "exec rofi -show drun";
"${mod}+tab" = "exec ${./rofi-window.py}";
"${mod}+shift+p" = "exec rofi-rbw-script";
}
// {
## Splits
"${mod}+v" = "split v";
"${mod}+Shift+v" = "split h";
## Run
"${mod}+r" = "exec ${config.wayland.windowManager.sway.config.menu}";
"${mod}+Shift+r" = "mode resize";
## Screenshot
"Print" = "exec ${screenshotScript}/bin/screenshot";
"Shift+Print" = "exec ${screenshotEditScript}/bin/screenshot";
## Locking
"${mod}+semicolon" = "exec ${cfg.lockCmd}";
## Multimedia
"XF86AudioPrev" = "exec ${playerctl} previous";
"XF86AudioPlay" = "exec ${playerctl} play-pause";
"Shift+XF86AudioPlay" = "exec ${playerctl} stop";
"XF86AudioNext" = "exec ${playerctl} next";
"XF86AudioRecord" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Capture toggle";
"XF86AudioMute" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Master toggle";
"XF86AudioLowerVolume" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Master 3%-";
"XF86AudioRaiseVolume" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Master 3%+";
## Backlight
"XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl s 10%-";
"XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl s 10%+";
"Shift+XF86MonBrightnessDown" =
"exec ${pkgs.brightnessctl}/bin/brightnessctl -d kbd_backlight s 25%-";
"Shift+XF86MonBrightnessUp" =
"exec ${pkgs.brightnessctl}/bin/brightnessctl -d kbd_backlight s 25%+";
}
//
# Map the workspaces
(builtins.listToAttrs (
lib.flatten (
map (key: [
{
name = "${mod}+${key}";
value = "workspace ${builtins.getAttr key wsAttrs}";
}
{
name = "${mod}+Shift+${key}";
value = "move to workspace ${builtins.getAttr key wsAttrs}";
}
]) (builtins.attrNames wsAttrs)
)
))
// {
# Extra workspaces
"${mod}+asciicircum" = "workspace ${extraWorkspaces.mail}";
"${mod}+shift+asciicircum" = "move to workspace ${extraWorkspaces.mail}";
}
//
# Move workspaces between outputs
keybindings = {
### Default Bindings
#
## App management
"${mod}+Return" = "exec ${swayCfg.config.terminal}";
"${mod}+Shift+q" = "kill";
"${mod}+d" = "exec ${swayCfg.config.menu}";
## Windowing
# Focus
"${mod}+${swayCfg.config.left}" = "focus left";
"${mod}+${swayCfg.config.down}" = "focus down";
"${mod}+${swayCfg.config.up}" = "focus up";
"${mod}+${swayCfg.config.right}" = "focus right";
"${mod}+Left" = "focus left";
"${mod}+Down" = "focus down";
"${mod}+Up" = "focus up";
"${mod}+Right" = "focus right";
# Move
"${mod}+Shift+${swayCfg.config.left}" = "move left";
"${mod}+Shift+${swayCfg.config.down}" = "move down";
"${mod}+Shift+${swayCfg.config.up}" = "move up";
"${mod}+Shift+${swayCfg.config.right}" = "move right";
"${mod}+Shift+Left" = "move left";
"${mod}+Shift+Down" = "move down";
"${mod}+Shift+Up" = "move up";
"${mod}+Shift+Right" = "move right";
# Toggles
"${mod}+f" = "fullscreen toggle";
"${mod}+a" = "focus parent";
# Layouts
"${mod}+s" = "layout stacking";
"${mod}+w" = "layout tabbed";
"${mod}+e" = "layout toggle split";
# Floating
"${mod}+Shift+space" = "floating toggle";
# Scratchpad
"${mod}+Shift+minus" = "move scratchpad";
# Resize
"${mod}+r" = "mode resize";
"${mod}+minus" = "scratchpad show";
## Reload and exit
"${mod}+Shift+c" = "reload";
"${mod}+Shift+e" =
"exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'";
# Launcher
"${mod}+space" = "exec rofi -show drun";
"${mod}+tab" = "exec ${./rofi-window.py}";
"${mod}+shift+p" = "exec ${lib.getExe rofi-rbw-script}";
} // {
## Splits
"${mod}+v" = "split v";
"${mod}+Shift+v" = "split h";
## Run
"${mod}+r" = "exec ${config.wayland.windowManager.sway.config.menu}";
"${mod}+Shift+r" = "mode resize";
## Screenshot
"Print" = "exec ${screenshotScript}/bin/screenshot";
"Shift+Print" = "exec ${screenshotEditScript}/bin/screenshot";
## Locking
"${mod}+semicolon" = "exec ${cfg.lockCmd}";
## Multimedia
"XF86AudioPrev" = "exec ${playerctl} previous";
"XF86AudioPlay" = "exec ${playerctl} play-pause";
"Shift+XF86AudioPlay" = "exec ${playerctl} stop";
"XF86AudioNext" = "exec ${playerctl} next";
"XF86AudioRecord" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Capture toggle";
"XF86AudioMute" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Master toggle";
"XF86AudioLowerVolume" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Master 3%-";
"XF86AudioRaiseVolume" = "exec ${pkgs.alsa-utils}/bin/amixer -q set Master 3%+";
## Backlight
"XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl s 10%-";
"XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl s 10%+";
"Shift+XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl -d kbd_backlight s 25%-";
"Shift+XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl -d kbd_backlight s 25%+";
} //
# Map the workspaces
(builtins.listToAttrs (lib.flatten (map
(key: [
{
"${mod}+ctrl+h" = "move workspace to output left";
"${mod}+ctrl+l" = "move workspace to output right";
};
name = "${mod}+${key}";
value = "workspace ${builtins.getAttr key wsAttrs}";
}
{
name = "${mod}+Shift+${key}";
value = "move to workspace ${builtins.getAttr key wsAttrs}";
}
])
(builtins.attrNames wsAttrs))
)) //
{
# Extra workspaces
"${mod}+asciicircum" = "workspace ${extraWorkspaces.mail}";
"${mod}+shift+asciicircum" = "move to workspace ${extraWorkspaces.mail}";
} //
# Move workspaces between outputs
{
"${mod}+ctrl+h" = "move workspace to output left";
"${mod}+ctrl+l" = "move workspace to output right";
};
### Fonts
#
fonts = {
names = [
"monospace"
"FontAwesome5Free"
];
names = [ "monospace" "FontAwesome5Free" ];
size = cfg.fontSize;
};
@ -311,9 +294,7 @@ in
# Assigning windows to workspaces
assigns = {
"${builtins.elemAt workspaces 0}" = [
{ app_id = "^firefox$"; }
{ app_id = "^librewolf$"; }
{ app_id = "^zen$"; }
{ class = "^firefox$"; }
];
"${builtins.elemAt workspaces 1}" = [
{ class = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; }
@ -321,8 +302,6 @@ in
{ app_id = "VencordDesktop"; }
{ class = "vesktop"; }
{ app_id = "vesktop"; }
{ class = "Slack"; }
];
${extraWorkspaces.mail} = [
{ app_id = "thunderbird"; }
@ -330,31 +309,21 @@ in
];
};
# Commands
window.commands =
[
{
criteria = {
title = ".*";
};
command = "inhibit_idle fullscreen";
}
]
++ (
# Floating assignments
let
criterias = [
{ app_id = ".*float.*"; }
{ app_id = "org\\.freedesktop\\.impl\\.portal\\.desktop\\..*"; }
{ class = ".*float.*"; }
{ title = "Extension: .*Bitwarden.*"; }
];
toCommand = criteria: {
inherit criteria;
command = "floating enable";
};
in
map toCommand criterias
);
window.commands = [
{ criteria = { title = ".*"; }; command = "inhibit_idle fullscreen"; }
] ++ (
# Floating assignments
let
criterias = [
{ app_id = ".*float.*"; }
{ app_id = "org\\.freedesktop\\.impl\\.portal\\.desktop\\..*"; }
{ class = ".*float.*"; }
{ title = "Extension: .*Bitwarden.*"; }
];
toCommand = criteria: { inherit criteria; command = "floating enable"; };
in
map toCommand criterias
);
# Focus
focus.followMouse = true;
focus.mouseWarping = true;
@ -376,50 +345,34 @@ in
# swaynag
swaynag.enable = true;
# Environment Variables
extraSessionCommands =
''
export QT_QPA_PLATFORM=wayland
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
export QT_IM_MODULE=fcitx
export GTK_IM_MODULE=fcitx # Til text-input is merged
# export NIXOS_OZONE_WL=1 # Until text-input is merged
extraSessionCommands = ''
export QT_QPA_PLATFORM=wayland
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
export QT_IM_MODULE=fcitx
export GTK_IM_MODULE=fcitx # Til text-input is merged
# export NIXOS_OZONE_WL=1 # Until text-input is merged
''
+ (
if config.services.gnome-keyring.enable then
''
# gnome-keyring
if type gnome-keyring-daemon >/dev/null; then
eval `gnome-keyring-daemon`
export SSH_AUTH_SOCK
fi
''
else
""
)
+ lib.optionalString osConfig.services.desktopManager.plasma6.enable ''
export XDG_MENU_PREFIX=plasma-
'';
'' + (if config.services.gnome-keyring.enable then ''
# gnome-keyring
if type gnome-keyring-daemon >/dev/null; then
eval `gnome-keyring-daemon`
export SSH_AUTH_SOCK
fi
'' else "");
# Extra
wrapperFeatures.base = true;
wrapperFeatures.gtk = true;
extraConfig =
(
if cfg.enableLaptop then
''
# Lock screen on lid close
bindswitch lid:off exec ${cfg.lockCmd}
(if cfg.enableLaptopBars then ''
# Lock screen on lid close
bindswitch lid:off exec ${cfg.lockCmd}
# Gesture bindings
bindgesture swipe:3:right workspace prev
bindgesture swipe:3:left workspace next
bindgesture swipe:3:up exec ${./rofi-window.py}
''
else
""
)
+ ''
# Gesture bindings
bindgesture swipe:3:right workspace prev
bindgesture swipe:3:left workspace next
bindgesture swipe:3:up exec ${./rofi-window.py}
'' else "") + ''
## swayfx stuff
# Rounded corners
corner_radius 5
@ -434,10 +387,10 @@ in
# Blur
for_window [app_id=".*kitty.*"] blur enable
blur_xray disable
''
+ ''
'' + ''
# Enable portal stuff
exec ${pkgs.writeShellScript "start-portals.sh" ''''}
exec ${pkgs.writeShellScript "start-portals.sh" ''
''}
'';
};
@ -449,28 +402,388 @@ in
# { timeout = 15 * 60; command = cfg.lockCmd; }
];
events = [
{
event = "lock";
command = cfg.lockCmd;
}
{
event = "before-sleep";
command = cfg.lockCmd;
}
{ event = "lock"; command = cfg.lockCmd; }
{ event = "before-sleep"; command = cfg.lockCmd; }
];
};
config.home.packages = mkIf cfg.enable (
with pkgs;
[
# Needed for QT_QPA_PLATFORM
kdePackages.qtwayland
# For waybar
font-awesome
]
);
config.programs.waybar =
let
barWith = { showMedia ? true, showConnectivity ? true, extraSettings ? { }, ... }: (mkMerge [{
position = "top";
modules-left = [
"sway/workspaces"
"sway/mode"
"sway/window"
];
modules-center = [
];
modules-right =
lib.optional showMedia (if cfg.enableMpd then "mpd" else "custom/media")
++ [
"tray"
"pulseaudio"
] ++ lib.optionals showConnectivity [
"bluetooth"
"network"
] ++ [
"cpu"
"memory"
"temperature"
] ++ lib.optionals cfg.enableLaptopBars [ "battery" "battery#bat2" ]
++ [
"clock"
];
modules = {
"sway/workspaces" = {
format = "{name}";
};
"sway/mode" = {
format = "<span style=\"italic\">{}</span>";
};
"sway/window" = {
max-length = 70;
format = "{title}";
"rewrite" = {
"(.*) Mozilla Firefox" = "[🌎] $1";
"(.*) - Mozilla Thunderbird" = "[📧] $1";
"(.*) - Kakoune" = "[] $1";
"(.*) - fish" = "[>_] $1";
"(.*) - Discord" = "[🗨] $1";
# ArmCord thing
" Discord \\| (.*)" = "[🗨] $1";
"\\((\\d+)\\) Discord \\| (.*)" = "[🗨] {$1} $2";
};
};
"tray" = {
icon-size = 21;
spacing = 10;
};
"clock" = {
# format = "{:📅 %Y-%m-%d | 🕰️ %H:%M [%Z]}";
format = "📅 {0:%Y-%m-%d} | 🕰 {0:%H:%M [%Z]}";
tooltip-format = "\n<span size='9pt' font_family='Noto Sans Mono CJK JP'>{calendar}</span>";
timezones = [
"Europe/Zurich"
"America/Toronto"
"Asia/Tokyo"
"Asia/Ho_Chi_Minh"
];
calendar = {
mode = "year";
mode-mon-col = 3;
weeks-pos = "right";
on-scroll = 1;
on-click-right = "mode";
format = {
months = "<span color='#ffead3'><b>{}</b></span>";
days = "<span color='#ecc6d9'><b>{}</b></span>";
weeks = "<span color='#99ffdd'><b>W{}</b></span>";
weekdays = "<span color='#ffcc66'><b> </b></span>"; # See https://github.com/Alexays/Waybar/issues/3132
today = "<span color='#ff6699'><b><u>{}</u></b></span>";
};
};
actions = {
on-click-middle = "mode";
on-click-right = "tz_up";
on-scroll-up = "shift_up";
on-scroll-down = "shift_down";
};
};
"cpu" = {
format = "{usage}% ";
};
"memory" = {
format = "{}% ";
};
"temperature" = {
# thermal-zone = 2;
# hwmon-path" = "/sys/class/hwmon/hwmon2/temp1_input";
critical-threshold = 80;
# format-critical = "{temperatureC}°C ";
format = "{temperatureC}°C ";
};
"backlight" = {
# device = "acpi_video1";
format = "{percent}% {icon}";
states = [ 0 50 ];
format-icons = [ "" "" ];
};
"battery" = mkIf cfg.enableLaptopBars {
states = {
good = 95;
warning = 30;
critical = 15;
};
format = "{capacity}% {icon}";
# format-good = ""; # An empty format will hide the module
# format-full = "";
format-icons = [ "" "" "" "" "" ];
};
"battery#bat2" = mkIf cfg.enableLaptopBars {
bat = "BAT2";
};
"network" = {
# interface = wlp2s0 # (Optional) To force the use of this interface
format-wifi = "{essid} ({signalStrength}%) ";
format-ethernet = "{ifname}: {ipaddr}/{cidr} ";
format-disconnected = "Disconnected ";
interval = 7;
};
"bluetooth" = {
format = " {status}";
format-connected = " {device_alias}";
format-connected-battery = " {device_alias} {device_battery_percentage}%";
# format-device-preference= [ "device1", "device2" ], // preference list deciding the displayed devic;
tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected";
tooltip-format-connected = "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}";
tooltip-format-enumerate-connected = "{device_alias}\t{device_address}";
tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_address}\t{device_battery_percentage}%";
on-click = "${pkgs.blueman}/bin/blueman-manager";
};
"pulseaudio" = {
# scroll-step = 1;
format = "{volume}% {icon}";
format-bluetooth = "{volume}% {icon}";
format-muted = "";
format-icons = {
headphones = "";
handsfree = "";
headset = "";
phone = "";
portable = "";
car = "";
default = [ "" "" ];
};
on-click = "${pkgs.pavucontrol}/bin/pavucontrol";
};
"mpd" = {
"format" = "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) 🎧";
"format-disconnected" = "Disconnected 🎧";
"format-stopped" = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped 🎧";
"interval" = 2;
"consume-icons" = {
"on" = " "; # Icon shows only when "consume" is on
};
"random-icons" = {
"off" = "<span color=\"#f53c3c\"></span> "; # Icon grayed out when "random" is off;
"on" = " ";
};
"repeat-icons" = {
"on" = " ";
};
"single-icons" = {
"on" = "1 ";
};
"state-icons" = {
"paused" = "";
"playing" = "";
};
"tooltip-format" = "MPD (connected)";
"tooltip-format-disconnected" = "MPD (disconnected)";
"on-click" = "${pkgs.mpc_cli}/bin/mpc toggle";
"on-click-right" = "${pkgs.mpc_cli}/bin/mpc stop";
"on-click-middle" = "${cfg.terminal} --class=kitty_ncmpcpp ${pkgs.ncmpcpp}/bin/ncmpcpp";
};
"custom/media" = {
"format" = "{icon}{}";
"return-type" = "json";
"format-icons" = {
"Playing" = " ";
"Paused" = " ";
};
"max-length" = 80;
"exec" = "${playerctl} -a metadata --format '{\"text\": \"{{artist}} - {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F";
"on-click" = "${playerctl} play-pause";
};
};
}
cfg.waybar.extraSettings
extraSettings]);
in
mkIf cfg.enable {
enable = true;
systemd.enable = true;
systemd.target = "sway-session.target";
settings = cfg.waybar.makeBars barWith;
style = ''
* {
border: none;
border-radius: 0;
font-family: monospace, 'Font Awesome 5', 'Symbols Nerd Font Mono', 'SFNS Display', Helvetica, Arial, sans-serif;
font-size: ${toString (cfg.fontSize * 1.1)}px;
min-height: 0;
}
window#waybar {
background: rgba(43, 48, 59, 0.8);
border-bottom: 3px solid rgba(100, 114, 125, 0.5);
color: #ffffff;
}
window#waybar.hidden {
opacity: 0.0;
}
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
#workspaces button {
padding: 0 5px;
background: transparent;
color: #ffffff;
border-bottom: 3px solid transparent;
}
#workspaces button.focused {
background: #64727D;
border-bottom: 3px solid #ffffff;
}
#workspaces button.urgent {
background-color: #eb4d4b;
}
#window, #sway, #sway-window {
padding-left: 1em;
margin-bottom: 0.4em;
}
#mode {
background: #64727D;
border-bottom: 3px solid #ffffff;
}
/* #clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #bluetooth, #custom-media, #tray, #mode, #idle_inhibitor, #mpd { */
.modules-right > * > * {
margin: 0.2em 0 0.4em 0;
padding: 0.2em 0.5em;
border: 1px solid rgba(0, 0, 0, 0.25);
border-radius: 0.3em;
}
.modules-right > *:not(:last-child) > * {
margin-right: 0.4em;
}
#clock {
background-color: #64727D;
}
#battery {
background-color: #ffffff;
color: #000000;
}
#battery.charging {
color: #ffffff;
background-color: #26A65B;
}
@keyframes blink {
to {
background-color: #ffffff;
color: #000000;
}
}
#battery.critical:not(.charging) {
background: #f53c3c;
color: #ffffff;
animation-name: blink;
animation-duration: 0.5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#cpu {
background: #2ecc71;
color: #000000;
}
#memory {
background: #9b59b6;
}
#backlight {
background: #90b1b1;
}
#network {
background: #2980b9;
}
#network.disconnected {
background: #f53c3c;
}
#pulseaudio {
background: #f1c40f;
color: #000000;
}
#pulseaudio.muted {
background: #90b1b1;
}
#bluetooth {
background: DarkSlateBlue;
color: white;
}
#custom-media {
background: #66cc99;
color: #2a5c45;
}
.custom-spotify {
background: #66cc99;
}
.custom-vlc {
background: #ffa000;
}
#temperature {
background: #f0932b;
}
#temperature.critical {
background: #eb4d4b;
}
#tray {
background-color: #2980b9;
}
#idle_inhibitor {
background-color: #2d3436;
}
#idle_inhibitor.activated {
background-color: #ecf0f1;
color: #2d3436;
}
#mpd {
background-color: teal;
color: white;
}
'' + cfg.waybar.extraStyle;
};
config.home.packages = mkIf cfg.enable (with pkgs; [
# Needed for QT_QPA_PLATFORM
kdePackages.qtwayland
# For waybar
font-awesome
]);
config.programs.rofi = mkIf cfg.enable {
font = lib.mkForce "monospace ${toString cfg.fontSize}";
enable = true;
package = pkgs.rofi-wayland;
cycle = true;
font = "monospace ${toString cfg.fontSize}";
terminal = cfg.terminal;
theme = "Paper";
plugins = with pkgs; [ rofi-bluetooth rofi-calc rofi-rbw rofi-power-menu ];
};
}

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
cfg = config.programs.my-sway;
@ -11,22 +6,15 @@ let
# Set up an ibus script
ibusNext = (
let
input-methods = [
"xkb:us::eng"
"mozc-jp"
"Bamboo"
];
next =
m:
input-methods = [ "xkb:us::eng" "mozc-jp" "Bamboo" ];
next = m:
let
nextRec =
l:
if (length l == 1) then
head input-methods
else if (m == head l) then
(head (tail l))
else
nextRec (tail l);
nextRec = l:
if (length l == 1)
then head input-methods
else if (m == head l)
then (head (tail l))
else nextRec (tail l);
in
nextRec input-methods;
changeTo = m: ''
@ -64,3 +52,4 @@ in
};
};
}

View file

@ -1,469 +0,0 @@
{
lib,
config,
pkgs,
...
}:
let
cfg = config.programs.my-waybar;
in
{
options.programs.my-waybar = {
enable = lib.mkEnableOption "custom configuration for waybar";
fontSize = lib.mkOption {
type = lib.types.float;
description = "The default font size";
};
terminal = lib.mkOption {
type = lib.types.str;
description = "The command to the terminal emulator to be used";
default = "${lib.getExe config.linux.graphical.defaults.terminal.package}";
};
enableLaptopBars = lib.mkOption {
type = lib.types.bool;
description = "Whether to enable laptop-specific bars (battery)";
default = true;
};
enableMpd = lib.mkOption {
type = lib.types.bool;
description = "Whether to enable mpd on waybar";
default = false;
};
makeBars = lib.mkOption {
type = lib.types.raw;
description = "Create bars with the barWith function, return a list of bars";
default = barWith: [ (barWith { }) ];
};
extraSettings = lib.mkOption {
type = lib.types.listOf lib.types.raw;
description = "Extra settings to be included with every default bar";
default = [ ];
};
extraStyle = lib.mkOption {
type = lib.types.lines;
description = "Additional style for the default waybar";
default = "";
};
};
config.systemd.user.services.waybar = lib.mkIf cfg.enable {
Unit.Before = [ "tray.target" ];
};
config.programs.waybar =
let
barWith =
{
showMedia ? true,
showConnectivity ? true,
extraSettings ? { },
...
}:
lib.mkMerge (
[
{
layer = "top";
position = "top";
modules-left = [
"sway/workspaces"
"sway/mode"
"sway/window"
"niri/workspaces"
"niri/window"
];
modules-center = [
];
modules-right =
lib.optional showMedia (if cfg.enableMpd then "mpd" else "custom/media")
++ [
"tray"
"pulseaudio"
]
++ lib.optionals showConnectivity [
"bluetooth"
"network"
]
++ [
"cpu"
"memory"
"temperature"
]
++ lib.optionals cfg.enableLaptopBars [
"battery"
"battery#bat2"
]
++ [
"clock"
];
modules = {
"sway/workspaces" = {
format = "{name}";
};
"sway/mode" = {
format = "<span style=\"italic\">{}</span>";
};
"sway/window" = {
max-length = 70;
format = "{title}";
"rewrite" = {
"(.*) Mozilla Firefox" = "[🌎] $1";
"(.*) - Mozilla Thunderbird" = "[📧] $1";
"(.*) - Kakoune" = "[] $1";
"(.*) - fish" = "[>_] $1";
"(.*) - Discord" = "[🗨] $1";
# ArmCord thing
" Discord \\| (.*)" = "[🗨] $1";
"\\((\\d+)\\) Discord \\| (.*)" = "[🗨] {$1} $2";
};
};
"niri/window" = {
format = "{title}";
"rewrite" = {
"(.*) Mozilla Firefox" = "[🌎] $1";
"(.*) - Mozilla Thunderbird" = "[📧] $1";
"(.*) - Kakoune" = "[] $1";
"(.*) - fish" = "[>_] $1";
"(.*) - Discord" = "[🗨] $1";
# ArmCord thing
" Discord \\| (.*)" = "[🗨] $1";
"\\((\\d+)\\) Discord \\| (.*)" = "[🗨] {$1} $2";
};
};
"tray" = {
icon-size = 21;
spacing = 10;
};
"clock" = {
# format = "{:📅 %Y-%m-%d | 🕰️ %H:%M [%Z]}";
format = "📅 {0:%Y-%m-%d} | 🕰 {0:%H:%M [%Z]}";
tooltip-format = "\n<span size='9pt' font_family='Noto Sans Mono CJK JP'>{calendar}</span>";
timezones = [
"Europe/Zurich"
"America/Toronto"
"Asia/Tokyo"
"Asia/Ho_Chi_Minh"
];
calendar = {
mode = "year";
mode-mon-col = 3;
weeks-pos = "right";
on-scroll = 1;
on-click-right = "mode";
format = {
months = "<span color='#ffead3'><b>{}</b></span>";
days = "<span color='#ecc6d9'><b>{}</b></span>";
weeks = "<span color='#99ffdd'><b>W{}</b></span>";
weekdays = "<span color='#ffcc66'><b> </b></span>"; # See https://github.com/Alexays/Waybar/issues/3132
today = "<span color='#ff6699'><b><u>{}</u></b></span>";
};
};
actions = {
on-click-middle = "mode";
on-click-right = "tz_up";
on-scroll-up = "shift_up";
on-scroll-down = "shift_down";
};
};
"cpu" = {
format = "{usage}% ";
};
"memory" = {
format = "{}% ";
};
"temperature" = {
# thermal-zone = 2;
# hwmon-path" = "/sys/class/hwmon/hwmon2/temp1_input";
critical-threshold = 80;
# format-critical = "{temperatureC}°C ";
format = "{temperatureC}°C ";
};
"backlight" = {
# device = "acpi_video1";
format = "{percent}% {icon}";
states = [
0
50
];
format-icons = [
""
""
];
};
"battery" = lib.mkIf cfg.enableLaptopBars {
states = {
good = 95;
warning = 30;
critical = 15;
};
format = "{capacity}% {icon}";
# format-good = ""; # An empty format will hide the module
# format-full = "";
format-icons = [
""
""
""
""
""
];
};
"battery#bat2" = lib.mkIf cfg.enableLaptopBars {
bat = "BAT2";
};
"network" = {
# interface = wlp2s0 # (Optional) To force the use of this interface
format-wifi = "{essid} ({signalStrength}%) ";
format-ethernet = "{ifname} ";
format-disconnected = "Disconnected ";
interval = 7;
on-click = "${cfg.terminal} ${lib.getExe' pkgs.iwd "iwctl"}";
};
"bluetooth" = {
format = " {status}";
format-connected = " {device_alias}";
format-connected-battery = " {device_alias} {device_battery_percentage}%";
# format-device-preference= [ "device1", "device2" ], // preference list deciding the displayed devic;
tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected";
tooltip-format-connected = "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}";
tooltip-format-enumerate-connected = "{device_alias}\t{device_address}";
tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_address}\t{device_battery_percentage}%";
on-click = "${pkgs.blueman}/bin/blueman-manager";
};
"pulseaudio" = {
# scroll-step = 1;
format = "{volume}% {icon}";
format-bluetooth = "{volume}% {icon}";
format-muted = "";
format-icons = {
headphones = "";
handsfree = "";
headset = "";
phone = "";
portable = "";
car = "";
default = [
""
""
];
};
on-click = "${pkgs.pavucontrol}/bin/pavucontrol";
};
"mpd" = {
"format" =
"{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) 🎧";
"format-disconnected" = "Disconnected 🎧";
"format-stopped" = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped 🎧";
"interval" = 2;
"consume-icons" = {
"on" = " "; # Icon shows only when "consume" is on
};
"random-icons" = {
"off" = "<span color=\"#f53c3c\"></span> "; # Icon grayed out when "random" is off;
"on" = " ";
};
"repeat-icons" = {
"on" = " ";
};
"single-icons" = {
"on" = "1 ";
};
"state-icons" = {
"paused" = "";
"playing" = "";
};
"tooltip-format" = "MPD (connected)";
"tooltip-format-disconnected" = "MPD (disconnected)";
"on-click" = "${pkgs.mpc_cli}/bin/mpc toggle";
"on-click-right" = "${pkgs.mpc_cli}/bin/mpc stop";
"on-click-middle" = "${cfg.terminal} --class=kitty_ncmpcpp ${pkgs.ncmpcpp}/bin/ncmpcpp";
};
"custom/media" = {
"format" = "{icon}{}";
"return-type" = "json";
"format-icons" = {
"Playing" = " ";
"Paused" = " ";
};
"max-length" = 80;
"exec" =
"${lib.getExe pkgs.playerctl} -a metadata --format '{\"text\": \"{{artist}} - {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F";
"on-click" = "${lib.getExe pkgs.playerctl} play-pause";
};
};
}
]
++ cfg.extraSettings
++ [ extraSettings ]
);
in
lib.mkIf cfg.enable {
enable = true;
systemd.enable = true;
systemd.target = "sway-session.target";
settings = cfg.makeBars barWith;
style =
''
* {
border: none;
border-radius: 0;
font-family: monospace, 'Font Awesome 5', 'Symbols Nerd Font Mono', 'SFNS Display', Helvetica, Arial, sans-serif;
font-size: ${toString (cfg.fontSize * 1.1)}px;
min-height: 0;
}
window#waybar {
background: rgba(43, 48, 59, 0.8);
border-bottom: 3px solid rgba(100, 114, 125, 0.5);
color: #ffffff;
}
window#waybar.hidden {
opacity: 0.0;
}
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
#workspaces button {
padding: 0 5px;
background: transparent;
color: #ffffff;
border-bottom: 3px solid transparent;
}
#workspaces button.focused {
background: #64727D;
border-bottom: 3px solid #ffffff;
}
#workspaces button.urgent {
background-color: #eb4d4b;
}
#window, #sway, #sway-window {
padding-left: 1em;
margin-bottom: 0.4em;
}
#mode {
background: #64727D;
border-bottom: 3px solid #ffffff;
}
/* #clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #bluetooth, #custom-media, #tray, #mode, #idle_inhibitor, #mpd { */
.modules-right > * > * {
margin: 0.2em 0 0.4em 0;
padding: 0.2em 0.5em;
border: 1px solid rgba(0, 0, 0, 0.25);
border-radius: 0.3em;
}
.modules-right > *:not(:last-child) > * {
margin-right: 0.4em;
}
#clock {
background-color: #64727D;
}
#battery {
background-color: #ffffff;
color: #000000;
}
#battery.charging {
color: #ffffff;
background-color: #26A65B;
}
@keyframes blink {
to {
background-color: #ffffff;
color: #000000;
}
}
#battery.critical:not(.charging) {
background: #f53c3c;
color: #ffffff;
animation-name: blink;
animation-duration: 0.5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#cpu {
background: #2ecc71;
color: #000000;
}
#memory {
background: #9b59b6;
}
#backlight {
background: #90b1b1;
}
#network {
background: #2980b9;
}
#network.disconnected {
background: #f53c3c;
}
#pulseaudio {
background: #f1c40f;
color: #000000;
}
#pulseaudio.muted {
background: #90b1b1;
}
#bluetooth {
background: DarkSlateBlue;
color: white;
}
#custom-media {
background: #66cc99;
color: #2a5c45;
}
.custom-spotify {
background: #66cc99;
}
.custom-vlc {
background: #ffa000;
}
#temperature {
background: #f0932b;
}
#temperature.critical {
background: #eb4d4b;
}
#tray {
background-color: #2980b9;
}
#idle_inhibitor {
background-color: #2d3436;
}
#idle_inhibitor.activated {
background-color: #ecf0f1;
color: #2d3436;
}
#mpd {
background-color: teal;
color: white;
}
''
+ cfg.extraStyle;
};
}

View file

@ -1,26 +1,16 @@
{
pkgs,
lib,
config,
...
}:
{ pkgs, lib, config, ... }:
let
openconnect-epfl = pkgs.writeShellApplication {
name = "openconnect-epfl";
runtimeInputs = with pkgs; [
openconnect
rbw
];
runtimeInputs = with pkgs; [ openconnect rbw ];
text = ''
METHOD="Microsoft Entra ID"
RBW_ENTRY="EPFL Microsoft Auth"
GASPAR_PASSWORD=$(rbw get "$RBW_ENTRY")
GASPAR_TOKEN=$(rbw code "$RBW_ENTRY")
GASPAR_PASSWORD=$(rbw get gaspar)
GASPAR_TOKEN=$(rbw code gaspar)
printf "\n%s\n%s\n%s\n" "$METHOD" "$GASPAR_PASSWORD" "$GASPAR_TOKEN" | command sudo openconnect \
printf "%s\n%s\n" "$GASPAR_PASSWORD" "$GASPAR_TOKEN" | sudo openconnect \
--passwd-on-stdin \
-u "pham" \
--useragent='AnyConnect' \
-u pham \
--useragent='AnyConnect' \
"https://vpn.epfl.ch"
'';
};
@ -28,3 +18,4 @@ in
{
home.packages = [ openconnect-epfl ];
}

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
{
imports = [
@ -12,7 +7,7 @@
# We use our own firefox
# ./firefox.nix
# osu!
./osu
./osu.nix
];
# Home Manager needs a bit of information about you and the
@ -20,14 +15,26 @@
home.username = "nki";
home.homeDirectory = "/home/nki";
# More packages
home.packages = (with pkgs; [
# CLI stuff
python3
zip
# TeX
texlive.combined.scheme-full
# Note-taking
rnote
]);
# Graphical set up
linux.graphical.type = "wayland";
linux.graphical.wallpaper = ./images/wallpaper_0.png;
linux.graphical.defaults.webBrowser.package = pkgs.zen-browser-bin;
linux.graphical.defaults.webBrowser.desktopFile = "zen.desktop";
linux.graphical.defaults.webBrowser = "librewolf.desktop";
# Enable sway
programs.my-sway.enable = true;
programs.my-sway.fontSize = 14.0;
programs.my-sway.terminal = "${config.programs.kitty.package}/bin/kitty";
programs.my-sway.browser = "librewolf";
wayland.windowManager.sway.config = {
# Keyboard support
input."*".xkb_layout = "jp";
@ -41,31 +48,6 @@
tap = "enabled";
};
};
programs.my-niri.enable = true;
programs.my-niri.enableLaptop = true;
programs.my-niri.workspaces = lib.genAttrs [ "04" "05" "06" "07" "08" "09" ] (_: {
fixed = false;
});
programs.niri.settings = {
input.keyboard.xkb.options = "ctrl:swapcaps";
};
programs.my-waybar.extraSettings =
let
change-mode = pkgs.writeScript "change-mode" ''
#!/usr/bin/env ${lib.getExe pkgs.fish}
set -ax PATH ${lib.getBin pkgs.power-profiles-daemon} ${lib.getBin config.programs.rofi.package} ${lib.getBin pkgs.ripgrep}
set profiles (powerprofilesctl list | rg "^[ *] (\S+):" -r '$1')
set selected_index (math (contains -i (powerprofilesctl get) $profiles) - 1)
set new_profile (printf "%s\n" $profiles | rofi -dmenu -p "Switch to power profile" -a $selected_index)
powerprofilesctl set $new_profile
'';
in
[
{
modules."battery"."on-click" = change-mode;
}
];
# input-remapping
xdg.configFile."autostart/input-remapper-autoload.desktop".source =
@ -79,35 +61,16 @@
# Multiple screen setup
services.kanshi = with config.common.monitors; {
enable = true;
settings = [
{
profile.name = "undocked";
profile.outputs = [ { criteria = "eDP-1"; } ];
}
{
profile.name = "work-both";
profile.outputs = [
{
criteria = "eDP-1";
position = "0,${toString (builtins.floor ((2160 / work.scale - 1200) + 1200 / 3))}";
status = "enable";
}
{
criteria = work.name;
position = "1920,0";
}
];
}
{
profile.name = "work-one";
profile.outputs = [
{
criteria = "eDP-1";
status = "disable";
}
];
}
{ output.criteria = config.common.monitors.work.name; }
profiles.undocked.outputs = [{
criteria = "eDP-1";
}];
profiles.work-both.outputs = [
{ criteria = "eDP-1"; position = "0,${toString (builtins.floor ((2160 / work.scale - 1200) + 1200 / 3))}"; status = "enable"; }
{ criteria = work.name; position = "1920,0"; }
];
profiles.work-one.outputs = [
{ criteria = "eDP-1"; status = "disable"; }
{ criteria = config.common.monitors.work.name; }
];
};
@ -121,3 +84,4 @@
# changes in each release.
home.stateVersion = "21.05";
}

View file

@ -1,30 +1,5 @@
{
pkgs,
options,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
let
iio-sway = pkgs.stdenv.mkDerivation {
name = "iio-sway";
version = "0.0.1";
src = pkgs.fetchFromGitHub {
owner = "okeri";
repo = "iio-sway";
rev = "e07477d1b2478fede1446e97424a94c80767819d";
hash = "sha256-JGacKajslCOvd/BFfFSf7s1/hgF6rJqJ6H6xNnsuMb4=";
};
buildInputs = with pkgs; [ dbus ];
nativeBuildInputs = with pkgs; [
meson
ninja
pkg-config
];
meta.mainProgram = "iio-sway";
};
in
{
imports = [
# Common configuration
@ -32,7 +7,7 @@ in
# We use our own firefox
# ./firefox.nix
# osu!
./osu
./osu.nix
];
# Home Manager needs a bit of information about you and the
@ -41,23 +16,25 @@ in
home.homeDirectory = "/home/nki";
# More packages
home.packages = (
with pkgs;
[
# Note-taking
rnote
]
);
home.packages = (with pkgs; [
# CLI stuff
python3
zip
# TeX
texlive.combined.scheme-full
# Note-taking
rnote
]);
# Graphical set up
linux.graphical.type = "wayland";
linux.graphical.wallpaper = ./images/wallpaper_0.png;
linux.graphical.startup = options.linux.graphical.startup.default ++ [ pkgs.slack ];
linux.graphical.defaults.webBrowser.package = pkgs.zen-browser-bin;
linux.graphical.defaults.webBrowser.desktopFile = "zen.desktop";
linux.graphical.defaults.webBrowser = "librewolf.desktop";
# Enable sway
programs.my-sway.enable = true;
programs.my-sway.fontSize = 14.0;
programs.my-sway.terminal = "${config.programs.kitty.package}/bin/kitty";
programs.my-sway.browser = "librewolf";
wayland.windowManager.sway.config = {
# Keyboard support
input."*".xkb_layout = "jp";
@ -72,28 +49,25 @@ in
startup = [
# rotation
{ command = "${lib.getExe iio-sway}"; }
(
let
iio-sway = pkgs.stdenv.mkDerivation {
name = "iio-sway";
version = "0.0.1";
src = pkgs.fetchFromGitHub {
owner = "okeri";
repo = "iio-sway";
rev = "e07477d1b2478fede1446e97424a94c80767819d";
hash = "sha256-JGacKajslCOvd/BFfFSf7s1/hgF6rJqJ6H6xNnsuMb4=";
};
buildInputs = with pkgs; [ dbus ];
nativeBuildInputs = with pkgs; [ meson ninja pkg-config ];
};
in
{ command = "${iio-sway}/bin/iio-sway"; }
)
];
};
programs.my-niri.enable = true;
programs.my-niri.enableLaptop = true;
# Assign some of the workspaces to big screen
programs.my-niri.workspaces = lib.genAttrs [ "06" "07" "08" "09" "10" ] (_: {
monitor = config.common.monitors.work.name;
});
programs.niri.settings = {
# input.keyboard.xkb.options = "ctrl:swapcaps";
input.mouse = lib.mkForce {
# Make M575 fast for now
accel-profile = "adaptive";
accel-speed = 0.4;
};
input.touch.map-to-output = "eDP-1";
switch-events = with config.lib.niri.actions; {
tablet-mode-on.action = spawn "systemctl" "--user" "kill" "--signal" "SIGUSR2" "wvkbd";
tablet-mode-off.action = spawn "systemctl" "--user" "kill" "--signal" "SIGUSR1" "wvkbd";
};
};
## Virtual keyboard
systemd.user.services.wvkbd = {
Unit = {
@ -122,35 +96,14 @@ in
# Multiple screen setup
services.kanshi = with config.common.monitors; {
enable = true;
settings = [
{
profile.name = "undocked";
profile.outputs = [ { criteria = "eDP-1"; } ];
}
{
profile.name = "work-both";
profile.outputs = [
{
criteria = "eDP-1";
position = "0,${toString (builtins.floor ((2160 / work.scale - 1200) + 1200 / 3))}";
status = "enable";
}
{
criteria = work.name;
position = "1920,0";
}
];
}
{
profile.name = "work-one";
profile.outputs = [
{
criteria = "eDP-1";
status = "disable";
}
{ criteria = work.name; }
];
}
profiles.undocked.outputs = [{ criteria = "LVDS-1"; }];
profiles.work-both.outputs = [
{ criteria = "eDP-1"; position = "0,${toString (builtins.floor ((2160 / work.scale - 1200) + 1200 / 3))}"; status = "enable"; }
{ criteria = work.name; position = "1920,0"; }
];
profiles.work-one.outputs = [
{ criteria = "eDP-1"; status = "disable"; }
{ criteria = config.common.monitors.work.name; }
];
};
@ -164,3 +117,4 @@ in
# changes in each release.
home.stateVersion = "21.05";
}

33
home/osu.nix Normal file
View file

@ -0,0 +1,33 @@
{ pkgs, lib, ... }:
let
osu-pkg = pkgs.unstable.osu-lazer-bin;
# osu-pkg = with pkgs; with lib;
# appimageTools.wrapType2 rec {
# pname = "osu-lazer-bin";
# version = "2024.312.1";
# src = pkgs.fetchurl {
# url = "https://github.com/ppy/osu/releases/download/${version}/osu.AppImage";
# hash = "sha256-1dzgs1p3/pf4eCdKvQ9JxowN+oBPBNaZv5e6qHeFPEM=";
# };
# extraPkgs = pkgs: with pkgs; [ icu ];
# extraInstallCommands =
# let contents = appimageTools.extract { inherit pname version src; };
# in
# ''
# mv -v $out/bin/${pname}-${version} $out/bin/osu\!
# install -m 444 -D ${contents}/osu\!.desktop -t $out/share/applications
# for i in 16 32 48 64 96 128 256 512 1024; do
# install -D ${contents}/osu\!.png $out/share/icons/hicolor/''${i}x$i/apps/osu\!.png
# done
# '';
# };
in
{
home.packages = [ osu-pkg ];
xdg.mimeApps.defaultApplications."x-scheme-handler/osu" = "osu!.desktop";
# home.packages = [ pkgs.osu-lazer ];
}

View file

@ -1,35 +0,0 @@
{ pkgs, lib, ... }:
let
# osu-pkg = pkgs.unstable.osu-lazer-bin;
osu-pkg =
with pkgs;
with lib;
appimageTools.wrapType2 rec {
pname = "osu-lazer-bin";
version = "2025.321.0";
src = fetchurl {
url = "https://github.com/ppy/osu/releases/download/${version}/osu.AppImage";
hash = "sha256-mNxoEx/wgJ1OUm7y9JLd5vHSwfcB49QjKDVQWZaMDJQ=";
};
extraPkgs = pkgs: with pkgs; [ icu ];
extraInstallCommands =
let
contents = appimageTools.extract { inherit pname version src; };
in
''
mv -v $out/bin/${pname} $out/bin/osu\!
install -m 444 -D ${contents}/osu\!.desktop -t $out/share/applications
install -m 444 -D ${./mimetypes.xml} $out/share/mime/packages/${pname}.xml
for i in 16 32 48 64 96 128 256 512 1024; do
install -D ${contents}/osu.png $out/share/icons/hicolor/''${i}x$i/apps/osu.png
done
'';
};
in
{
home.packages = [ osu-pkg ];
xdg.mimeApps.defaultApplications."x-scheme-handler/osu" = "osu!.desktop";
# home.packages = [ pkgs.osu-lazer ];
}

View file

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
<mime-type type="application/x-osu-beatmap-archive">
<icon name="osu"/>
<comment xml:lang="en">osu! Beatmap Archive</comment>
<glob pattern="*.osz"/>
<glob pattern="*.olz"/>
</mime-type>
<mime-type type="application/x-osu-skin-archive">
<icon name="osu"/>
<comment xml:lang="en">osu! Skin Archive</comment>
<glob pattern="*.osk"/>
</mime-type>
<mime-type type="application/x-osu-beatmap">
<icon name="osu"/>
<comment xml:lang="en">osu! Beatmap</comment>
<glob pattern="*.osu"/>
</mime-type>
<mime-type type="application/x-osu-storyboard">
<icon name="osu"/>
<comment xml:lang="en">osu! Storyboard</comment>
<glob pattern="*.osb"/>
</mime-type>
<mime-type type="application/x-osu-replay">
<icon name="osu"/>
<comment xml:lang="en">osu! Replay</comment>
<glob pattern="*.osr"/>
</mime-type>
</mime-info>

View file

@ -1,162 +0,0 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{
config,
pkgs,
lib,
...
}:
{
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
# Fonts
../modules/personal/fonts
# Encrypted DNS
../modules/services/edns
# Override base mesa
(
{ ... }:
{
nixpkgs.overlays = lib.mkBefore [
(final: prev: {
mesa = prev.mesa.override {
enableOpenCL = true;
meson = final.unstable.meson;
};
})
];
}
)
];
# time.timeZone = lib.mkForce "Asia/Ho_Chi_Minh";
services.xserver.desktopManager.plasma5.enable = true;
# Asahi kernel configuration
hardware.asahi = {
peripheralFirmwareDirectory = ./firmware;
use4KPages = false;
withRust = true;
addEdgeKernelConfig = true;
useExperimentalGPUDriver = true;
experimentalGPUInstallMode = "overlay";
};
# Override mesa
nixpkgs.overlays = lib.mkAfter [
(final: prev: {
mesa-asahi-edge = prev.mesa-asahi-edge.overrideAttrs (attrs: {
version = "24.0.0";
# buildInputs = attrs.buildInputs ++ (with pkgslw; [ libclc cmake (spirv-llvm-translator.override { inherit (llvmPackages_15) llvm; }) ]);
# nativeBuildInputs = attrs.nativeBuildInputs ++ (with pkgs; [ pkgs.unstable.spirv-llvm-translator ]);
src = final.fetchFromGitLab {
# latest release
domain = "gitlab.freedesktop.org";
owner = "asahi";
repo = "mesa";
rev = "asahi-20231121";
hash = "sha256-IcKKe1RA8sCaUfWK71ELzF15YaBS3DjoYhNMIWiQ5Jw=";
};
patches = lib.forEach attrs.patches (
p: if lib.hasSuffix "opencl.patch" p then ./mesa-asahi-edge/opencl.patch else p
);
});
})
];
## Additional mesa-related packages
environment.systemPackages = with pkgs; [ SDL2 ];
# Power Management
services.upower = {
enable = true;
criticalPowerAction = "PowerOff";
usePercentageForPolicy = true;
percentageCritical = 3;
percentageLow = 10;
};
services.logind.lidSwitch = "suspend";
# Printing
services.printing.drivers = with pkgs; [ epfl-cups-drivers ];
# Enable touchpad support (enabled default in most desktopManager).
services.libinput.enable = true;
# Keyboard
services.input-remapper.enable = true;
services.input-remapper.serviceWantedBy = [ "multi-user.target" ];
hardware.uinput.enable = true;
# Define a user account. Don't forget to set a password with passwd.
common.linux.username = "nki";
# Enable sway on login.
environment.loginShellInit = ''
if [ -z $DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
exec sway
fi
'';
# Networking
common.linux.networking = {
hostname = "kagami-air-m1";
networks."10-wired".match = "enp*";
networks."20-wireless".match = "wlan*";
dnsServers = [ "127.0.0.1" ];
};
nki.services.edns.enable = true;
nki.services.edns.ipv6 = true;
# Secrets
sops.defaultSopsFile = ./secrets.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
## tinc
sops.secrets."tinc/ed25519-private-key" = { };
services.my-tinc = {
enable = true;
hostName = "macbooknix";
ed25519PrivateKey = config.sops.secrets."tinc/ed25519-private-key".path;
bindPort = 6565;
};
services.dbus.packages = with pkgs; [ gcr ];
# Power Management
powerManagement = {
enable = true;
# powerDownCommands = ''
# /run/current-system/sw/bin/rmmod brcmfmac # Disable wifi
# /run/current-system/sw/bin/rmmod hci_bcm4377 # Disable bluetooth
# '';
# resumeCommands = ''
# /run/current-system/sw/bin/modprobe brcmfmac # Enable wifi
# /run/current-system/sw/bin/modprobe hci_bcm4377 # Enable bluetooth
# /run/current-system/sw/bin/systemctl restart iwd
# /run/current-system/sw/bin/systemctl restart bluetooth
# '';
};
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# Copy the NixOS configuration file and link it from the resulting system
# (/run/current-system/configuration.nix). This is useful in case you
# accidentally delete configuration.nix.
# system.copySystemConfiguration = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.05"; # Did you read the comment?
}

View file

@ -1,3 +0,0 @@
#!/usr/bin/env bash
mkdir -p firmware && cp /boot/asahi/{all_firmware.tar.gz,kernelcache*} firmware

View file

@ -1,41 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "usb_storage" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-uuid/ebb6bf2e-2d7f-4fa6-88cb-751fdd174ef9";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/19BC-1BE8";
fsType = "vfat";
};
swapDevices = [
{
device = "/swap";
size = 16 * 1024;
}
];
# nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
}

View file

@ -1,66 +0,0 @@
diff --git a/meson.build b/meson.build
index 04d89987311..babfe440973 100644
--- a/meson.build
+++ b/meson.build
@@ -1812,7 +1812,7 @@ endif
dep_clang = null_dep
if with_clc
- llvm_libdir = dep_llvm.get_variable(cmake : 'LLVM_LIBRARY_DIR', configtool: 'libdir')
+ llvm_libdir = get_option('clang-libdir')
dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false)
diff --git a/meson_options.txt b/meson_options.txt
index e885ba61a8a..29ce0270479 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,6 +1,12 @@
# Copyright © 2017-2019 Intel Corporation
# SPDX-License-Identifier: MIT
+option(
+ 'clang-libdir',
+ type : 'string',
+ value : '',
+ description : 'Locations to search for clang libraries.'
+)
option(
'platforms',
type : 'array',
diff --git a/src/gallium/targets/opencl/meson.build b/src/gallium/targets/opencl/meson.build
index 7c14135898e..74dc6850603 100644
--- a/src/gallium/targets/opencl/meson.build
+++ b/src/gallium/targets/opencl/meson.build
@@ -39,7 +39,8 @@ if dep_llvm.version().version_compare('>=10.0.0')
polly_isl_dep = cpp.find_library('PollyISL', dirs : llvm_libdir, required : false)
endif
-dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false)
+clang_libdir = get_option('clang-libdir')
+dep_clang = cpp.find_library('clang-cpp', dirs : clang_libdir, required : false)
# meson will return clang-cpp from system dirs if it's not found in llvm_libdir
linker_rpath_arg = '-Wl,--rpath=@0@'.format(llvm_libdir)
@@ -123,7 +124,7 @@ if with_opencl_icd
configuration : _config,
input : 'mesa.icd.in',
output : 'mesa.icd',
- install : true,
+ install : false,
install_tag : 'runtime',
install_dir : join_paths(get_option('sysconfdir'), 'OpenCL', 'vendors'),
)
diff --git a/src/gallium/targets/rusticl/meson.build b/src/gallium/targets/rusticl/meson.build
index b2963fe6dfa..99d6d801b94 100644
--- a/src/gallium/targets/rusticl/meson.build
+++ b/src/gallium/targets/rusticl/meson.build
@@ -76,7 +76,7 @@ configure_file(
configuration : _config,
input : 'rusticl.icd.in',
output : 'rusticl.icd',
- install : true,
+ install : false,
install_tag : 'runtime',
install_dir : join_paths(get_option('sysconfdir'), 'OpenCL', 'vendors'),
)

View file

@ -1,31 +0,0 @@
tinc:
ed25519-private-key: ENC[AES256_GCM,data:Cc86FPxUK+MEHTDKtbSOb4WE8WrK9sPI5fQ0oyYPkLzKqn0ZeHlTyeXZD9THTWDyW9Ky5q0rIk7HxjFkLZMid5x3d/EcovSvpx2dyIzYGX2EiVfAbkF4v2JqXrnfdF/EQSF+Z9G6P2elPdXlXu7dUEqe3XsFFdKwe80EIzItO+b3BE3P3Xt9NxbkCRj3zHSuVlt5v81WzLkUTtPLwOcQafwrZ3Engi9Yrjyh58ufGYQyBItTdwlKblv42XahiOqhJ8QXBGiMCFY=,iv:h88X3PT/G1QV4GcD07IvLcMyM7WLRMuBMMYQ6Z1YOgE=,tag:aK2dCizwThbJt8woLKS9UQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age169v95f5fqx0sg5mjpp63sumrj9sma9se203ra2c05qa67h2h2drs3tvdph
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHQ0ZFampRSm5BbTVpUk9o
MUhLenM0czVDM1NUWFFsTGxZUllKMjNOU3pZCm00eUZjRFU3bTZnbnNVR2RnMVl2
UEV2c1VXNDRhRklIZmpnN2dLczJPVGcKLS0tIGVlTkkrWXVTbFVJS1h4YnZRKzNn
dFJYaEErRWFJZXpnWVY1dk4zbnMxK3cKZ0aiD0ZusCWnjfhEsuVNO8XZrwupDANu
GUf03lwpLiOx6OehK2wR0pfMEfmbDOP6+o673Sw9PcreEPvUovh82Q==
-----END AGE ENCRYPTED FILE-----
- recipient: age10dd4t507h3ey68l2alu7z94s5lw0kshjq9lre5sv2vehrm9hg4rqk2let7
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAraHhUUXlpb3UvNWdkc3ZP
bFdNU0NaaStxR2c4SEY2NFByKzVGa1BkWXpjCmVlMmF3eUdid3RSMjVTUlJOM0hS
eHByVGtiUzBEZGRVRjg1TENPQlpPNjQKLS0tIG11cWFUU3JNeFY4cCt3d2ZUWmpl
dnZKYUIvM1N2eGFubkgzdUVESEVCYm8KGIEl6MKIc7Xsg9MePOgLovSBWh7b0BX/
aUXZm+elav6a7dmPSXqA7/ZSUtxZqD3sYF06YnABEhO+wQ5McArkFg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-10-17T11:24:18Z"
mac: ENC[AES256_GCM,data:nJLJXWvJpZRzvDuIiXiFQE2V4IYKtkFLR0U0KnTz7V9e/k+i4x53rMf8HuvKCxbWiJl/YdmxAEj0j+K8UPQv2G5OCG84qO0AUUXik2rHsd8WAv3EweS9WWSu0lgzf5U9ZdUuwZacmoU2khDmfXeZ5NTF/+eVDSDp3hZ+hTiJDFM=,iv:iEW9jecRfiT7vLYffNsFSI4wE/Ok5aNjOZfV1dTtt5Q=,tag:Gw7VpSbn17O75jNN3t8deg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3

View file

@ -1,15 +1,11 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
cfg = config.cloud.authentik;
mkImage = { imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
mkImage =
{ imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
# If we can pullImage we can just do
# mkImage = pkgs.dockerTools.pullImage;
@ -26,8 +22,8 @@ let
};
authentik = mkImage {
imageName = "ghcr.io/goauthentik/server";
finalImageTag = "2025.2.1";
imageDigest = "sha256:dc07e81b4462a1dad9c6720f4c73993e37d7cb2d2f94a306187318704d112e71";
finalImageTag = "2024.4.2";
imageDigest = "sha256:a2e592a08eb3c9e3435aa4e6585d60cc1eb54850da9d1498d56a131bbfbe03ff";
};
};
authentikEnv = pkgs.writeText "authentik.env" ''
@ -52,24 +48,13 @@ in
};
config = mkIf cfg.enable {
systemd.services.arion-authentik = {
serviceConfig.EnvironmentFile = cfg.envFile;
serviceConfig.Type = "notify";
serviceConfig.NotifyAccess = "all";
serviceConfig.TimeoutSec = 300;
script = lib.mkBefore ''
${lib.getExe pkgs.wait4x} http http://127.0.0.1:${toString cfg.port} --expect-status-code 200 -t 0 -q -- systemd-notify --ready &
'';
};
systemd.services.arion-authentik.serviceConfig.EnvironmentFile = cfg.envFile;
virtualisation.arion.projects.authentik.settings = {
services.postgresql.service = {
image = images.postgresql;
restart = "unless-stopped";
healthcheck = {
test = [
"CMD-SHELL"
"pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}"
];
test = [ "CMD-SHELL" "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}" ];
start_period = "20s";
interval = "30s";
retries = 5;
@ -80,20 +65,14 @@ in
POSTGRES_USER = "authentik";
POSTGRES_DB = "authentik";
};
env_file = [
cfg.envFile
"${postgresEnv}"
];
env_file = [ cfg.envFile "${postgresEnv}" ];
};
services.redis.service = {
image = images.redis;
command = "--save 60 1 --loglevel warning";
restart = "unless-stopped";
healthcheck = {
test = [
"CMD-SHELL"
"redis-cli ping | grep PONG"
];
test = [ "CMD-SHELL" "redis-cli ping | grep PONG" ];
start_period = "20s";
interval = "30s";
retries = 5;
@ -115,14 +94,10 @@ in
AUTHENTIK_POSTGRESQL__USER = "authentik";
AUTHENTIK_POSTGRESQL__NAME = "authentik";
};
env_file = [
cfg.envFile
"${authentikEnv}"
];
env_file = [ cfg.envFile "${authentikEnv}" ];
ports = [
"127.0.0.1:${toString cfg.port}:9000"
];
};
services.worker.service = {
image = images.authentik;
@ -140,11 +115,7 @@ in
AUTHENTIK_POSTGRESQL__USER = "authentik";
AUTHENTIK_POSTGRESQL__NAME = "authentik";
};
env_file = [
cfg.envFile
"${authentikEnv}"
];
user = "root";
env_file = [ cfg.envFile "${authentikEnv}" ];
};
docker-compose.volumes = {
database.driver = "local";
@ -153,3 +124,4 @@ in
};
};
}

View file

@ -1,9 +1,4 @@
{
pkgs,
lib,
config,
...
}:
{ pkgs, lib, config, ... }:
with lib;
let

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
let
cfg = config.cloud.conduit;
@ -38,105 +33,142 @@ with lib;
};
instances = mkOption {
type = types.attrsOf (
types.submodule {
options = {
host = mkOption {
type = types.str;
};
server_name = mkOption {
type = types.str;
default = "";
};
port = mkOption {
type = types.int;
};
noCloudflare = mkOption {
type = types.bool;
default = false;
};
allow_registration = mkOption {
type = types.bool;
default = false;
};
well-known_port = mkOption {
type = types.int;
};
type = types.attrsOf (types.submodule {
options = {
host = mkOption {
type = types.str;
};
}
);
server_name = mkOption {
type = types.str;
default = "";
};
port = mkOption {
type = types.int;
};
noCloudflare = mkOption {
type = types.bool;
default = false;
};
allow_registration = mkOption {
type = types.bool;
default = false;
};
well-known_port = mkOption {
type = types.int;
};
};
});
};
};
config.systemd.services = mkIf cfg.enable (
lib.attrsets.mapAttrs' (
name: instance:
lib.attrsets.nameValuePair "matrix-conduit-${name}" (
let
srvName = "matrix-conduit-${name}";
format = pkgs.formats.toml { };
server_name = if instance.server_name == "" then instance.host else instance.server_name;
configFile = format.generate "conduit.toml" (
lib.attrsets.recursiveUpdate defaultConfig {
config.systemd.services = mkIf cfg.enable
(lib.attrsets.mapAttrs'
(name: instance: lib.attrsets.nameValuePair "matrix-conduit-${name}"
(
let
srvName = "matrix-conduit-${name}";
format = pkgs.formats.toml { };
server_name = if instance.server_name == "" then instance.host else instance.server_name;
configFile = format.generate "conduit.toml" (lib.attrsets.recursiveUpdate defaultConfig {
global.server_name = server_name;
global.port = instance.port;
global.allow_registration = instance.allow_registration;
global.database_path = "/mnt/data/${srvName}/";
global.well_known_client = "https://${instance.host}";
global.well_known_server = "${instance.host}:443";
}
);
in
{
description = "Conduit Matrix Server (for ${server_name})";
documentation = [ "https://gitlab.com/famedly/conduit/" ];
wantedBy = [ "multi-user.target" ];
environment = {
CONDUIT_CONFIG = configFile;
};
serviceConfig = {
DynamicUser = true;
User = "${srvName}";
LockPersonality = true;
MemoryDenyWriteExecute = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateUsers = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
# StateDirectory = "/mnt/data/${srvName}";
BindPaths = [ "/mnt/data/${srvName}" ];
ExecStart = "${cfg.package}/bin/conduit";
Restart = "on-failure";
RestartSec = 10;
StartLimitBurst = 5;
};
}
)
) cfg.instances
);
});
in
{
description = "Conduit Matrix Server (for ${server_name})";
documentation = [ "https://gitlab.com/famedly/conduit/" ];
wantedBy = [ "multi-user.target" ];
environment = { CONDUIT_CONFIG = configFile; };
serviceConfig = {
DynamicUser = true;
User = "${srvName}";
LockPersonality = true;
MemoryDenyWriteExecute = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateUsers = true;
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
# StateDirectory = "/mnt/data/${srvName}";
BindPaths = [ "/mnt/data/${srvName}" ];
ExecStart = "${cfg.package}/bin/conduit";
Restart = "on-failure";
RestartSec = 10;
StartLimitBurst = 5;
};
}
))
cfg.instances);
# Serving .well-known files
# This is a single .well-known/matrix/server file that points to the server,
# which is NOT on port 8448 since Cloudflare doesn't allow us to route HTTPS
# through that port.
config.services.nginx = mkIf cfg.enable
{
enable = true;
virtualHosts = lib.attrsets.mapAttrs'
(name: instance: lib.attrsets.nameValuePair "conduit-${name}-well-known" {
listen = [{ addr = "127.0.0.1"; port = instance.well-known_port; }];
# Check https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-well-known.md
# for the file structure.
root = pkgs.symlinkJoin
{
name = "well-known-files-for-conduit-${name}";
paths = [
(pkgs.writeTextDir ".well-known/matrix/client" (builtins.toJSON {
"m.homeserver".base_url = "https://${instance.host}";
"org.matrix.msc3575.proxy".url = "https://${instance.host}";
}))
(pkgs.writeTextDir ".well-known/matrix/server" (builtins.toJSON {
"m.server" = "${instance.host}:443";
}))
];
};
extraConfig =
# Enable CORS from anywhere since we want all clients to find us out
''
add_header 'Access-Control-Allow-Origin' "*";
'' +
# Force returning values to be JSON data
''
default_type application/json;
'';
})
cfg.instances;
};
config.cloud.traefik.hosts = mkIf cfg.enable (
(lib.attrsets.mapAttrs' (
name: instance:
lib.attrsets.nameValuePair "conduit-${name}" ({
(lib.attrsets.mapAttrs'
(name: instance: lib.attrsets.nameValuePair "conduit-${name}" ({
inherit (instance) host port noCloudflare;
})
) cfg.instances)
}))
cfg.instances)
// (lib.attrsets.mapAttrs'
(name: instance: lib.attrsets.nameValuePair "conduit-${name}-well-known" (
let
server_name = if instance.server_name == "" then instance.host else instance.server_name;
in
{
port = instance.well-known_port;
filter = "Host(`${server_name}`) && PathPrefix(`/.well-known`)";
}
))
cfg.instances)
);
}

View file

@ -1,15 +1,9 @@
{
pkgs,
lib,
config,
...
}:
{ pkgs, lib, config, ... }:
let
cfg = config.cloud.conduit.heisenbridge;
cfgConduit = config.cloud.conduit;
in
with lib;
{
with lib; {
options.cloud.conduit.heisenbridge = {
enable = mkEnableOption "Enable heisenbridge for conduit";
package = mkPackageOption pkgs "heisenbridge" { };
@ -29,26 +23,17 @@ with lib;
};
config = mkIf cfg.enable (
let
cfgFile =
if cfg.port == null then
cfg.appserviceFile
else
pkgs.runCommand "heisenbridge-config" { } ''
cp ${cfg.appserviceFile} $out
${pkgs.sd}/bin/sd '^url: .*$' "url: http://127.0.0.1:${cfg.port}"
'';
listenArgs = lists.optionals (cfg.port != null) [
"--listen-port"
(toString cfg.port)
];
cfgFile = if cfg.port == null then cfg.appserviceFile else
pkgs.runCommand "heisenbridge-config" { } ''
cp ${cfg.appserviceFile} $out
${pkgs.sd}/bin/sd '^url: .*$' "url: http://127.0.0.1:${cfg.port}"
'';
listenArgs = lists.optionals (cfg.port != null) [ "--listen-port" (toString cfg.port) ];
in
{
systemd.services.heisenbridge = {
description = "Matrix<->IRC bridge";
requires = [
"matrix-conduit-nkagami.service"
"matrix-synapse.service"
]; # So the registration file can be used by Synapse
requires = [ "matrix-synapse.service" ]; # So the registration file can be used by Synapse
wantedBy = [ "multi-user.target" ];
serviceConfig = rec {
@ -92,18 +77,12 @@ with lib;
RemoveIPC = true;
UMask = "0077";
CapabilityBoundingSet = [
"CAP_CHOWN"
] ++ optional (cfg.port != null && cfg.port < 1024) "CAP_NET_BIND_SERVICE";
CapabilityBoundingSet = [ "CAP_CHOWN" ] ++ optional (cfg.port != null && cfg.port < 1024) "CAP_NET_BIND_SERVICE";
AmbientCapabilities = CapabilityBoundingSet;
NoNewPrivileges = true;
LockPersonality = true;
RestrictRealtime = true;
SystemCallFilter = [
"@system-service"
"~@privileged"
"@chown"
];
SystemCallFilter = [ "@system-service" "~@privileged" "@chown" ];
SystemCallArchitectures = "native";
RestrictAddressFamilies = "AF_INET AF_INET6";
};
@ -118,3 +97,4 @@ with lib;
}
);
}

View file

@ -1,15 +1,11 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
cfg = config.cloud.firezone;
mkImage = { imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
mkImage =
{ imageName, imageDigest, ... }: "${imageName}@${imageDigest}";
# If we can pullImage we can just do
# mkImage = pkgs.dockerTools.pullImage;
@ -52,10 +48,7 @@ in
image = images.postgresql;
restart = "unless-stopped";
healthcheck = {
test = [
"CMD-SHELL"
"pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}"
];
test = [ "CMD-SHELL" "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}" ];
start_period = "20s";
interval = "30s";
retries = 5;
@ -96,10 +89,7 @@ in
driver = "bridge";
ipam.config = [
{ subnet = "172.25.0.0/16"; }
{
subnet = "2001:3990:3990::/64";
gateway = "2001:3990:3990::1";
}
{ subnet = "2001:3990:3990::/64"; gateway = "2001:3990:3990::1"; }
];
};
};

View file

@ -1,15 +1,9 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
cfg = config.cloud.gotosocial;
dbUser = "gotosocial";
storageLocation = "/mnt/data/gotosocial";
in
{
options.cloud.gotosocial = {
@ -46,21 +40,13 @@ in
# Postgres
cloud.postgresql.databases = [ dbUser ];
# Traefik
cloud.traefik.hosts =
{
gotosocial = { inherit (cfg) host port; };
}
// (
if cfg.accountDomain != cfg.host && cfg.accountDomain != "" then
{
gotosocial-wellknown = {
inherit (cfg) port;
filter = "Host(`${cfg.accountDomain}`) && (PathPrefix(`/.well-known/webfinger`) || PathPrefix(`/.well-known/nodeinfo`) || PathPrefix(`/.well-known/host-meta`))";
};
}
else
{ }
);
cloud.traefik.hosts = { gotosocial = { inherit (cfg) host port; }; } //
(if cfg.accountDomain != cfg.host && cfg.accountDomain != "" then {
gotosocial-wellknown = {
inherit (cfg) port;
filter = "Host(`${cfg.accountDomain}`) && (PathPrefix(`/.well-known/webfinger`) || PathPrefix(`/.well-known/nodeinfo`) || PathPrefix(`/.well-known/host-meta`))";
};
} else { });
# The service itself
services.gotosocial = {
enable = true;
@ -73,10 +59,7 @@ in
bind-address = "localhost";
port = cfg.port;
# Instance
instance-languages = [
"en-ca"
"vi"
];
instance-languages = [ "en-ca" "vi" ];
# Accounts
accounts-registration-open = false;
accounts-allow-custom-css = true;
@ -89,49 +72,20 @@ in
web-template-base-dir = "${cfg.package}/share/gotosocial/web/template";
web-asset-base-dir = "${cfg.package}/share/gotosocial/web/assets";
# Media
media-emoji-remote-max-size =
256 * 1024 # bytes
;
media-emoji-local-max-size =
256 * 1024 # bytes
;
media-remote-cache-days = 7;
media-cleanup-from = "00:00";
media-cleanup-every = "24h";
media-emoji-remote-max-size = 256 * 1024 /* bytes */;
media-emoji-local-max-size = 256 * 1024 /* bytes */;
# OIDC
oidc-enabled = true;
oidc-idp-name = "DTTH";
oidc-scopes = [
"openid"
"email"
"profile"
];
oidc-scopes = [ "openid" "email" "profile" ];
# HTTP Client
http-client.block-ips = [ "11.0.0.0/24" ];
# Advanced
advanced-rate-limit-requests = 0;
# Storage
storage-backend = "local";
storage-local-base-path = "${storageLocation}/storage";
# instance-inject-mastodon-version = true;
};
};
systemd.services.gotosocial.requires = mkAfter [
"postgresql.service"
"arion-authentik.service"
];
systemd.services.gotosocial.after = mkAfter [
"postgresql.service"
"arion-authentik.service"
];
systemd.services.gotosocial.unitConfig = {
RequiresMountsFor = [ storageLocation ];
ReadWritePaths = [ storageLocation ];
};
systemd.tmpfiles.settings."10-gotosocial".${storageLocation}.d = {
user = dbUser;
group = dbUser;
mode = "0700";
};
systemd.services.gotosocial.requires = mkAfter [ "minio.service" "postgresql.service" ];
systemd.services.gotosocial.after = mkAfter [ "minio.service" "postgresql.service" ];
};
}

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib;
let
@ -243,12 +238,7 @@ in
# MTA-STS server
services.nginx.enable = true;
services.nginx.virtualHosts.maddy-mta-sts = {
listen = [
{
addr = "127.0.0.1";
port = mtaStsPort;
}
];
listen = [{ addr = "127.0.0.1"; port = mtaStsPort; }];
root = mtaStsDir;
};
@ -283,10 +273,7 @@ in
# maddy itself
systemd.services."${name}" = {
after = [
"network.target"
"traefik-certs-dumper.service"
];
after = [ "network.target" "traefik-certs-dumper.service" ];
wantedBy = [ "multi-user.target" ];
requires = [ "postgresql.service" ];
@ -340,6 +327,7 @@ in
KillMode = "mixed";
KillSignal = "SIGTERM";
# Required to bind on ports lower than 1024.
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
CapabilityBoundingSet = "CAP_NET_BIND_SERVICE";

View file

@ -1,178 +0,0 @@
diff --git a/.env.sample b/.env.sample
index 51046501d..6daf60347 100644
--- a/.env.sample
+++ b/.env.sample
@@ -66,6 +66,8 @@ AWS_S3_UPLOAD_BUCKET_URL=http://s3:4569
AWS_S3_UPLOAD_BUCKET_NAME=bucket_name_here
AWS_S3_FORCE_PATH_STYLE=true
AWS_S3_ACL=private
+AWS_S3_R2=true
+AWS_S3_R2_PUBLIC_URL=http://s3:4569
# AUTHENTICATION
diff --git a/app/utils/files.ts b/app/utils/files.ts
index 16b66a2c4..c56ffd2b2 100644
--- a/app/utils/files.ts
+++ b/app/utils/files.ts
@@ -88,8 +88,13 @@ export const uploadFile = async (
xhr.addEventListener("loadend", () => {
resolve(xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 400);
});
- xhr.open("POST", data.uploadUrl, true);
- xhr.send(formData);
+ xhr.open(data.method, data.uploadUrl, true);
+ xhr.setRequestHeader("Content-Type", file.type);
+ if (data.method === "POST") {
+ xhr.send(formData);
+ } else {
+ xhr.send(file);
+ }
});
if (!success) {
diff --git a/server/env.ts b/server/env.ts
index 5b420f2e1..4ea1e8d3c 100644
--- a/server/env.ts
+++ b/server/env.ts
@@ -519,6 +519,14 @@ export class Environment {
environment.AWS_S3_UPLOAD_BUCKET_NAME
);
+ @IsOptional()
+ public AWS_S3_R2 = this.toBoolean(environment.AWS_S3_R2 ?? "false");
+
+ @IsOptional()
+ public AWS_S3_R2_PUBLIC_URL = this.toOptionalString(
+ environment.AWS_S3_R2_PUBLIC_URL
+ );
+
/**
* Whether to force path style URLs for S3 objects, this is required for some
* S3-compatible storage providers.
diff --git a/server/routes/api/attachments/attachments.ts b/server/routes/api/attachments/attachments.ts
index d2288c215..72251962c 100644
--- a/server/routes/api/attachments/attachments.ts
+++ b/server/routes/api/attachments/attachments.ts
@@ -3,6 +3,7 @@ import { v4 as uuidv4 } from "uuid";
import { AttachmentPreset } from "@shared/types";
import { bytesToHumanReadable, getFileNameFromUrl } from "@shared/utils/files";
import { AttachmentValidation } from "@shared/validations";
+import env from "@server/env";
import { createContext } from "@server/context";
import {
AuthorizationError,
@@ -83,16 +84,30 @@ router.post(
userId: user.id,
});
- const presignedPost = await FileStorage.getPresignedPost(
- key,
- acl,
- maxUploadSize,
- contentType
- );
+ let uploadUrl;
+ let method;
+ let presignedPost = {
+ fields: {},
+ };
+ if (env.AWS_S3_R2) {
+ uploadUrl = await FileStorage.getPresignedPut(key);
+ method = "PUT";
+ } else {
+ uploadUrl = FileStorage.getUploadUrl();
+ method = "POST";
+
+ presignedPost = await FileStorage.getPresignedPost(
+ key,
+ acl,
+ maxUploadSize,
+ contentType
+ );
+ }
ctx.body = {
data: {
- uploadUrl: FileStorage.getUploadUrl(),
+ uploadUrl,
+ method,
form: {
"Cache-Control": "max-age=31557600",
"Content-Type": contentType,
diff --git a/server/storage/files/BaseStorage.ts b/server/storage/files/BaseStorage.ts
index 339262cc5..03f658271 100644
--- a/server/storage/files/BaseStorage.ts
+++ b/server/storage/files/BaseStorage.ts
@@ -26,6 +26,8 @@ export default abstract class BaseStorage {
contentType: string
): Promise<Partial<PresignedPost>>;
+ public abstract getPresignedPut(key: string): Promise<string>;
+
/**
* Returns a promise that resolves with a stream for reading a file from the storage provider.
*
diff --git a/server/storage/files/LocalStorage.ts b/server/storage/files/LocalStorage.ts
index 83cf98c50..324e60dd9 100644
--- a/server/storage/files/LocalStorage.ts
+++ b/server/storage/files/LocalStorage.ts
@@ -30,6 +30,10 @@ export default class LocalStorage extends BaseStorage {
});
}
+ public async getPresignedPut(key: string) {
+ return this.getUrlForKey(key);
+ }
+
public getUploadUrl() {
return "/api/files.create";
}
diff --git a/server/storage/files/S3Storage.ts b/server/storage/files/S3Storage.ts
index beba39ab2..4f0fe09a9 100644
--- a/server/storage/files/S3Storage.ts
+++ b/server/storage/files/S3Storage.ts
@@ -4,6 +4,7 @@ import {
S3Client,
DeleteObjectCommand,
GetObjectCommand,
+ PutObjectCommand,
ObjectCannedACL,
} from "@aws-sdk/client-s3";
import { Upload } from "@aws-sdk/lib-storage";
@@ -58,6 +59,16 @@ export default class S3Storage extends BaseStorage {
return createPresignedPost(this.client, params);
}
+ public async getPresignedPut(key: string) {
+ const params = {
+ Bucket: env.AWS_S3_UPLOAD_BUCKET_NAME,
+ Key: key,
+ };
+
+ const command = new PutObjectCommand(params);
+ return await getSignedUrl(this.client, command, { expiresIn: 3600 });
+ }
+
private getPublicEndpoint(isServerUpload?: boolean) {
if (env.AWS_S3_ACCELERATE_URL) {
return env.AWS_S3_ACCELERATE_URL;
@@ -137,10 +148,17 @@ export default class S3Storage extends BaseStorage {
);
}
+ public getR2ObjectUrl = async (key: string) =>
+ env.AWS_S3_R2_PUBLIC_URL + "/" + key;
+
public getSignedUrl = async (
key: string,
expiresIn = S3Storage.defaultSignedUrlExpires
) => {
+ if (env.AWS_S3_R2) {
+ return this.getR2ObjectUrl(key);
+ }
+
const isDocker = env.AWS_S3_UPLOAD_BUCKET_URL.match(/http:\/\/s3:/);
const params = {
Bucket: this.getBucket(),

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
@ -36,13 +31,6 @@ in
ensureDatabases = cfg.databases;
ensureUsers = (map userFromDatabase cfg.databases);
dataDir = "/mnt/data/postgresql/${config.services.postgresql.package.psqlSchema}";
};
config.systemd.services.postgresql.serviceConfig = {
StateDirectory = "postgresql postgresql ${config.services.postgresql.dataDir}";
StateDirectoryMode = "0750";
};
# Backup settings

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let

View file

@ -1,9 +1,4 @@
{
pkgs,
lib,
config,
...
}:
{ pkgs, lib, config, ... }:
with lib;
let
@ -14,169 +9,126 @@ let
};
# Copied from traefik.nix
jsonValue =
with types;
jsonValue = with types;
let
valueType =
nullOr (oneOf [
valueType = nullOr
(oneOf [
bool
int
float
str
(lazyAttrsOf valueType)
(listOf valueType)
])
// {
description = "JSON value";
emptyValue.value = { };
};
]) // {
description = "JSON value";
emptyValue.value = { };
};
in
valueType;
hostType =
with types;
submodule {
options = {
host = mkOption {
type = str;
description = "The host for the router filter";
};
path = mkOption {
type = nullOr str;
default = null;
description = "The path for the router filter (exact path is matched)";
};
filter = mkOption {
type = nullOr str;
default = null;
description = "The filter syntax for the router. Overrides `host` and `path` if provided";
};
localHost = mkOption {
type = types.nullOr types.str;
description = "The local host of the service. Must be an IP if protocol is TCP. Default to localhost/127.0.0.1";
default = null;
};
port = mkOption {
type = types.port;
description = "The port that the service is listening on";
};
entrypoints = mkOption {
type = listOf (enum [
"http"
"https"
"smtp-submission"
"smtp-submission-ssl"
"imap"
"wireguard"
]);
default = [ "https" ];
description = "The entrypoints that will serve the host";
};
middlewares = mkOption {
type = listOf jsonValue;
default = [ ];
description = "The middlewares to be used with the host.";
};
protocol = mkOption {
type = enum [
"http"
"tcp"
"udp"
];
default = "http";
description = "The protocol of the router and service";
};
tlsPassthrough = mkOption {
type = types.bool;
default = true;
description = "Sets the TCP passthrough value. Defaults to `true` if the connection is tcp";
};
noCloudflare = mkOption {
type = types.bool;
default = false;
description = "Bypasses the client cert requirement, enable if you don't route things through cloudflare";
};
hostType = with types; submodule {
options = {
host = mkOption {
type = str;
description = "The host for the router filter";
};
path = mkOption {
type = nullOr str;
default = null;
description = "The path for the router filter (exact path is matched)";
};
filter = mkOption {
type = nullOr str;
default = null;
description = "The filter syntax for the router. Overrides `host` and `path` if provided";
};
localHost = mkOption {
type = types.nullOr types.str;
description = "The local host of the service. Must be an IP if protocol is TCP. Default to localhost/127.0.0.1";
default = null;
};
port = mkOption {
type = types.port;
description = "The port that the service is listening on";
};
entrypoints = mkOption {
type = listOf (enum [ "http" "https" "smtp-submission" "smtp-submission-ssl" "imap" "wireguard" ]);
default = [ "https" ];
description = "The entrypoints that will serve the host";
};
middlewares = mkOption {
type = listOf jsonValue;
default = [ ];
description = "The middlewares to be used with the host.";
};
protocol = mkOption {
type = enum [ "http" "tcp" "udp" ];
default = "http";
description = "The protocol of the router and service";
};
tlsPassthrough = mkOption {
type = types.bool;
default = true;
description = "Sets the TCP passthrough value. Defaults to `true` if the connection is tcp";
};
noCloudflare = mkOption {
type = types.bool;
default = false;
description = "Bypasses the client cert requirement, enable if you don't route things through cloudflare";
};
};
};
# Returns the filter given a host configuration
filterOfHost =
host:
filterOfHost = host:
let
hostFilter = if host.protocol == "http" then "Host" else "HostSNI";
in
if host.filter != null then
host.filter
else if host.path == null then
"${hostFilter}(`${host.host}`)"
else
"${hostFilter}(`${host.host}`) && Path(`${host.path}`)";
if host.filter != null then host.filter
else if host.path == null then "${hostFilter}(`${host.host}`)"
else "${hostFilter}(`${host.host}`) && Path(`${host.path}`)";
# Turns a host configuration into dynamic traefik configuration
hostToConfig = name: host: {
"${host.protocol}" =
{
routers."${name}-router" =
(
if (host.protocol != "udp") then
{
rule = filterOfHost host;
tls =
{
certResolver = "le";
}
// (
if host.protocol == "tcp" then
{ passthrough = if (host ? tlsPassthrough) then host.tlsPassthrough else true; }
else
{ }
)
// (if host.noCloudflare then tlsNoCloudflare else { });
}
else
{ }
)
// {
entryPoints = host.entrypoints;
service = "${name}-service";
}
// (
if host.protocol == "http" then
{ middlewares = lists.imap0 (id: m: "${name}-middleware-${toString id}") host.middlewares; }
else if host.middlewares == [ ] then
{ }
else
abort "Cannot have middlewares on non-http routers"
);
services."${name}-service".loadBalancer.servers = [
(
let
localhost =
if isNull host.localHost then
(if host.protocol == "http" then "localhost" else "127.0.0.1")
else
host.localHost;
in
if host.protocol == "http" then
{ url = "http://${localhost}:${toString host.port}"; }
else
{ address = "${localhost}:${toString host.port}"; }
)
];
}
// (
if (host.middlewares != [ ]) then
{
middlewares = builtins.listToAttrs (
lists.imap0 (id: v: {
name = "${name}-middleware-${toString id}";
value = v;
}) host.middlewares
);
}
else
"${host.protocol}" = {
routers."${name}-router" = (if (host.protocol != "udp") then {
rule = filterOfHost host;
tls = { certResolver = "le"; }
// (if host.protocol == "tcp" then { passthrough = if (host ? tlsPassthrough) then host.tlsPassthrough else true; } else { })
// (if host.noCloudflare then tlsNoCloudflare else { });
} else { }) // {
entryPoints = host.entrypoints;
service = "${name}-service";
} // (
if host.protocol == "http" then
{ middlewares = lists.imap0 (id: m: "${name}-middleware-${toString id}") host.middlewares; }
else if host.middlewares == [ ] then
{ }
else abort "Cannot have middlewares on non-http routers"
);
services."${name}-service".loadBalancer.servers = [
(
let
localhost =
if isNull host.localHost then
(
if host.protocol == "http" then "localhost"
else "127.0.0.1"
) else host.localHost;
in
if host.protocol == "http" then
{ url = "http://${localhost}:${toString host.port}"; }
else { address = "${localhost}:${toString host.port}"; }
)
];
} // (if (host.middlewares != [ ]) then {
middlewares = builtins.listToAttrs (lists.imap0
(id: v: {
name = "${name}-middleware-${toString id}";
value = v;
})
host.middlewares);
} else { });
};
tlsConfig = {

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
@ -33,8 +28,7 @@ in
# Dynamic configuration
# ---------------------
## Middleware
services.traefik.dynamicConfigOptions.http.middlewares.dashboard-auth.basicAuth.usersFile =
cfg.usersFile;
services.traefik.dynamicConfigOptions.http.middlewares.dashboard-auth.basicAuth.usersFile = cfg.usersFile;
## Router
services.traefik.dynamicConfigOptions.http.routers.dashboard = {
rule = "Host(`${cfg.host}`)";

View file

@ -1,29 +1,22 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
# Copied from traefik.nix
jsonValue =
with types;
jsonValue = with types;
let
valueType =
nullOr (oneOf [
valueType = nullOr
(oneOf [
bool
int
float
str
(lazyAttrsOf valueType)
(listOf valueType)
])
// {
description = "JSON value";
emptyValue.value = { };
};
]) // {
description = "JSON value";
emptyValue.value = { };
};
in
valueType;
@ -48,11 +41,7 @@ let
cfg = config.cloud.traefik;
in
{
imports = [
./config.nix
./dashboard.nix
./certs-dumper.nix
];
imports = [ ./config.nix ./dashboard.nix ./certs-dumper.nix ];
options.cloud.traefik = {
cloudflareKeyFile = mkOption {
type = types.path;
@ -115,12 +104,7 @@ in
config.systemd.services.traefik.environment.CF_DNS_API_TOKEN_FILE = cfg.cloudflareKeyFile;
# Set up firewall to allow traefik traffic.
config.networking.firewall.allowedTCPPorts = [
443
993
587
465
];
config.networking.firewall.allowedTCPPorts = [ 443 993 587 465 ];
config.networking.firewall.allowedUDPPorts = [
443 # QUIC
51820 # Wireguard

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.cloud.writefreely;
@ -67,3 +62,4 @@ in
}
);
}

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
@ -11,203 +6,105 @@ let
# Modules
modules = {
adb =
{ config, ... }:
mkIf config.common.linux.enable {
services.udev.packages = with pkgs; [ android-udev-rules ];
programs.adb.enable = true;
users.users.${config.common.linux.username}.extraGroups = [ "adbusers" ];
adb = { config, ... }: mkIf config.common.linux.enable {
services.udev.packages = with pkgs; [ android-udev-rules ];
programs.adb.enable = true;
users.users.${config.common.linux.username}.extraGroups = [ "adbusers" ];
};
ios = { config, pkgs, ... }: mkIf config.common.linux.enable {
services.avahi.enable = true;
services.usbmuxd.enable = true;
services.usbmuxd.package = pkgs.usbmuxd2;
environment.systemPackages = with pkgs; [
libimobiledevice
ifuse
];
users.users.${config.common.linux.username}.extraGroups = [ config.services.usbmuxd.group ];
systemd.network.networks."05-ios-tethering" = {
matchConfig.Driver = "ipheth";
networkConfig.DHCP = "yes";
linkConfig.RequiredForOnline = "no";
};
ios =
{ config, pkgs, ... }:
mkIf config.common.linux.enable {
services.usbmuxd.enable = true;
services.usbmuxd.package = pkgs.usbmuxd2;
environment.systemPackages = with pkgs; [
libimobiledevice
ifuse
];
users.users.${config.common.linux.username}.extraGroups = [ config.services.usbmuxd.group ];
systemd.network.networks."05-ios-tethering" = {
matchConfig.Driver = "ipheth";
networkConfig.DHCP = "yes";
linkConfig.RequiredForOnline = "no";
};
};
accounts = { pkgs, ... }: mkIf (config.common.linux.enable && !pkgs.stdenv.isAarch64) {
environment.systemPackages = with pkgs.gnome; [ pkgs.glib gnome-control-center ];
services.accounts-daemon.enable = true;
services.gnome.gnome-online-accounts.enable = true;
# programs.evolution.enable = true;
# programs.evolution.plugins = with pkgs; [ evolution-ews ];
# services.gnome.evolution-data-server.enable = true;
# services.gnome.evolution-data-server.plugins = with pkgs; [ evolution-ews ];
};
wlr = { ... }: mkIf config.common.linux.enable {
# swaync disable notifications on screencast
xdg.portal.wlr.settings.screencast = {
exec_before = ''which swaync-client && swaync-client --inhibitor-add "xdg-desktop-portal-wlr" || true'';
exec_after = ''which swaync-client && swaync-client --inhibitor-remove "xdg-desktop-portal-wlr" || true'';
};
};
logitech = { pkgs, ... }: mkIf cfg.enable {
services.ratbagd.enable = true;
environment.systemPackages = with pkgs; [ piper ];
};
kwallet = { pkgs, lib, ... }: mkIf cfg.enable {
environment.systemPackages = [ pkgs.kdePackages.kwallet ];
services.dbus.packages = [ pkgs.kdePackages.kwallet ];
xdg.portal = {
extraPortals = [ pkgs.kdePackages.kwallet ];
};
};
virtualisation = { pkgs, ... }: mkIf cfg.enable {
virtualisation.podman = {
enable = true;
dockerCompat = true;
defaultNetwork.settings.dns_enabled = true;
};
graphics =
{ config, pkgs, ... }:
{
hardware.graphics.enable = true;
hardware.graphics.enable32Bit = true;
# Monitor backlight
hardware.i2c.enable = true;
services.ddccontrol.enable = true;
environment.systemPackages = [
pkgs.luminance
pkgs.ddcutil
];
};
virtualisation.oci-containers.backend = "podman";
accounts =
{ pkgs, ... }:
mkIf (config.common.linux.enable && !pkgs.stdenv.isAarch64) {
environment.systemPackages = [
pkgs.glib
(pkgs.gnome-control-center or pkgs.gnome.gnome-control-center)
];
services.accounts-daemon.enable = true;
services.gnome.gnome-online-accounts.enable = true;
# programs.evolution.enable = true;
# programs.evolution.plugins = with pkgs; [ evolution-ews ];
# services.gnome.evolution-data-server.enable = true;
# services.gnome.evolution-data-server.plugins = with pkgs; [ evolution-ews ];
};
wlr =
{ lib, config, ... }:
mkIf config.common.linux.enable {
# swaync disable notifications on screencast
xdg.portal.wlr.settings.screencast = {
exec_before = ''which swaync-client && swaync-client --inhibitor-add "xdg-desktop-portal-wlr" || true'';
exec_after = ''which swaync-client && swaync-client --inhibitor-remove "xdg-desktop-portal-wlr" || true'';
};
# Niri stuff
# https://github.com/sodiboo/niri-flake/blob/main/docs.md
programs.niri.enable = true;
programs.niri.package = pkgs.niri-stable;
# Override gnome-keyring disabling
services.gnome.gnome-keyring.enable = lib.mkForce false;
# ydotool
programs.ydotool.enable = true;
users.extraGroups.${config.programs.ydotool.group}.members = [ cfg.username ];
};
logitech =
{ pkgs, ... }:
mkIf cfg.enable {
services.ratbagd.enable = true;
environment.systemPackages = with pkgs; [ piper ];
};
kwallet =
{ pkgs, lib, ... }:
mkIf cfg.enable {
environment.systemPackages = [ pkgs.kdePackages.kwallet ];
services.dbus.packages = [ pkgs.kdePackages.kwallet ];
xdg.portal = {
extraPortals = [ pkgs.kdePackages.kwallet ];
};
};
virtualisation =
{ pkgs, ... }:
mkIf cfg.enable {
virtualisation.podman = {
enable = true;
extraPackages = [ pkgs.slirp4netns ];
dockerCompat = true;
defaultNetwork.settings.dns_enabled = true;
};
virtualisation.oci-containers.backend = "podman";
virtualisation.virtualbox.host.enable = false;
users.extraGroups.vboxusers.members = [ cfg.username ];
};
nix-ld =
{ pkgs, ... }:
{
programs.nix-ld = {
enable = true;
libraries = with pkgs; [
ncurses
llvmPackages.libcxx
glibc
sqlite
];
};
};
virtualisation.virtualbox.host.enable = false;
users.extraGroups.vboxusers.members = [ cfg.username ];
};
};
rt-audio =
{ pkgs, ... }:
mkIf cfg.enable {
services.pipewire.lowLatency = {
# enable this module
enable = true;
# defaults (no need to be set unless modified)
quantum = 32;
rate = 44100;
};
security.rtkit.enable = true;
# Real time configurations
boot.kernel.sysctl = {
"vm.swappiness" = 10;
"fs.inotify.max_user_watches" = 524288;
};
security.pam.loginLimits = [
{
domain = "@audio";
item = "rtprio";
type = "-";
value = "90";
}
{
domain = "@audio";
item = "memlock";
type = "-";
value = "unlimited";
}
];
rt-audio = { pkgs, ... }: mkIf cfg.enable {
services.pipewire.lowLatency = {
# enable this module
enable = true;
# defaults (no need to be set unless modified)
quantum = 32;
rate = 48000;
};
security.rtkit.enable = true;
tailscale =
{ config, ... }:
{
options.common.linux = {
tailscale = {
firewall.allowPorts = mkOption {
type = types.listOf types.port;
description = "List of ports to allow tailscale to pass through";
default = [ ];
};
};
};
config =
let
cfg = config.common.linux.tailscale;
in
{
# Enable tailscale
services.tailscale.enable = true;
networking.firewall.interfaces."tailscale0" = {
allowedUDPPorts = cfg.firewall.allowPorts;
allowedTCPPorts = cfg.firewall.allowPorts;
};
};
# Real time configurations
boot.kernel.sysctl = {
"vm.swappiness" = 10;
"fs.inotify.max_user_watches" = 524288;
};
security.pam.loginLimits = [
{
domain = "@audio";
item = "rtprio";
type = "-";
value = "90";
}
{
domain = "@audio";
item = "memlock";
type = "-";
value = "unlimited";
}
];
};
in
{
imports = with modules; [
./sops.nix
adb
ios
graphics
wlr
logitech
kwallet
virtualisation
accounts
rt-audio
nix-ld
tailscale
];
imports = with modules; [ adb ios wlr logitech kwallet virtualisation accounts rt-audio ];
options.common.linux = {
enable = mkOption {
@ -230,30 +127,23 @@ in
dnsServers = mkOption {
type = types.listOf types.str;
description = "DNS server list";
default = [
"1.1.1.1"
"2606:4700:4700:1111"
];
default = [ "1.1.1.1" "2606:4700:4700:1111" ];
};
networks = mkOption {
type = types.attrsOf (
types.submodule {
options.match = mkOption {
type = types.str;
description = "The interface name to match";
};
options.isRequired = mkOption {
type = types.bool;
description = "Require this interface to be connected for network-online.target";
default = false;
};
}
);
type = types.attrsOf (types.submodule {
options.match = mkOption {
type = types.str;
description = "The interface name to match";
};
options.isRequired = mkOption {
type = types.bool;
description = "Require this interface to be connected for network-online.target";
default = false;
};
});
description = "Network configuration";
default = {
default = {
match = "*";
};
default = { match = "*"; };
};
};
};
@ -278,16 +168,18 @@ in
};
boot.initrd.systemd.enable = builtins.length (builtins.attrNames (cfg.luksDevices)) > 0;
# LUKS devices
boot.initrd.luks.devices = builtins.mapAttrs (name: path: {
device = path;
preLVM = true;
allowDiscards = true;
boot.initrd.luks.devices = builtins.mapAttrs
(name: path: {
device = path;
preLVM = true;
allowDiscards = true;
crypttabExtraOpts = [
"tpm2-device=auto"
"fido2-device=auto"
];
}) cfg.luksDevices;
crypttabExtraOpts = [
"tpm2-device=auto"
"fido2-device=auto"
];
})
cfg.luksDevices;
## Hardware-related
@ -326,15 +218,10 @@ in
"wheel" # Enable sudo for the user.
"plugdev" # Enable openrazer-daemon privileges
"audio"
"video"
"input"
];
shell = pkgs.fish;
};
nix.settings.trusted-users = [
"root"
cfg.username
];
nix.settings.trusted-users = [ "root" cfg.username ];
## Network configuration
systemd.network.enable = true;
@ -345,11 +232,13 @@ in
networking.hostName = cfg.networking.hostname;
networking.wireless.iwd.enable = true;
networking.wireless.iwd.settings.General.EnableNetworkConfiguration = true;
systemd.network.networks = builtins.mapAttrs (name: cfg: {
matchConfig.Name = cfg.match;
networkConfig.DHCP = "yes";
linkConfig.RequiredForOnline = if cfg.isRequired then "yes" else "no";
}) cfg.networking.networks;
systemd.network.networks = builtins.mapAttrs
(name: cfg: {
matchConfig.Name = cfg.match;
networkConfig.DHCP = "yes";
linkConfig.RequiredForOnline = if cfg.isRequired then "yes" else "no";
})
cfg.networking.networks;
# Leave DNS to systemd-resolved
services.resolved.enable = true;
services.resolved.domains = cfg.networking.dnsServers;
@ -357,44 +246,24 @@ in
# Firewall: only open to SSH now
networking.firewall.allowedTCPPorts = [ 22 ];
networking.firewall.allowedUDPPorts = [ 22 ];
# Network namespaces management
systemd.services."netns@" = {
description = "Network namespace %I";
before = [ "network.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${pkgs.iproute2}/bin/ip netns add %I";
ExecStop = "${pkgs.iproute2}/bin/ip netns del %I";
};
};
# Enable tailscale
services.tailscale.enable = true;
## Time and Region
time.timeZone = lib.mkDefault "Europe/Zurich";
time.timeZone = "Europe/Zurich";
# Select internationalisation properties.
console.keyMap = "jp106"; # Console key layout
i18n.defaultLocale = "ja_JP.UTF-8";
# Input methods (only fcitx5 works reliably on Wayland)
i18n.inputMethod =
{
fcitx5.waylandFrontend = true;
fcitx5.addons = with pkgs; [
fcitx5-mozc
fcitx5-unikey
fcitx5-gtk
];
}
// (
if config.system.nixos.release == "24.05" then
{
enabled = "fcitx5";
}
else
{
enable = true;
type = "fcitx5";
}
);
i18n.inputMethod = {
enabled = "fcitx5";
fcitx5.waylandFrontend = true;
fcitx5.addons = with pkgs; [
fcitx5-mozc
fcitx5-unikey
fcitx5-gtk
];
};
# Default packages
environment.systemPackages = with pkgs; [
@ -420,23 +289,12 @@ in
programs.kdeconnect.enable = true;
# Flatpaks are useful... sometimes...
services.flatpak.enable = true;
# AppImages should run
programs.appimage = {
enable = true;
binfmt = true;
};
# DConf for GNOME configurations
programs.dconf.enable = true;
# Gaming! (not for ARM64)
programs.steam.enable = true;
programs.gamescope = {
enable = true;
# capSysNice = true; # https://github.com/NixOS/nixpkgs/issues/351516
args = [
"--adaptive-sync"
"--rt"
];
};
programs.steam.enable = !pkgs.stdenv.isAarch64;
hardware.opengl.enable = true;
hardware.opengl.driSupport32Bit = !pkgs.stdenv.isAarch64; # For 32 bit applications
## Services
# OpenSSH so you can SSH to me
@ -453,28 +311,9 @@ in
wlr.enable = true;
xdgOpenUsePortal = true;
# gtk portal needed to make gtk apps happy
extraPortals = [
pkgs.kdePackages.xdg-desktop-portal-kde
pkgs.xdg-desktop-portal-gtk
];
extraPortals = [ pkgs.kdePackages.xdg-desktop-portal-kde pkgs.xdg-desktop-portal-gtk ];
config.sway.default = [
"wlr"
"kde"
"kwallet"
];
config.niri = {
default = [
"kde"
"gnome"
"gtk"
];
# "org.freedesktop.impl.portal.Access" = "gtk";
# "org.freedesktop.impl.portal.Notification" = "gtk";
"org.freedesktop.impl.portal.ScreenCast" = "gnome";
"org.freedesktop.impl.portal.Secret" = "kwallet";
"org.freedesktop.impl.portal.FileChooser" = "kde";
};
config.sway.default = [ "wlr" "kde" "kwallet" ];
};
# D-Bus
services.dbus.packages = with pkgs; [ gcr ];

View file

@ -1,18 +0,0 @@
{ config, lib, ... }:
with { inherit (lib) types mkOption mkEnableOption; };
let
cfg = config.common.linux.sops;
in
{
options.common.linux.sops = {
enable = mkEnableOption "Enable sops configuration";
file = mkOption {
type = types.path;
description = "Path to the default sops file";
};
};
config = lib.mkIf cfg.enable {
sops.defaultSopsFile = cfg.file;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
};
}

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib;
let
@ -39,91 +34,75 @@ in
default = 655;
description = "The port to listen on";
};
meshIp = mkOption {
type = types.str;
description = "The mesh ip to be assigned by hostname";
};
};
config = mkIf cfg.enable (
builtins.seq
(mkIf (isNull cfg.rsaPrivateKey && isNull cfg.ed25519PrivateKey) (
builtins.abort "one of the keys must be defined"
))
(
let
networkName = "my-tinc";
config = mkIf cfg.enable (builtins.seq
(mkIf (isNull cfg.rsaPrivateKey && isNull cfg.ed25519PrivateKey) (builtins.abort "one of the keys must be defined"))
(
let
networkName = "my-tinc";
myHost = builtins.getAttr cfg.hostName hosts;
myMeshIp = myHost.subnetAddr;
in
{
# Scripts that set up the tinc services
environment.etc = {
"tinc/${networkName}/tinc-up".source = pkgs.writeScript "tinc-up-${networkName}" ''
#!${pkgs.stdenv.shell}
${pkgs.nettools}/bin/ifconfig $INTERFACE ${myMeshIp} netmask 255.255.255.0
'';
"tinc/${networkName}/tinc-down".source = pkgs.writeScript "tinc-down-${networkName}" ''
#!${pkgs.stdenv.shell}
/run/wrappers/bin/sudo ${pkgs.nettools}/bin/ifconfig $INTERFACE down
'';
};
myHost = builtins.getAttr cfg.hostName hosts;
myMeshIp = myHost.subnetAddr;
in
{
services.my-tinc.meshIp = myMeshIp;
# Scripts that set up the tinc services
environment.etc = {
"tinc/${networkName}/tinc-up".source = pkgs.writeScript "tinc-up-${networkName}" ''
#!${pkgs.stdenv.shell}
${pkgs.nettools}/bin/ifconfig $INTERFACE ${myMeshIp} netmask 255.255.255.0
'';
"tinc/${networkName}/tinc-down".source = pkgs.writeScript "tinc-down-${networkName}" ''
#!${pkgs.stdenv.shell}
/run/wrappers/bin/sudo ${pkgs.nettools}/bin/ifconfig $INTERFACE down
'';
};
# Allow the tinc service to call ifconfig without sudo password.
security.sudo.extraRules = [
{
users = [ "tinc.${networkName}" ];
commands = [
{
command = "${pkgs.nettools}/bin/ifconfig";
options = [ "NOPASSWD" ];
}
];
}
];
# simple interface setup
# ----------------------
networking.interfaces."tinc.${networkName}".ipv4.addresses = [
{
address = myMeshIp;
prefixLength = 24;
}
];
# firewall
networking.firewall.allowedUDPPorts = [ 655 ];
networking.firewall.allowedTCPPorts = [ 655 ];
networking.firewall.interfaces."tinc.${networkName}" = {
allowedUDPPortRanges = [
# Allow the tinc service to call ifconfig without sudo password.
security.sudo.extraRules = [
{
users = [ "tinc.${networkName}" ];
commands = [
{
from = 0;
to = 65535;
command = "${pkgs.nettools}/bin/ifconfig";
options = [ "NOPASSWD" ];
}
];
allowedTCPPortRanges = [
{
from = 0;
to = 65535;
}
];
};
}
];
# configure tinc service
# ----------------------
services.tinc.networks."${networkName}" = {
# simple interface setup
# ----------------------
networking.interfaces."tinc.${networkName}".ipv4.addresses = [{ address = myMeshIp; prefixLength = 24; }];
name = cfg.hostName; # who are we in this network.
# firewall
networking.firewall.allowedUDPPorts = [ 655 ];
networking.firewall.allowedTCPPorts = [ 655 ];
debugLevel = 3; # the debug level for journal -u tinc.private
chroot = false; # otherwise addresses can't be a DNS
interfaceType = "tap"; # tun might also work.
# configure tinc service
# ----------------------
services.tinc.networks."${networkName}" = {
bindToAddress = "* ${toString cfg.bindPort}";
name = cfg.hostName; # who are we in this network.
ed25519PrivateKeyFile = cfg.ed25519PrivateKey;
rsaPrivateKeyFile = cfg.rsaPrivateKey;
debugLevel = 3; # the debug level for journal -u tinc.private
chroot = false; # otherwise addresses can't be a DNS
interfaceType = "tap"; # tun might also work.
settings.ExperimentalProtocol = "yes";
};
}
)
bindToAddress = "* ${toString cfg.bindPort}";
ed25519PrivateKeyFile = cfg.ed25519PrivateKey;
rsaPrivateKeyFile = cfg.rsaPrivateKey;
settings.ExperimentalProtocol = "yes";
};
}
)
);
}

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib;
let
@ -11,34 +6,27 @@ let
cfg = config.services.my-tinc;
mapAttrs =
f: attrs:
builtins.listToAttrs (
map (name: {
inherit name;
value = f name (builtins.getAttr name attrs);
}) (builtins.attrNames attrs)
);
mapAttrs = f: attrs: builtins.listToAttrs (
map (name: { inherit name; value = f name (builtins.getAttr name attrs); }) (builtins.attrNames attrs)
);
in
{
config = mkIf cfg.enable {
# All hosts we know of
services.tinc.networks.my-tinc.hostSettings = mapAttrs (name: host: {
addresses = if (host ? address) then [ { address = host.address; } ] else [ ];
subnets = [ { address = host.subnetAddr; } ];
rsaPublicKey = mkIf (host ? "rsaPublicKey") host.rsaPublicKey;
settings.Ed25519PublicKey = mkIf (host ? "ed25519PublicKey") host.ed25519PublicKey;
}) hosts;
services.tinc.networks.my-tinc.hostSettings = mapAttrs
(name: host: {
addresses = if (host ? address) then [{ address = host.address; }] else [ ];
subnets = [{ address = host.subnetAddr; }];
rsaPublicKey = mkIf (host ? "rsaPublicKey") host.rsaPublicKey;
settings.Ed25519PublicKey = mkIf (host ? "ed25519PublicKey") host.ed25519PublicKey;
})
hosts;
# Add all of them to host
nki.services.edns = {
enable = true;
cloaking-rules = (
lib.attrsets.mapAttrs' (name: host: {
name = "${name}.tinc";
value = host.subnetAddr;
}) hosts
);
};
networking.extraHosts = lib.strings.concatStringsSep
"\n"
(lib.attrsets.mapAttrsToList
(name: host: "${host.subnetAddr} ${name}.tinc")
hosts);
};
}

View file

@ -12,24 +12,4 @@
rsaPublicKey = builtins.readFile ./nki-home.pub;
ed25519PublicKey = "Ts5OdPtBNLIRfosoYRcb6Z2iwWyOz/VKTKB9J0p5LlH";
};
macbook = {
subnetAddr = "11.0.0.3";
rsaPublicKey = builtins.readFile ./nki-macbook.pub;
ed25519PublicKey = "lkNkBTl5GmcQFrtA7F1nN2gq5gFK7KuGqHUN8fiJU7H";
};
macbooknix = {
subnetAddr = "11.0.0.4";
ed25519PublicKey = "6MN5LVE4juavv8qJW2dTN4t/haKCADWquAQj/ADF7iN";
};
yoga = {
subnetAddr = "11.0.0.5";
ed25519PublicKey = "n+gIZjuuTPxi0OBqw2oOcmXd3loOHG+GQHBMXNlgyqI";
};
framework = {
subnetAddr = "11.0.0.6";
ed25519PublicKey = "YL7NA6Ydv/3FBfSzOPvyHlGweAViPvsG3b0Zh8L0NzF";
};
}

View file

@ -1,25 +0,0 @@
-----BEGIN RSA PUBLIC KEY-----
MIIECgKCBAEArruSM+4etKvZ2dWeBP8nA1lQeY/T3gBD7JMdHqG/BlEmEkEW2jrq
1UpABXEh5MyZ2ekSG5xr9awmVdybxauC0NPiDGxfknctS4F23asK0q5XjcnPtnln
cBhq7RPKdX1oGDyWrL4pVHOX+6cRZ6IsQemxfXlm3chl/5ore9b728wrU/FpkBBL
5gnzI3vtPWlBhrGxQOVobdLI4EYtFfbXV/IOqoe+5po8iYCliUQGF88R0V57YYpK
YXjuVtANMvoRsT5N7OJgoLjGeHEVXB0Umjfci+gbt+u+bKt0eBODFsawFWJCxxpY
cgbHtAViHZLSL5MTOlSBaW6tKsR/LrDUOCKu27Ccf7ZGG6U3O32ZI95+rsmuo+y7
DicZuW/YnvLomy+/XxzBvMYhDgQAMrOZTzCj6fjyie3FsdUHB2ydUhAkpvQMgBZM
6m0F5kancKNXaSXv82AaJrEclqo3DjAAtOy8jS/t7JyjwUh6LdKjjt68dmbq8weK
y9IZxQun/X+fEK4W2YVxm/nftJSPv/j1qsxakzuSHOAeQggLiOIcJi2aMftrfJJS
9DNqoDHy1cf0I9hH6VLcwx+fk4RkDdr7+SupKjFmhSz0ZlL80uc3I4yJg+cN+4rW
E5HFS+nxDQ1fwbH/pC5fXgvNTyepzqs+zTOKCjzezqGP4fgfCTODt6uXpuc52smY
agUfYd5fOW+RLrAP/Z1vvFBI26RBrOpfIFYEgAsRfx5iHI/SUxu3FDSl+cewiQ3k
AIvD+wGEpTI64nZr7sgF/rUR5mTrS51+3eWm9SHLF9R5hYHHe2HWILBvNu9YLQdI
pQmNmu4H32/gNP8HnSm8I1zDChB84o+FnjyZ0EhTDOdg6BemssvoWnuQ+CoUsmyZ
lB+A8bUIaFYaGtx46ESdSzHJVWV25P6vVgXbqS2OqC2Slkc8RWYKfoHLvJg28zT0
A5naep3YWymXXhzsUXeEuyc68GZvF8BFV13XTiiULy3ZCjlBGA9xZoc4lLKdKXNk
Y/q908RHu2BUB3z6eeVKGDCGD9E/jiK+NpBWtrPmuBNTz4cC2cbjhx17j7dLF/wa
JY2iCeRCfNhTkE7oP9uWf5nUrUU/DlUdz4DC6JNHeo2hmLNjNQLBx+2ExtAdcF1g
4WhDnuKtrMTedRqwQLVE7FNW9iwBDpCQlmGkg+JE0+qdQBaoKDco/l2npSVVWjCU
5eeB+xCZd25gPFDUQtGYt6Pux/6E0+3wLr2flGODfYHEGLsGlUIisIEs2WrISxcd
5bSDrFh23GUsOZdruUA1GDgXu5+DUFhEriZDDWYzl5Zf83qqLgYP/RZuX5VWQ8Ge
PGw+fTnj/IneKgrhg8YgZCmK9j4hh+KMPwIDAQAB
-----END RSA PUBLIC KEY-----

View file

@ -1,91 +1,49 @@
{
pkgs,
lib,
config,
...
}:
{ pkgs, lib, ... }:
with lib;
let
nerd-fonts =
if builtins.hasAttr "nerd-fonts" pkgs then
pkgs.nerd-fonts.symbols-only
else
pkgs.nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; };
in
{
imports = [ ./mounting.nix ];
# Fonts
config.fonts =
{
packages =
with pkgs;
mkForce [
noto-fonts-emoji-blob-bin
ibm-plex
nerd-fonts
noto-fonts
(pkgs.noto-fonts-cjk-sans or pkgs.noto-fonts-cjk)
merriweather
corefonts
font-awesome
hack-font # for Plasma
];
}
// (
if pkgs.stdenv.isLinux then
{
enableDefaultPackages = false;
fontconfig = {
defaultFonts = {
emoji = lib.mkBefore [ "Blobmoji" ];
serif = lib.mkBefore [
"IBM Plex Serif"
"IBM Plex Sans JP"
"IBM Plex Sans KR"
"Blobmoji"
];
sansSerif = lib.mkBefore [
"IBM Plex Sans"
"IBM Plex Sans JP"
"IBM Plex Sans KR"
"Blobmoji"
];
monospace = lib.mkBefore [
"IBM Plex Mono"
"Font Awesome 6 Free"
"Symbols Nerd Font"
"Blobmoji"
"IBM Plex Sans JP"
];
};
localConf = ''
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
<alias binding="same">
<family>system-ui</family>
<prefer>
<family>IBM Plex Sans</family>
<family>IBM Plex Sans JP</family>
<family>IBM Plex Sans KR</family>
<family>Blobmoji</family>
</prefer>
</alias>
</fontconfig>
'';
};
fontDir.enable = true;
}
else
{ }
)
// (
if pkgs.stdenv.isDarwin then
{
fontDir.enable = true;
}
else
{ }
);
config.fonts = {
packages = with pkgs; mkForce [
noto-fonts-emoji-blob-bin
ibm-plex
(nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; })
noto-fonts
noto-fonts-cjk
merriweather
corefonts
font-awesome
hack-font # for Plasma
];
} // (if pkgs.stdenv.isLinux then {
enableDefaultPackages = false;
fontconfig = {
defaultFonts = {
emoji = lib.mkBefore [ "Blobmoji" ];
serif = lib.mkBefore [ "IBM Plex Serif" "IBM Plex Sans JP" "IBM Plex Sans KR" "Blobmoji" ];
sansSerif = lib.mkBefore [ "IBM Plex Sans" "IBM Plex Sans JP" "IBM Plex Sans KR" "Blobmoji" ];
monospace = lib.mkBefore [ "IBM Plex Mono" "Font Awesome 6 Free" "Symbols Nerd Font" "Blobmoji" "IBM Plex Sans JP" ];
};
localConf = ''
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
<alias binding="same">
<family>system-ui</family>
<prefer>
<family>IBM Plex Sans</family>
<family>IBM Plex Sans JP</family>
<family>IBM Plex Sans KR</family>
<family>Blobmoji</family>
</prefer>
</alias>
</fontconfig>
'';
};
fontDir.enable = true;
} else { }) // (if pkgs.stdenv.isDarwin then {
fontDir.enable = true;
} else { });
}

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
lib.mkIf pkgs.stdenv.isLinux {
system.fsPackages = [ pkgs.bindfs ];
fileSystems =
@ -11,17 +6,13 @@ lib.mkIf pkgs.stdenv.isLinux {
mkRoSymBind = path: {
device = path;
fsType = "fuse.bindfs";
options = [
"ro"
"resolve-symlinks"
"x-gvfs-hide"
];
options = [ "ro" "resolve-symlinks" "x-gvfs-hide" ];
};
aggregatedIcons = pkgs.buildEnv {
name = "system-icons";
paths = with pkgs; [
#libsForQt5.breeze-qt5 # for plasma
(pkgs.gnome-themes-extra or gnome.gnome-themes-extra) # Until 24.11
gnome.gnome-themes-extra
];
pathsToLink = [ "/share/icons" ];
};

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib;
let
@ -21,7 +16,7 @@ in
security.pam = mkIf pkgs.stdenv.isLinux {
u2f = {
enable = true;
settings.cue = true;
cue = true;
};
# Services

View file

@ -1,9 +1,4 @@
{
pkgs,
config,
lib,
...
}:
{ pkgs, config, lib, ... }:
with lib;
let
@ -13,11 +8,6 @@ in
options.nki.services.edns = {
enable = mkEnableOption "Enable encrypted DNS";
ipv6 = mkEnableOption "Enable ipv6";
cloaking-rules = mkOption {
type = types.attrsOf types.str;
default = { };
description = "A set of domain -> ip mapping for cloaking_rules";
};
};
config = mkIf cfg.enable {
@ -39,10 +29,7 @@ in
# Sources
sources.public_resolvers = {
urls = [
"https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md"
"https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md"
];
urls = [ "https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md" "https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md" ];
cache_file = "/var/lib/dnscrypt-proxy/public_resolvers.md";
minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
};
@ -52,22 +39,9 @@ in
# Anonymized DNS
anonymized_dns.routes = [
{
server_name = "*";
via = [
"anon-plan9-dns"
"anon-v.dnscrypt.up-ipv4"
];
}
{ server_name = "*"; via = [ "anon-plan9-dns" "anon-v.dnscrypt.up-ipv4" ]; }
];
anonymized_dns.skip_incompatible = true;
# Cloaking rules
cloaking_rules = pkgs.writeText "cloaking_rules.txt" (
lib.strings.concatStringsSep "\n" (
lib.attrsets.mapAttrsToList (name: ip: "${name} ${ip}") cfg.cloaking-rules
)
);
};
};
};

View file

@ -1,68 +0,0 @@
{ config, lib, ... }:
with { inherit (lib) mkOption types mkIf; };
let
cfg = config.services.nix-build-farm;
hosts = import ./hosts.nix;
build-user = "nix-builder";
isBuilder = host: host ? "builder";
allBuilders = lib.filterAttrs (_: isBuilder) hosts;
in
{
options.services.nix-build-farm = {
enable = mkOption {
type = types.bool;
default = true;
description = "Whether to enable nix-build-farm as a client";
};
hostname = mkOption {
type = types.enum (builtins.attrNames hosts);
description = "The hostname as listed in ./hosts.nix file";
};
privateKeyFile = mkOption {
type = types.path;
description = "The path to the private SSH key file";
};
ipAddrs = mkOption {
type = types.str;
description = "The ip addresses to limit access to";
default = "11.0.0.*";
};
};
config = mkIf cfg.enable (
let
host = hosts.${cfg.hostname};
otherHosts = lib.filterAttrs (name: _: name != cfg.hostname) hosts;
otherBuilders = lib.filterAttrs (name: _: name != cfg.hostname) allBuilders;
in
{
nix.distributedBuilds = true;
nix.buildMachines = lib.mapAttrsToList (
name: host:
{
hostName = host.host;
sshUser = build-user;
sshKey = cfg.privateKeyFile;
}
// host.builder
) otherBuilders;
users = mkIf (isBuilder host) {
users.${build-user} = {
description = "Nix build farm user";
group = build-user;
isNormalUser = true;
openssh.authorizedKeys.keys = lib.mapAttrsToList (
_: host: ''from="${cfg.ipAddrs}" ${host.pubKey}''
) otherHosts;
};
groups.${build-user} = { };
};
nix.settings.trusted-users = mkIf (isBuilder host) [ build-user ];
}
);
}

View file

@ -1,53 +0,0 @@
{
cloud = {
host = "cloud.tinc";
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE87ddj0fTH0NuvJz0dT5ln7v7zbafXqDVdM2A4ddOb0 root@nki-personal-do";
};
home = {
host = "home.tinc";
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK6N1uTxnbo73tyzD9X7d7OgPeoOpY7JmQaHASjSWFPI nki@kagamiPC";
builder = {
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUhiVTh2NlNBa0kyOTBCc1QzVG1IRVVJQWdXcVFyNm9jRmpjakRRczRoT2ggcm9vdEBrYWdhbWlQQwo=";
systems = [
"x86_64-linux"
"aarch64-linux"
];
maxJobs = 16;
speedFactor = 2;
supportedFeatures = [
"nixos-test"
"benchmark"
"big-parallel"
"kvm"
];
};
};
yoga = {
host = "yoga.tinc";
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE6ZrO/xIdmwBCUx80cscBSpJBBTp55OHGrXYBGRXKAw nki@nki-yoga-g8";
};
framework = {
host = "framework.tinc";
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH/g472MaT7YySUhBjxClfmMjpn98qYnKXDKlzWHYwuO nki@nki-framework";
builder = {
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUdOUlBCVFRkNTVVMXY1U1Jac0FjYVdhS3JGZTY0ZjIxOVViODVTQ2NWd28gcm9vdEBua2ktZnJhbWV3b3JrCg==";
systems = [
"x86_64-linux"
"aarch64-linux"
];
maxJobs = 16;
speedFactor = 3;
supportedFeatures = [
"nixos-test"
"benchmark"
"big-parallel"
"kvm"
];
};
};
}

View file

@ -1 +0,0 @@
nix.home.tinc:zG2uDy0MbLY0wLuoVH/qKzTD6hTfKZufA2cWDSTCZMA=

View file

@ -1,72 +0,0 @@
{
config,
pkgs,
lib,
...
}:
with {
inherit (lib)
mkEnableOption
mkOption
types
mkIf
;
};
let
cfg = config.nki.services.nix-cache;
bindAddr = "127.0.0.1:5000";
in
{
options.nki.services.nix-cache = {
enableClient = mkOption {
type = types.bool;
default = !cfg.enableServer;
description = "Enable nix-cache client";
};
enableServer = mkEnableOption "Enable nix-cache server";
host = mkOption {
type = types.str;
default = "nix.home.tinc";
};
publicKey = mkOption {
type = types.str;
default = builtins.readFile ./cache-pub-key.pem;
};
privateKeyFile = mkOption {
type = types.path;
description = "Path to the private key .pem file";
};
};
config = {
nix.settings = mkIf cfg.enableClient {
substituters = lib.mkAfter [ "http://${cfg.host}" ];
trusted-public-keys = [ cfg.publicKey ];
};
services.harmonia = mkIf cfg.enableServer {
enable = true;
signKeyPaths = [ cfg.privateKeyFile ];
settings = {
bind = bindAddr;
priority = 45;
};
};
services.nginx = mkIf cfg.enableServer {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
# ... existing hosts config etc. ...
"${cfg.host}" = {
locations."/".proxyPass = "http://${bindAddr}";
};
};
};
};
}

View file

@ -1,9 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.swaylock;

View file

@ -2,39 +2,25 @@
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
{
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
# Fonts
../modules/personal/fonts
# Encrypted DNS
../modules/services/edns
# Wireless card
./wireless.nix
];
# Sops
common.linux.sops.enable = true;
common.linux.sops.file = ./secrets.yaml;
sops.secrets."nix-build-farm/private-key" = {
mode = "0400";
};
services.nix-build-farm.hostname = "framework";
services.nix-build-farm.privateKeyFile = config.sops.secrets."nix-build-farm/private-key".path;
imports =
[
# Include the results of the hardware scan.
./hardware-configuration.nix
# Fonts
../modules/personal/fonts
# Encrypted DNS
../modules/services/edns
# Wireless card
./wireless.nix
];
# services.xserver.enable = true;
# services.xserver.displayManager.sddm.enable = true;
# services.xserver.displayManager.sddm.wayland.enable = true;
services.desktopManager.plasma6.enable = true;
services.xserver.desktopManager.plasma6.enable = true;
# Power Management
services.upower = {
@ -48,13 +34,13 @@
services.power-profiles-daemon.enable = true;
# powerManagement.enable = true;
# powerManagement.powertop.enable = true;
services.logind.lidSwitch = "suspend-then-hibernate";
services.logind.lidSwitch = "suspend";
# Printing
services.printing.drivers = with pkgs; [ epfl-cups-drivers ];
# Enable touchpad support (enabled default in most desktopManager).
services.libinput.enable = true;
services.xserver.libinput.enable = true;
# Keyboard
services.input-remapper.enable = true;
services.input-remapper.serviceWantedBy = [ "multi-user.target" ];
@ -91,15 +77,6 @@
security.pam.services.swaylock.fprintAuth = true;
security.pam.services.login.fprintAuth = true;
# tinc network
sops.secrets."tinc-private-key" = { };
services.my-tinc = {
enable = true;
hostName = "framework";
ed25519PrivateKey = config.sops.secrets."tinc-private-key".path;
bindPort = 6565;
};
# Secrets
# sops.defaultSopsFile = ./secrets.yaml;
# sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
@ -115,9 +92,6 @@
services.dbus.packages = with pkgs; [ gcr ];
services.avahi.enable = true;
networking.firewall.allowedTCPPorts = [ 8010 ];
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
@ -137,3 +111,4 @@
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.05"; # Did you read the comment?
}

View file

@ -1,42 +1,32 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
imports =
[
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [
"nvme"
"xhci_pci"
"thunderbolt"
"usb_storage"
"sd_mod"
];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
boot.kernelParams = [
# See https://community.frame.work/t/tracking-graphical-corruption-in-fedora-39-amd-3-03-bios/39073/143
"amdgpu.sg_display=0"
# Hibernation
"resume=UUID=fa8aaf51-b99f-4fb4-9230-8c0957d8af3f"
"resume_offset=5776640" # btrfs inspect-internal map-swapfile -r /var/swapfile
];
fileSystems."/" = {
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
fsType = "btrfs";
options = [
"subvol=root"
"compress=zstd"
];
};
fileSystems."/" =
{
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
fsType = "btrfs";
options = [ "subvol=root" "compress=zstd" ];
};
services.btrfs.autoScrub = {
enable = true;
interval = "monthly";
@ -44,35 +34,28 @@
common.linux.luksDevices."cryptroot" = "/dev/disk/by-uuid/94226aae-6d1c-401a-bfad-3aa5f371a365";
fileSystems."/home" = {
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
fsType = "btrfs";
options = [
"subvol=home"
"compress=zstd"
];
};
fileSystems."/home" =
{
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
fsType = "btrfs";
options = [ "subvol=home" "compress=zstd" ];
};
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
fsType = "btrfs";
options = [
"subvol=nix"
"compress=zstd"
];
};
fileSystems."/nix" =
{
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
fsType = "btrfs";
options = [ "subvol=nix" "compress=zstd" ];
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/6A0E-4D23";
fsType = "vfat";
};
fileSystems."/boot" =
{
device = "/dev/disk/by-uuid/6A0E-4D23";
fsType = "vfat";
};
swapDevices = [
{
device = "/var/swapfile";
size = 32 * 1024;
priority = 10;
}
{ device = "/var/swapfile"; size = 32 * 1024; priority = 10; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking

View file

@ -1,32 +0,0 @@
tinc-private-key: ENC[AES256_GCM,data:cKtOFrF5FRSHWxe/QxH5O9GAba1WcWeCwW1IOzmbgdtFufRoWbCtYeaLP+WQhQ70z6xobiY9DN8Jrh7mDptKSsfKrrx2SH5JrdpsoINhLMbetXq7E29+q6CkS8NlLgE/KyV8eFjQySNsYiA/+Efq9xj9e1wOmHBDsND/jgiJDkA1qsEIFZg/vuv8LdoRY3TV/oKJ4pao9+70G4H+8Ef1sMZHGNe9qJ94Wa71nNX2fTSjKH5YBbRijMAePWr/IeCpZ9Phs7RqjBs=,iv:l0iB136X7nLVblQjFi7K4f42JKSxdsiLIRy5GPzK1nc=,tag:HAgkvWkl0Rx62ejGZckdKA==,type:str]
nix-build-farm:
private-key: ENC[AES256_GCM,data:w56sobHrhvVcKbuK15Yj20EqgFrR/5pNy/rcQjlZCiFEfgPC6ZrbsxziIdMTOX+Q4DyllKCKo+g/MIKm5S+s+nIff509ODlILhTtXlZvZlnT9+wvm5oN3WQCdkkqOr1gNnErPupfMxA6V35tNvNBCeomYuM8Xb7TuH4I1fXa5GFeT0Tnp5A2WqWoS1MzXz34CxlKXvoL6i4w7nUngt5zaGr9oMZbSa0pHxEzIhXk6h/lE864QlJid7q/mDok9gh2R80WvArGtNNj9PrT6cNKYIFuXo7vITkSkT3vo9BLflg5sgRxy4+7rBaRla0ziihQvZLtworwo6aNDvEqPqYfiX0TMYPpEWvJpp/HGDJy+Po7b0ZZkwSza+tB0J79vFH2h11Px1XSwXdq757Bn9G4OTb5oKWS5ycBU4xTnnHQBjYTSooFxYyTAvfKNEsB8AHKSuQRZgtVhWoOSPpJ6YL94ClUIT+DTaNmQjwouqNatf/nif+N/FCar8JWZDE+FX1TBu0yLmJie/f0LCdCQx+6IVdyXg7oVCoNiGg0,iv:TeSxlVc0WlOMMUtv/uq3f7JvW/kNCM7LjguhZxL51a4=,tag:m1iuk4pAX/yugM0ObzkJHQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age188tgu3psvywk6shq85mk2q0jdjwd0tcswzwlwu5pa5n3pndx75dq090z59
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmL2Z1RzBWaTI1TDl6WDNa
NTNVdEhTSFU5enNlTGVNWTI5anBZb1BtaVhjCm1BRnJDSXl1cWdBRUs1VnREVjBU
QWZxdkgzdm9JL0k5WmhDL1RCNTltdm8KLS0tIFhvQTlKMDZiVklTRWd4TzVmc2ll
bmpjcWdBV1doZml2NjlzQzdQczJ3alEKBMRP3POxtPIqBWnrvxY/++5jtVE70Uxa
EVfhsUO76A/hzyxfzpLEy1QGFE+DB/zlU0CK7HkNGPD2TrBHbzkPJA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1vgh6kvee8lvxylm7z86fpl3xzjyjs4u3zdfkyf064rjvxk9fpumsew7n27
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2MUxQU0dZOGRaekF4MWdo
T0krcERtRTJndFR1RHZmL0t6MjBxMW5PSENNCkR6SUhxQ0FoaEhuaWpiUzJ0MnJE
RXRERzVhL0lRVW1iRUlac0c5OHZsckEKLS0tIC9VM1dNZTNzdkFnMWk2YUwvcDNB
TDZnVjBaVzZBem5lZDB1MW4xQ0RmZ28K6d7mF+f3ZyilXlSIQGT2pBrTWuYLccE1
rYIJjHjFft/2wPX2gAW9VTiwfMT3lKJhJRqNdoie5phV5BZhkb3D9w==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-08-17T14:58:10Z"
mac: ENC[AES256_GCM,data:ZCrzXDttLxYUvdLiqM5I17Ys6O3zoOVKq8xP78VaLb3AAoV4RGGQxixKVQ6K9h84e8bFymh512BR7xKa9fqebxTyL1XCqPkRaSZy0aWjbc6QCaK+JD4yqivgO/x5x2xgMpX/ZhPFzKNLpMga61bnm6plvF8ocG+wOqYvj3vL0Ss=,iv:QZ8YJD7h2QD2jqVKo4bg0rwpZSTyyNw6zZDcBfClKPo=,tag:PH2XnTqxV2irymg2+Z+Egg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.0

View file

@ -1,5 +1,4 @@
{ pkgs, lib, ... }:
{
{ pkgs, lib, ... }: {
environment.systemPackages = with pkgs; [ iw ];
# Disable power_save on boot
services.udev.packages = [

View file

@ -1,11 +1,5 @@
{
config,
pkgs,
lib,
...
}:
{
{ config, pkgs, lib, ... }: {
environment.etc = {
"wireplumber/wireplumber.conf.d/51-sdac.conf".source = ./sdac.conf.json;
"wireplumber/main.lua.d/51-sdac.lua".source = ./sdac.lua;
};
}

View file

@ -1,19 +0,0 @@
monitor.alsa.rules = [
{
matches = [
{
device.name = "alsa_output.usb-Grace_Design_SDAC-00.*"
}
]
actions = {
update-props = {
# audio.format = "S24_3LE"
audio.rate = 88200
api.alsa.period-size = 2
api.alsa.headroom = 0
api.alsa.disable-batch = true
}
}
}
]

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