format
This commit is contained in:
97
flake.nix
97
flake.nix
@@ -32,28 +32,55 @@
|
|||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
outputs = { self, darwin, nix-homebrew, homebrew-bundle, homebrew-core, homebrew-cask, home-manager, nixpkgs, disko, agenix, secrets } @inputs:
|
outputs =
|
||||||
|
{
|
||||||
|
self,
|
||||||
|
darwin,
|
||||||
|
nix-homebrew,
|
||||||
|
homebrew-bundle,
|
||||||
|
homebrew-core,
|
||||||
|
homebrew-cask,
|
||||||
|
home-manager,
|
||||||
|
nixpkgs,
|
||||||
|
disko,
|
||||||
|
agenix,
|
||||||
|
secrets,
|
||||||
|
}@inputs:
|
||||||
let
|
let
|
||||||
user = "cschmatzler";
|
user = "cschmatzler";
|
||||||
linuxSystems = [ "x86_64-linux" ];
|
linuxSystems = [ "x86_64-linux" ];
|
||||||
darwinSystems = [ "aarch64-darwin" ];
|
darwinSystems = [ "aarch64-darwin" ];
|
||||||
forAllSystems = f: nixpkgs.lib.genAttrs (linuxSystems ++ darwinSystems) f;
|
forAllSystems = f: nixpkgs.lib.genAttrs (linuxSystems ++ darwinSystems) f;
|
||||||
devShell = system: let pkgs = nixpkgs.legacyPackages.${system}; in {
|
devShell =
|
||||||
default = with pkgs; mkShell {
|
system:
|
||||||
nativeBuildInputs = with pkgs; [ bashInteractive git age age-plugin-yubikey ];
|
let
|
||||||
shellHook = with pkgs; ''
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
export EDITOR=vim
|
in
|
||||||
'';
|
{
|
||||||
|
default =
|
||||||
|
with pkgs;
|
||||||
|
mkShell {
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
bashInteractive
|
||||||
|
git
|
||||||
|
age
|
||||||
|
age-plugin-yubikey
|
||||||
|
];
|
||||||
|
shellHook = with pkgs; ''
|
||||||
|
export EDITOR=vim
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
mkApp = scriptName: system: {
|
mkApp = scriptName: system: {
|
||||||
type = "app";
|
type = "app";
|
||||||
program = "${(nixpkgs.legacyPackages.${system}.writeScriptBin scriptName ''
|
program = "${
|
||||||
#!/usr/bin/env bash
|
(nixpkgs.legacyPackages.${system}.writeScriptBin scriptName ''
|
||||||
PATH=${nixpkgs.legacyPackages.${system}.git}/bin:$PATH
|
#!/usr/bin/env bash
|
||||||
echo "Running ${scriptName} for ${system}"
|
PATH=${nixpkgs.legacyPackages.${system}.git}/bin:$PATH
|
||||||
exec ${self}/apps/${system}/${scriptName}
|
echo "Running ${scriptName} for ${system}"
|
||||||
'')}/bin/${scriptName}";
|
exec ${self}/apps/${system}/${scriptName}
|
||||||
|
'')
|
||||||
|
}/bin/${scriptName}";
|
||||||
};
|
};
|
||||||
mkLinuxApps = system: {
|
mkLinuxApps = system: {
|
||||||
"apply" = mkApp "apply" system;
|
"apply" = mkApp "apply" system;
|
||||||
@@ -76,9 +103,11 @@
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
devShells = forAllSystems devShell;
|
devShells = forAllSystems devShell;
|
||||||
apps = nixpkgs.lib.genAttrs linuxSystems mkLinuxApps // nixpkgs.lib.genAttrs darwinSystems mkDarwinApps;
|
apps =
|
||||||
|
nixpkgs.lib.genAttrs linuxSystems mkLinuxApps // nixpkgs.lib.genAttrs darwinSystems mkDarwinApps;
|
||||||
|
|
||||||
darwinConfigurations = nixpkgs.lib.genAttrs darwinSystems (system:
|
darwinConfigurations = nixpkgs.lib.genAttrs darwinSystems (
|
||||||
|
system:
|
||||||
darwin.lib.darwinSystem {
|
darwin.lib.darwinSystem {
|
||||||
inherit system;
|
inherit system;
|
||||||
specialArgs = inputs;
|
specialArgs = inputs;
|
||||||
@@ -103,20 +132,24 @@
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
nixosConfigurations = nixpkgs.lib.genAttrs linuxSystems (system: nixpkgs.lib.nixosSystem {
|
nixosConfigurations = nixpkgs.lib.genAttrs linuxSystems (
|
||||||
inherit system;
|
system:
|
||||||
specialArgs = inputs;
|
nixpkgs.lib.nixosSystem {
|
||||||
modules = [
|
inherit system;
|
||||||
disko.nixosModules.disko
|
specialArgs = inputs;
|
||||||
home-manager.nixosModules.home-manager {
|
modules = [
|
||||||
home-manager = {
|
disko.nixosModules.disko
|
||||||
useGlobalPkgs = true;
|
home-manager.nixosModules.home-manager
|
||||||
useUserPackages = true;
|
{
|
||||||
users.${user} = import ./modules/nixos/home-manager.nix;
|
home-manager = {
|
||||||
};
|
useGlobalPkgs = true;
|
||||||
}
|
useUserPackages = true;
|
||||||
./hosts/nixos
|
users.${user} = import ./modules/nixos/home-manager.nix;
|
||||||
];
|
};
|
||||||
});
|
}
|
||||||
};
|
./hosts/nixos
|
||||||
|
];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
{ agenix, config, pkgs, ... }:
|
{
|
||||||
|
agenix,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
let user = "cschmatzler"; in
|
let
|
||||||
|
user = "cschmatzler";
|
||||||
|
in
|
||||||
{
|
{
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
@@ -13,13 +20,23 @@ let user = "cschmatzler"; in
|
|||||||
nix = {
|
nix = {
|
||||||
package = pkgs.nix;
|
package = pkgs.nix;
|
||||||
settings = {
|
settings = {
|
||||||
trusted-users = [ "@admin" "${user}" ];
|
trusted-users = [
|
||||||
substituters = [ "https://nix-community.cachix.org" "https://cache.nixos.org" ];
|
"@admin"
|
||||||
|
"${user}"
|
||||||
|
];
|
||||||
|
substituters = [
|
||||||
|
"https://nix-community.cachix.org"
|
||||||
|
"https://cache.nixos.org"
|
||||||
|
];
|
||||||
trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
|
trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
|
||||||
};
|
};
|
||||||
gc = {
|
gc = {
|
||||||
automatic = true;
|
automatic = true;
|
||||||
interval = { Weekday = 0; Hour = 2; Minute = 0; };
|
interval = {
|
||||||
|
Weekday = 0;
|
||||||
|
Hour = 2;
|
||||||
|
Minute = 0;
|
||||||
|
};
|
||||||
options = "--delete-older-than 30d";
|
options = "--delete-older-than 30d";
|
||||||
};
|
};
|
||||||
extraOptions = ''
|
extraOptions = ''
|
||||||
@@ -27,9 +44,12 @@ let user = "cschmatzler"; in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages =
|
||||||
agenix.packages."${pkgs.system}".default
|
with pkgs;
|
||||||
] ++ (import ../../modules/shared/packages.nix { inherit pkgs; });
|
[
|
||||||
|
agenix.packages."${pkgs.system}".default
|
||||||
|
]
|
||||||
|
++ (import ../../modules/shared/packages.nix { inherit pkgs; });
|
||||||
|
|
||||||
system = {
|
system = {
|
||||||
checks.verifyNixPath = false;
|
checks.verifyNixPath = false;
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
{ config, inputs, pkgs, agenix, ... }:
|
{
|
||||||
|
config,
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
agenix,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
let user = "cschmatzler";
|
let
|
||||||
keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOk8iAnIaa1deoc7jw8YACPNVka1ZFJxhnU4G74TmS+p" ]; in
|
user = "cschmatzler";
|
||||||
|
keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOk8iAnIaa1deoc7jw8YACPNVka1ZFJxhnU4G74TmS+p" ];
|
||||||
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
../../modules/nixos/secrets.nix
|
../../modules/nixos/secrets.nix
|
||||||
@@ -19,7 +27,14 @@ let user = "cschmatzler";
|
|||||||
};
|
};
|
||||||
efi.canTouchEfiVariables = true;
|
efi.canTouchEfiVariables = true;
|
||||||
};
|
};
|
||||||
initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" ];
|
initrd.availableKernelModules = [
|
||||||
|
"xhci_pci"
|
||||||
|
"ahci"
|
||||||
|
"nvme"
|
||||||
|
"usbhid"
|
||||||
|
"usb_storage"
|
||||||
|
"sd_mod"
|
||||||
|
];
|
||||||
# Uncomment for AMD GPU
|
# Uncomment for AMD GPU
|
||||||
# initrd.kernelModules = [ "amdgpu" ];
|
# initrd.kernelModules = [ "amdgpu" ];
|
||||||
kernelPackages = pkgs.linuxPackages_latest;
|
kernelPackages = pkgs.linuxPackages_latest;
|
||||||
@@ -42,8 +57,14 @@ let user = "cschmatzler";
|
|||||||
nixPath = [ "nixos-config=/home/${user}/.local/share/src/nixos-config:/etc/nixos" ];
|
nixPath = [ "nixos-config=/home/${user}/.local/share/src/nixos-config:/etc/nixos" ];
|
||||||
settings = {
|
settings = {
|
||||||
allowed-users = [ "${user}" ];
|
allowed-users = [ "${user}" ];
|
||||||
trusted-users = [ "@admin" "${user}" ];
|
trusted-users = [
|
||||||
substituters = [ "https://nix-community.cachix.org" "https://cache.nixos.org" ];
|
"@admin"
|
||||||
|
"${user}"
|
||||||
|
];
|
||||||
|
substituters = [
|
||||||
|
"https://nix-community.cachix.org"
|
||||||
|
"https://cache.nixos.org"
|
||||||
|
];
|
||||||
trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
|
trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -120,7 +141,7 @@ let user = "cschmatzler";
|
|||||||
overrideDevices = true;
|
overrideDevices = true;
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
devices = {};
|
devices = { };
|
||||||
options.globalAnnounceEnabled = false; # Only sync on LAN
|
options.globalAnnounceEnabled = false; # Only sync on LAN
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -154,8 +175,8 @@ let user = "cschmatzler";
|
|||||||
"class_g = 'i3lock'"
|
"class_g = 'i3lock'"
|
||||||
];
|
];
|
||||||
round-borders = 3;
|
round-borders = 3;
|
||||||
round-borders-exclude = [];
|
round-borders-exclude = [ ];
|
||||||
round-borders-rule = [];
|
round-borders-rule = [ ];
|
||||||
shadow = true;
|
shadow = true;
|
||||||
shadow-radius = 8;
|
shadow-radius = 8;
|
||||||
shadow-opacity = 0.4;
|
shadow-opacity = 0.4;
|
||||||
@@ -206,12 +227,29 @@ let user = "cschmatzler";
|
|||||||
log-level = "info";
|
log-level = "info";
|
||||||
|
|
||||||
wintypes = {
|
wintypes = {
|
||||||
normal = { fade = true; shadow = false; };
|
normal = {
|
||||||
tooltip = { fade = true; shadow = false; opacity = 0.75; focus = true; full-shadow = false; };
|
fade = true;
|
||||||
dock = { shadow = false; };
|
shadow = false;
|
||||||
dnd = { shadow = false; };
|
};
|
||||||
popup_menu = { opacity = 1.0; };
|
tooltip = {
|
||||||
dropdown_menu = { opacity = 1.0; };
|
fade = true;
|
||||||
|
shadow = false;
|
||||||
|
opacity = 0.75;
|
||||||
|
focus = true;
|
||||||
|
full-shadow = false;
|
||||||
|
};
|
||||||
|
dock = {
|
||||||
|
shadow = false;
|
||||||
|
};
|
||||||
|
dnd = {
|
||||||
|
shadow = false;
|
||||||
|
};
|
||||||
|
popup_menu = {
|
||||||
|
opacity = 1.0;
|
||||||
|
};
|
||||||
|
dropdown_menu = {
|
||||||
|
opacity = 1.0;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -241,8 +279,7 @@ let user = "cschmatzler";
|
|||||||
ledger.enable = true;
|
ledger.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Add docker daemon
|
||||||
# Add docker daemon
|
|
||||||
virtualisation.docker.enable = true;
|
virtualisation.docker.enable = true;
|
||||||
virtualisation.docker.logDriver = "json-file";
|
virtualisation.docker.logDriver = "json-file";
|
||||||
|
|
||||||
@@ -266,15 +303,17 @@ let user = "cschmatzler";
|
|||||||
# Don't require password for users in `wheel` group for these commands
|
# Don't require password for users in `wheel` group for these commands
|
||||||
security.sudo = {
|
security.sudo = {
|
||||||
enable = true;
|
enable = true;
|
||||||
extraRules = [{
|
extraRules = [
|
||||||
commands = [
|
{
|
||||||
{
|
commands = [
|
||||||
command = "${pkgs.systemd}/bin/reboot";
|
{
|
||||||
options = [ "NOPASSWD" ];
|
command = "${pkgs.systemd}/bin/reboot";
|
||||||
}
|
options = [ "NOPASSWD" ];
|
||||||
];
|
}
|
||||||
groups = [ "wheel" ];
|
];
|
||||||
}];
|
groups = [ "wheel" ];
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
fonts.packages = with pkgs; [
|
fonts.packages = with pkgs; [
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
_:
|
_: [ ]
|
||||||
[]
|
|
||||||
|
|||||||
@@ -1,2 +1,7 @@
|
|||||||
{ user, config, pkgs, ... }:
|
{
|
||||||
{}
|
user,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{ }
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
{ config, pkgs, lib, home-manager, ... }:
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
home-manager,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
user = "cschmatzler";
|
user = "cschmatzler";
|
||||||
@@ -7,7 +13,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./dock
|
./dock
|
||||||
];
|
];
|
||||||
|
|
||||||
# It me
|
# It me
|
||||||
@@ -20,7 +26,7 @@ in
|
|||||||
|
|
||||||
homebrew = {
|
homebrew = {
|
||||||
enable = true;
|
enable = true;
|
||||||
casks = pkgs.callPackage ./casks.nix {};
|
casks = pkgs.callPackage ./casks.nix { };
|
||||||
|
|
||||||
masApps = {
|
masApps = {
|
||||||
};
|
};
|
||||||
@@ -28,18 +34,25 @@ in
|
|||||||
|
|
||||||
home-manager = {
|
home-manager = {
|
||||||
useGlobalPkgs = true;
|
useGlobalPkgs = true;
|
||||||
users.${user} = { pkgs, config, lib, ... }:{
|
users.${user} =
|
||||||
home = {
|
{
|
||||||
enableNixpkgsReleaseCheck = false;
|
pkgs,
|
||||||
packages = pkgs.callPackage ./packages.nix {};
|
config,
|
||||||
file = lib.mkMerge [
|
lib,
|
||||||
sharedFiles
|
...
|
||||||
additionalFiles
|
}:
|
||||||
];
|
{
|
||||||
stateVersion = "23.11";
|
home = {
|
||||||
|
enableNixpkgsReleaseCheck = false;
|
||||||
|
packages = pkgs.callPackage ./packages.nix { };
|
||||||
|
file = lib.mkMerge [
|
||||||
|
sharedFiles
|
||||||
|
additionalFiles
|
||||||
|
];
|
||||||
|
stateVersion = "23.11";
|
||||||
|
};
|
||||||
|
programs = { } // import ../shared/home-manager.nix { inherit config pkgs lib; };
|
||||||
};
|
};
|
||||||
programs = {} // import ../shared/home-manager.nix { inherit config pkgs lib; };
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Fully declarative dock using the latest from Nix Store
|
# Fully declarative dock using the latest from Nix Store
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
{ pkgs }:
|
{ pkgs }:
|
||||||
|
|
||||||
with pkgs;
|
with pkgs;
|
||||||
let shared-packages = import ../shared/packages.nix { inherit pkgs; }; in
|
let
|
||||||
shared-packages ++ [
|
shared-packages = import ../shared/packages.nix { inherit pkgs; };
|
||||||
|
in
|
||||||
|
shared-packages
|
||||||
|
++ [
|
||||||
dockutil
|
dockutil
|
||||||
_1password-gui
|
_1password-gui
|
||||||
raycast
|
raycast
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
{ config, pkgs, agenix, secrets, ... }:
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
agenix,
|
||||||
|
secrets,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
let user = "cschmatzler"; in
|
let
|
||||||
|
user = "cschmatzler";
|
||||||
|
in
|
||||||
{
|
{
|
||||||
age.identityPaths = [
|
age.identityPaths = [
|
||||||
"/Users/${user}/.ssh/id_ed25519"
|
"/Users/${user}/.ssh/id_ed25519"
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
{ user, ... }:
|
{ user, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
home = builtins.getEnv "HOME";
|
home = builtins.getEnv "HOME";
|
||||||
xdg_configHome = "${home}/.config";
|
xdg_configHome = "${home}/.config";
|
||||||
xdg_dataHome = "${home}/.local/share";
|
xdg_dataHome = "${home}/.local/share";
|
||||||
xdg_stateHome = "${home}/.local/state"; in
|
xdg_stateHome = "${home}/.local/state";
|
||||||
|
in
|
||||||
{
|
{
|
||||||
|
|
||||||
"${xdg_configHome}/bspwm/bspwmrc" = {
|
"${xdg_configHome}/bspwm/bspwmrc" = {
|
||||||
@@ -62,162 +63,162 @@ let
|
|||||||
|
|
||||||
"${xdg_configHome}/sxhkd/sxhkdrc" = {
|
"${xdg_configHome}/sxhkd/sxhkdrc" = {
|
||||||
text = ''
|
text = ''
|
||||||
# Close window
|
# Close window
|
||||||
alt + F4
|
alt + F4
|
||||||
bspc node --close
|
bspc node --close
|
||||||
|
|
||||||
# Make split ratios equal
|
# Make split ratios equal
|
||||||
super + equal
|
super + equal
|
||||||
bspc node @/ --equalize
|
bspc node @/ --equalize
|
||||||
|
|
||||||
# Make split ratios balanced
|
# Make split ratios balanced
|
||||||
super + minus
|
super + minus
|
||||||
bspc node @/ --balance
|
bspc node @/ --balance
|
||||||
|
|
||||||
# Toogle tiling of window
|
# Toogle tiling of window
|
||||||
super + d
|
super + d
|
||||||
bspc query --nodes -n focused.tiled && state=floating || state=tiled; \
|
bspc query --nodes -n focused.tiled && state=floating || state=tiled; \
|
||||||
bspc node --state \~$state
|
bspc node --state \~$state
|
||||||
|
|
||||||
# Toggle fullscreen of window
|
# Toggle fullscreen of window
|
||||||
super + f
|
super + f
|
||||||
bspc node --state \~fullscreen
|
bspc node --state \~fullscreen
|
||||||
|
|
||||||
# Swap the current node and the biggest window
|
# Swap the current node and the biggest window
|
||||||
super + g
|
super + g
|
||||||
bspc node -s biggest.window
|
bspc node -s biggest.window
|
||||||
|
|
||||||
# Swap the current node and the smallest window
|
# Swap the current node and the smallest window
|
||||||
super + shift + g
|
super + shift + g
|
||||||
bspc node -s biggest.window
|
bspc node -s biggest.window
|
||||||
|
|
||||||
# Alternate between the tiled and monocle layout
|
# Alternate between the tiled and monocle layout
|
||||||
super + m
|
super + m
|
||||||
bspc desktop -l next
|
bspc desktop -l next
|
||||||
|
|
||||||
# Move between windows in monocle layout
|
# Move between windows in monocle layout
|
||||||
super + {_, alt + }m
|
super + {_, alt + }m
|
||||||
bspc node -f {next, prev}.local.!hidden.window
|
bspc node -f {next, prev}.local.!hidden.window
|
||||||
|
|
||||||
# Focus the node in the given direction
|
# Focus the node in the given direction
|
||||||
super + {_,shift + }{h,j,k,l}
|
super + {_,shift + }{h,j,k,l}
|
||||||
bspc node -{f,s} {west,south,north,east}
|
bspc node -{f,s} {west,south,north,east}
|
||||||
|
|
||||||
# Focus left/right occupied desktop
|
# Focus left/right occupied desktop
|
||||||
super + {Left,Right}
|
super + {Left,Right}
|
||||||
bspc desktop --focus {prev,next}.occupied
|
bspc desktop --focus {prev,next}.occupied
|
||||||
|
|
||||||
# Focus left/right occupied desktop
|
# Focus left/right occupied desktop
|
||||||
super + {Up,Down}
|
super + {Up,Down}
|
||||||
bspc desktop --focus {prev,next}.occupied
|
bspc desktop --focus {prev,next}.occupied
|
||||||
|
|
||||||
# Focus left/right desktop
|
# Focus left/right desktop
|
||||||
ctrl + alt + {Left,Right}
|
ctrl + alt + {Left,Right}
|
||||||
bspc desktop --focus {prev,next}
|
bspc desktop --focus {prev,next}
|
||||||
|
|
||||||
# Focus left/right desktop
|
# Focus left/right desktop
|
||||||
ctrl + alt + {Up, Down}
|
ctrl + alt + {Up, Down}
|
||||||
bspc desktop --focus {prev,next}
|
bspc desktop --focus {prev,next}
|
||||||
|
|
||||||
# Focus the older or newer node in the focus history
|
# Focus the older or newer node in the focus history
|
||||||
super + {o,i}
|
super + {o,i}
|
||||||
bspc wm -h off; \
|
bspc wm -h off; \
|
||||||
bspc node {older,newer} -f; \
|
bspc node {older,newer} -f; \
|
||||||
bspc wm -h on
|
bspc wm -h on
|
||||||
|
|
||||||
# Focus or send to the given desktop
|
# Focus or send to the given desktop
|
||||||
super + {_,shift + }{1-9,0}
|
super + {_,shift + }{1-9,0}
|
||||||
bspc {desktop -f,node -d} '^{1-9,10}'
|
bspc {desktop -f,node -d} '^{1-9,10}'
|
||||||
|
|
||||||
# Preselect the direction
|
# Preselect the direction
|
||||||
super + alt + {h,j,k,l}
|
super + alt + {h,j,k,l}
|
||||||
bspc node -p {west,south,north,east}
|
bspc node -p {west,south,north,east}
|
||||||
|
|
||||||
# Cancel the preselect
|
# Cancel the preselect
|
||||||
# For context on syntax: https://github.com/baskerville/bspwm/issues/344
|
# For context on syntax: https://github.com/baskerville/bspwm/issues/344
|
||||||
super + alt + {_,shift + }Escape
|
super + alt + {_,shift + }Escape
|
||||||
bspc query -N -d | xargs -I id -n 1 bspc node id -p cancel
|
bspc query -N -d | xargs -I id -n 1 bspc node id -p cancel
|
||||||
|
|
||||||
# Preselect the direction
|
# Preselect the direction
|
||||||
super + ctrl + {h,j,k,l}
|
super + ctrl + {h,j,k,l}
|
||||||
bspc node -p {west,south,north,east}
|
bspc node -p {west,south,north,east}
|
||||||
|
|
||||||
# Cancel the preselect
|
# Cancel the preselect
|
||||||
# For context on syntax: https://github.com/baskerville/bspwm/issues/344
|
# For context on syntax: https://github.com/baskerville/bspwm/issues/344
|
||||||
super + ctrl + {_,shift + }Escape
|
super + ctrl + {_,shift + }Escape
|
||||||
bspc query -N -d | xargs -I id -n 1 bspc node id -p cancel
|
bspc query -N -d | xargs -I id -n 1 bspc node id -p cancel
|
||||||
|
|
||||||
# Set the node flags
|
# Set the node flags
|
||||||
super + ctrl + {m,x,s,p}
|
super + ctrl + {m,x,s,p}
|
||||||
bspc node -g {marked,locked,sticky,private}
|
bspc node -g {marked,locked,sticky,private}
|
||||||
|
|
||||||
# Send the newest marked node to the newest preselected node
|
# Send the newest marked node to the newest preselected node
|
||||||
super + y
|
super + y
|
||||||
bspc node newest.marked.local -n newest.!automatic.local
|
bspc node newest.marked.local -n newest.!automatic.local
|
||||||
|
|
||||||
# Program launcher
|
# Program launcher
|
||||||
super + @space
|
super + @space
|
||||||
rofi -config -no-lazy-grab -show drun -modi drun -theme /home/${user}/.config/rofi/launcher.rasi
|
rofi -config -no-lazy-grab -show drun -modi drun -theme /home/${user}/.config/rofi/launcher.rasi
|
||||||
|
|
||||||
# Terminal emulator
|
# Terminal emulator
|
||||||
super + Return
|
super + Return
|
||||||
bspc rule -a Alacritty -o state=floating rectangle=1024x768x0x0 center=true && /etc/profiles/per-user/${user}/bin/alacritty
|
bspc rule -a Alacritty -o state=floating rectangle=1024x768x0x0 center=true && /etc/profiles/per-user/${user}/bin/alacritty
|
||||||
|
|
||||||
# Terminal emulator
|
# Terminal emulator
|
||||||
super + ctrl + Return
|
super + ctrl + Return
|
||||||
/etc/profiles/per-user/${user}/bin/alacritty
|
/etc/profiles/per-user/${user}/bin/alacritty
|
||||||
|
|
||||||
# Jump to workspaces
|
# Jump to workspaces
|
||||||
super + t
|
super + t
|
||||||
bspc desktop --focus ^2
|
bspc desktop --focus ^2
|
||||||
super + b
|
super + b
|
||||||
bspc desktop --focus ^1
|
bspc desktop --focus ^1
|
||||||
super + w
|
super + w
|
||||||
bspc desktop --focus ^4
|
bspc desktop --focus ^4
|
||||||
super + Tab
|
super + Tab
|
||||||
bspc {node,desktop} -f last
|
bspc {node,desktop} -f last
|
||||||
|
|
||||||
# Keepass XC
|
# Keepass XC
|
||||||
super + shift + x
|
super + shift + x
|
||||||
/etc/profiles/per-user/${user}/bin/keepassxc
|
/etc/profiles/per-user/${user}/bin/keepassxc
|
||||||
|
|
||||||
# Emacs
|
# Emacs
|
||||||
# -c flag is --create-frame
|
# -c flag is --create-frame
|
||||||
# -a flag is fallback to plain emacs if daemon fails
|
# -a flag is fallback to plain emacs if daemon fails
|
||||||
super + alt + Return
|
super + alt + Return
|
||||||
emacsclient -c -a emacs
|
emacsclient -c -a emacs
|
||||||
|
|
||||||
super + alt + e
|
super + alt + e
|
||||||
systemctl --user restart emacs.service && \
|
systemctl --user restart emacs.service && \
|
||||||
emacsclient -c -a emacs
|
emacsclient -c -a emacs
|
||||||
|
|
||||||
# Web browser
|
# Web browser
|
||||||
ctrl + alt + Return
|
ctrl + alt + Return
|
||||||
google-chrome-stable
|
google-chrome-stable
|
||||||
|
|
||||||
# File browser at home dir
|
# File browser at home dir
|
||||||
super + shift + @space
|
super + shift + @space
|
||||||
pcmanfm
|
pcmanfm
|
||||||
|
|
||||||
# Take a screenshot with PrintSc
|
# Take a screenshot with PrintSc
|
||||||
Print
|
Print
|
||||||
flameshot gui -c -p $HOME/.local/share/img/screenshots
|
flameshot gui -c -p $HOME/.local/share/img/screenshots
|
||||||
|
|
||||||
# Lock the screen
|
# Lock the screen
|
||||||
ctrl + alt + BackSpace
|
ctrl + alt + BackSpace
|
||||||
i3lock
|
i3lock
|
||||||
|
|
||||||
# Audio controls for + volume
|
# Audio controls for + volume
|
||||||
XF86AudioRaiseVolume
|
XF86AudioRaiseVolume
|
||||||
pactl set-sink-volume @DEFAULT_SINK@ +5%
|
pactl set-sink-volume @DEFAULT_SINK@ +5%
|
||||||
|
|
||||||
# Audio controls for - volume
|
# Audio controls for - volume
|
||||||
XF86AudioLowerVolume
|
XF86AudioLowerVolume
|
||||||
pactl set-sink-volume @DEFAULT_SINK@ -5%
|
pactl set-sink-volume @DEFAULT_SINK@ -5%
|
||||||
|
|
||||||
# Audio controls for mute
|
# Audio controls for mute
|
||||||
XF86AudioMute
|
XF86AudioMute
|
||||||
pactl set-sink-mute @DEFAULT_SINK@ toggle
|
pactl set-sink-mute @DEFAULT_SINK@ toggle
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -285,84 +286,84 @@ let
|
|||||||
"${xdg_configHome}/rofi/bin/powermenu.sh" = {
|
"${xdg_configHome}/rofi/bin/powermenu.sh" = {
|
||||||
executable = true;
|
executable = true;
|
||||||
text = ''
|
text = ''
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
configDir="${xdg_configHome}/rofi"
|
configDir="${xdg_configHome}/rofi"
|
||||||
uptime=$(uptime -p | sed -e 's/up //g')
|
uptime=$(uptime -p | sed -e 's/up //g')
|
||||||
rofi_command="rofi -no-config -theme $configDir/powermenu.rasi"
|
rofi_command="rofi -no-config -theme $configDir/powermenu.rasi"
|
||||||
|
|
||||||
# Options
|
# Options
|
||||||
shutdown=" Shutdown"
|
shutdown=" Shutdown"
|
||||||
reboot=" Restart"
|
reboot=" Restart"
|
||||||
lock=" Lock"
|
lock=" Lock"
|
||||||
suspend=" Sleep"
|
suspend=" Sleep"
|
||||||
logout=" Logout"
|
logout=" Logout"
|
||||||
|
|
||||||
# Confirmation
|
# Confirmation
|
||||||
confirm_exit() {
|
confirm_exit() {
|
||||||
rofi -dmenu\
|
rofi -dmenu\
|
||||||
-no-config\
|
-no-config\
|
||||||
-i\
|
-i\
|
||||||
-no-fixed-num-lines\
|
-no-fixed-num-lines\
|
||||||
-p "Are You Sure? : "\
|
-p "Are You Sure? : "\
|
||||||
-theme $configDir/confirm.rasi
|
-theme $configDir/confirm.rasi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Message
|
# Message
|
||||||
msg() {
|
msg() {
|
||||||
rofi -no-config -theme "$configDir/message.rasi" -e "Available Options - yes / y / no / n"
|
rofi -no-config -theme "$configDir/message.rasi" -e "Available Options - yes / y / no / n"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Variable passed to rofi
|
# Variable passed to rofi
|
||||||
options="$lock\n$suspend\n$logout\n$reboot\n$shutdown"
|
options="$lock\n$suspend\n$logout\n$reboot\n$shutdown"
|
||||||
chosen="$(echo -e "$options" | $rofi_command -p "Uptime: $uptime" -dmenu -selected-row 0)"
|
chosen="$(echo -e "$options" | $rofi_command -p "Uptime: $uptime" -dmenu -selected-row 0)"
|
||||||
case $chosen in
|
case $chosen in
|
||||||
$shutdown)
|
$shutdown)
|
||||||
ans=$(confirm_exit &)
|
ans=$(confirm_exit &)
|
||||||
if [[ $ans == "yes" || $ans == "YES" || $ans == "y" || $ans == "Y" ]]; then
|
if [[ $ans == "yes" || $ans == "YES" || $ans == "y" || $ans == "Y" ]]; then
|
||||||
systemctl poweroff
|
systemctl poweroff
|
||||||
elif [[ $ans == "no" || $ans == "NO" || $ans == "n" || $ans == "N" ]]; then
|
elif [[ $ans == "no" || $ans == "NO" || $ans == "n" || $ans == "N" ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
msg
|
msg
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
$reboot)
|
$reboot)
|
||||||
ans=$(confirm_exit &)
|
ans=$(confirm_exit &)
|
||||||
if [[ $ans == "yes" || $ans == "YES" || $ans == "y" || $ans == "Y" ]]; then
|
if [[ $ans == "yes" || $ans == "YES" || $ans == "y" || $ans == "Y" ]]; then
|
||||||
systemctl reboot
|
systemctl reboot
|
||||||
elif [[ $ans == "no" || $ans == "NO" || $ans == "n" || $ans == "N" ]]; then
|
elif [[ $ans == "no" || $ans == "NO" || $ans == "n" || $ans == "N" ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
msg
|
msg
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
$lock)
|
$lock)
|
||||||
betterlockscreen -l
|
betterlockscreen -l
|
||||||
;;
|
;;
|
||||||
$suspend)
|
$suspend)
|
||||||
ans=$(confirm_exit &)
|
ans=$(confirm_exit &)
|
||||||
if [[ $ans == "yes" || $ans == "YES" || $ans == "y" || $ans == "Y" ]]; then
|
if [[ $ans == "yes" || $ans == "YES" || $ans == "y" || $ans == "Y" ]]; then
|
||||||
mpc -q pause
|
mpc -q pause
|
||||||
amixer set Master mute
|
amixer set Master mute
|
||||||
systemctl suspend
|
systemctl suspend
|
||||||
elif [[ $ans == "no" || $ans == "NO" || $ans == "n" || $ans == "N" ]]; then
|
elif [[ $ans == "no" || $ans == "NO" || $ans == "n" || $ans == "N" ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
msg
|
msg
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
$logout)
|
$logout)
|
||||||
ans=$(confirm_exit &)
|
ans=$(confirm_exit &)
|
||||||
if [[ $ans == "yes" || $ans == "YES" || $ans == "y" || $ans == "Y" ]]; then
|
if [[ $ans == "yes" || $ans == "YES" || $ans == "y" || $ans == "Y" ]]; then
|
||||||
bspc quit
|
bspc quit
|
||||||
elif [[ $ans == "no" || $ans == "NO" || $ans == "n" || $ans == "N" ]]; then
|
elif [[ $ans == "no" || $ans == "NO" || $ans == "n" || $ans == "N" ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
msg
|
msg
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,25 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
user = "cschmatzler";
|
user = "cschmatzler";
|
||||||
xdg_configHome = "/home/${user}/.config";
|
xdg_configHome = "/home/${user}/.config";
|
||||||
shared-programs = import ../shared/home-manager.nix { inherit config pkgs lib; };
|
shared-programs = import ../shared/home-manager.nix { inherit config pkgs lib; };
|
||||||
shared-files = import ../shared/files.nix { inherit config pkgs; };
|
shared-files = import ../shared/files.nix { inherit config pkgs; };
|
||||||
|
|
||||||
polybar-user_modules = builtins.readFile (pkgs.replaceVars ./config/polybar/user_modules.ini {
|
polybar-user_modules = builtins.readFile (
|
||||||
packages = "${xdg_configHome}/polybar/bin/check-nixos-updates.sh";
|
pkgs.replaceVars ./config/polybar/user_modules.ini {
|
||||||
searchpkgs = "${xdg_configHome}/polybar/bin/search-nixos-updates.sh";
|
packages = "${xdg_configHome}/polybar/bin/check-nixos-updates.sh";
|
||||||
launcher = "${xdg_configHome}/polybar/bin/launcher.sh";
|
searchpkgs = "${xdg_configHome}/polybar/bin/search-nixos-updates.sh";
|
||||||
powermenu = "${xdg_configHome}/rofi/bin/powermenu.sh";
|
launcher = "${xdg_configHome}/polybar/bin/launcher.sh";
|
||||||
calendar = "${xdg_configHome}/polybar/bin/popup-calendar.sh";
|
powermenu = "${xdg_configHome}/rofi/bin/powermenu.sh";
|
||||||
});
|
calendar = "${xdg_configHome}/polybar/bin/popup-calendar.sh";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
polybar-config = pkgs.replaceVars ./config/polybar/config.ini {
|
polybar-config = pkgs.replaceVars ./config/polybar/config.ini {
|
||||||
font0 = "DejaVu Sans:size=12;3";
|
font0 = "DejaVu Sans:size=12;3";
|
||||||
@@ -29,7 +36,7 @@ in
|
|||||||
enableNixpkgsReleaseCheck = false;
|
enableNixpkgsReleaseCheck = false;
|
||||||
username = "${user}";
|
username = "${user}";
|
||||||
homeDirectory = "/home/${user}";
|
homeDirectory = "/home/${user}";
|
||||||
packages = pkgs.callPackage ./packages.nix {};
|
packages = pkgs.callPackage ./packages.nix { };
|
||||||
file = shared-files // import ./files.nix { inherit user; };
|
file = shared-files // import ./files.nix { inherit user; };
|
||||||
stateVersion = "21.05";
|
stateVersion = "21.05";
|
||||||
};
|
};
|
||||||
@@ -112,6 +119,8 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
programs = shared-programs // { gpg.enable = true; };
|
programs = shared-programs // {
|
||||||
|
gpg.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
{ pkgs }:
|
{ pkgs }:
|
||||||
|
|
||||||
with pkgs;
|
with pkgs;
|
||||||
let shared-packages = import ../shared/packages.nix { inherit pkgs; }; in
|
let
|
||||||
shared-packages ++ [
|
shared-packages = import ../shared/packages.nix { inherit pkgs; };
|
||||||
|
in
|
||||||
|
shared-packages
|
||||||
|
++ [
|
||||||
|
|
||||||
# Security and authentication
|
# Security and authentication
|
||||||
yubikey-agent
|
yubikey-agent
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
{ config, pkgs, agenix, secrets, ... }:
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
agenix,
|
||||||
|
secrets,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
let user = "cschmatzler"; in
|
let
|
||||||
|
user = "cschmatzler";
|
||||||
|
in
|
||||||
{
|
{
|
||||||
age.identityPaths = [
|
age.identityPaths = [
|
||||||
"/home/${user}/.ssh/id_ed25519"
|
"/home/${user}/.ssh/id_ed25519"
|
||||||
|
|||||||
@@ -9,10 +9,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
overlays =
|
overlays =
|
||||||
let path = ../../overlays; in with builtins;
|
let
|
||||||
map (n: import (path + ("/" + n)))
|
path = ../../overlays;
|
||||||
(filter (n: match ".*\\.nix" n != null ||
|
in
|
||||||
pathExists (path + ("/" + n + "/default.nix")))
|
with builtins;
|
||||||
(attrNames (readDir path)));
|
map (n: import (path + ("/" + n))) (
|
||||||
|
filter (n: match ".*\\.nix" n != null || pathExists (path + ("/" + n + "/default.nix"))) (
|
||||||
|
attrNames (readDir path)
|
||||||
|
)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
{ pkgs, config, ... }:
|
{ pkgs, config, ... }: { }
|
||||||
{}
|
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
let name = "Christoph Schmatzler";
|
let
|
||||||
user = "cschmatzler";
|
name = "Christoph Schmatzler";
|
||||||
email = "christoph@schmatzler.com"; in
|
user = "cschmatzler";
|
||||||
|
email = "christoph@schmatzler.com";
|
||||||
|
in
|
||||||
{
|
{
|
||||||
zsh = {
|
zsh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -10,14 +17,14 @@ let name = "Christoph Schmatzler";
|
|||||||
cdpath = [ "~/Projects" ];
|
cdpath = [ "~/Projects" ];
|
||||||
plugins = [
|
plugins = [
|
||||||
{
|
{
|
||||||
name = "powerlevel10k";
|
name = "powerlevel10k";
|
||||||
src = pkgs.zsh-powerlevel10k;
|
src = pkgs.zsh-powerlevel10k;
|
||||||
file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
|
file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
name = "powerlevel10k-config";
|
name = "powerlevel10k-config";
|
||||||
src = lib.cleanSource ./config;
|
src = lib.cleanSource ./config;
|
||||||
file = "p10k.zsh";
|
file = "p10k.zsh";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
initContent = lib.mkBefore ''
|
initContent = lib.mkBefore ''
|
||||||
@@ -74,7 +81,7 @@ let name = "Christoph Schmatzler";
|
|||||||
extraConfig = {
|
extraConfig = {
|
||||||
init.defaultBranch = "main";
|
init.defaultBranch = "main";
|
||||||
core = {
|
core = {
|
||||||
editor = "vim";
|
editor = "vim";
|
||||||
autocrlf = "input";
|
autocrlf = "input";
|
||||||
};
|
};
|
||||||
commit.gpgsign = true;
|
commit.gpgsign = true;
|
||||||
@@ -86,23 +93,15 @@ let name = "Christoph Schmatzler";
|
|||||||
ssh = {
|
ssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
includes = [
|
includes = [
|
||||||
(lib.mkIf pkgs.stdenv.hostPlatform.isLinux
|
(lib.mkIf pkgs.stdenv.hostPlatform.isLinux "/home/${user}/.ssh/config_external")
|
||||||
"/home/${user}/.ssh/config_external"
|
(lib.mkIf pkgs.stdenv.hostPlatform.isDarwin "/Users/${user}/.ssh/config_external")
|
||||||
)
|
|
||||||
(lib.mkIf pkgs.stdenv.hostPlatform.isDarwin
|
|
||||||
"/Users/${user}/.ssh/config_external"
|
|
||||||
)
|
|
||||||
];
|
];
|
||||||
matchBlocks = {
|
matchBlocks = {
|
||||||
"github.com" = {
|
"github.com" = {
|
||||||
identitiesOnly = true;
|
identitiesOnly = true;
|
||||||
identityFile = [
|
identityFile = [
|
||||||
(lib.mkIf pkgs.stdenv.hostPlatform.isLinux
|
(lib.mkIf pkgs.stdenv.hostPlatform.isLinux "/home/${user}/.ssh/id_github")
|
||||||
"/home/${user}/.ssh/id_github"
|
(lib.mkIf pkgs.stdenv.hostPlatform.isDarwin "/Users/${user}/.ssh/id_github")
|
||||||
)
|
|
||||||
(lib.mkIf pkgs.stdenv.hostPlatform.isDarwin
|
|
||||||
"/Users/${user}/.ssh/id_github"
|
|
||||||
)
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{ pkgs }:
|
{ pkgs }:
|
||||||
|
|
||||||
with pkgs; [
|
with pkgs;
|
||||||
|
[
|
||||||
age
|
age
|
||||||
age-plugin-yubikey
|
age-plugin-yubikey
|
||||||
bat
|
bat
|
||||||
|
|||||||
Reference in New Issue
Block a user