Initial commit
This commit is contained in:
6
.editorconfig
Normal file
6
.editorconfig
Normal file
@@ -0,0 +1,6 @@
|
||||
root=true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
1
.gitignore
vendored
Executable file
1
.gitignore
vendored
Executable file
@@ -0,0 +1 @@
|
||||
./results
|
20
README.md
Normal file
20
README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Structure
|
||||
|Directory|Usage|
|
||||
|:--:|--|
|
||||
|hosts/<hostname>|Configuration for <hostname>|
|
||||
|modules/|Classical modules and configurations|
|
||||
|lib/|Functions|
|
||||
|assets/|Extra files|
|
||||
|secrets/|Rekeyd secrets|
|
||||
|users/|todo: User configuration and dotfiles|
|
||||
|
||||
# Hosts
|
||||
|Hostname|Device|Description|
|
||||
|:--:|--|:--:|
|
||||
|Phoenix|Asus TUF Gaming FX505DT|My main laptop|
|
||||
|Tureis|Thinkpad X240|My second laptop|
|
||||
|Cepheus|Contabo VPS|
|
||||
|Naos|todo: homeserver|
|
||||
|
||||
# Thanks to...
|
||||
oddlama, sodiboo, nhnn
|
BIN
assets/Wallpaper.jpg
Normal file
BIN
assets/Wallpaper.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 MiB |
1316
flake.lock
generated
Normal file
1316
flake.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
144
flake.nix
Executable file
144
flake.nix
Executable file
@@ -0,0 +1,144 @@
|
||||
{
|
||||
description = "Thary and nothing.run`s NixOS configuration";
|
||||
|
||||
inputs = {
|
||||
# NixOS stuff
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
lix-module = {
|
||||
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.92.0-3.tar.gz";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
lanzaboote = {
|
||||
url = "github:nix-community/lanzaboote";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
deploy-rs.url = "github:serokell/deploy-rs";
|
||||
impermanence.url = "github:nix-community/impermanence";
|
||||
agenix.url = "github:ryantm/agenix";
|
||||
agenix-rekey = {
|
||||
url = "github:oddlama/agenix-rekey";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
nixpak = {
|
||||
url = "github:nixpak/nixpak";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# User stuff
|
||||
niri.url = "github:sodiboo/niri-flake";
|
||||
ags.url = "github:Aylur/ags";
|
||||
stylix.url = "github:danth/stylix";
|
||||
arkenfox = {
|
||||
url = "github:dwarfmaster/arkenfox-nixos";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
website = {
|
||||
url = "git+https://tea.nothing.run/nothing.run/website?ref=main";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
...
|
||||
} @ inputs: let
|
||||
system = "x86_64-linux";
|
||||
|
||||
l = nixpkgs.lib.extend (import ./lib);
|
||||
getModules = dir: l.pipe (l.filterAttrs (_: type: type == "directory") (builtins.readDir ./${dir})) [
|
||||
(x: builtins.mapAttrs (name: _: builtins.readDir ./${dir}/${name}) x) # Get all types and their files
|
||||
(x: builtins.mapAttrs (name: value: (l.pipe value [
|
||||
(y: l.filterAttrs (n: _: n != "secrets") y) # Exclude agenix secrets directory
|
||||
(y: l.filterAttrs (n: _: n != "containers") y) # Exclude containers directory
|
||||
(y: l.mapAttrsToList (n: _: ./${dir}/${name}/${n}) y) # Make phoenix."default.nix" = "regular" phoenix = [ "default.nix" ]
|
||||
])) x)
|
||||
];
|
||||
|
||||
modulesList = {
|
||||
hosts = getModules "hosts";
|
||||
# profiles = getModules "profiles";
|
||||
modules = getModules "modules";
|
||||
# users = getModules "users";
|
||||
};
|
||||
|
||||
hosts = builtins.mapAttrs (
|
||||
host: modules:
|
||||
let
|
||||
cfg = import ./hosts/${host}/default.nix { lib = l; pkgs = {}; config = {}; };
|
||||
in l.nixosSystem {
|
||||
inherit system;
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
inherit host;
|
||||
username = cfg.n.host.defaultUser;
|
||||
};
|
||||
|
||||
modules =
|
||||
modules
|
||||
++ l.flatten (builtins.map (x: modulesList.modules.${x}) (cfg.n.host.types
|
||||
++ [
|
||||
"global"
|
||||
"n"
|
||||
]
|
||||
));
|
||||
}) modulesList.hosts;
|
||||
|
||||
externals = l.pipe hosts [
|
||||
# (x: builtins.mapAttrs (_: v: (l.filterAttrs (n: _: n == "global" || n == "nodes") v.config)) x) # Get `global` and `nodes`
|
||||
(x: builtins.mapAttrs (_: v: (l.filterAttrs (n: _: n == "nodes") v.config)) x) # Get `nodes`
|
||||
(x: builtins.attrValues x)
|
||||
];
|
||||
|
||||
hosts' = builtins.mapAttrs (
|
||||
name: system: system.extendModules {
|
||||
modules = map (n: if l.hasAttr "${name}" n.nodes then n.nodes.${name} else {}) externals;
|
||||
}
|
||||
) hosts;
|
||||
|
||||
in {
|
||||
nixosConfigurations = hosts';
|
||||
|
||||
deploy = {
|
||||
# sudo = "doas -u";
|
||||
sshOpts = [ "-p" "22" ];
|
||||
autoRollback = false;
|
||||
magicRollback = false;
|
||||
remoteBuild = false;
|
||||
|
||||
# KOSTYL'
|
||||
nodes.cepheus = {
|
||||
hostname = "nothing.run";
|
||||
user = "root";
|
||||
profiles.system = {
|
||||
sshUser = "root";
|
||||
path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.cepheus;
|
||||
};
|
||||
};
|
||||
nodes.naos = {
|
||||
hostname = "192.168.1.115";
|
||||
user = "root";
|
||||
profiles.system = {
|
||||
sshUser = "root";
|
||||
path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.cepheus;
|
||||
};
|
||||
};
|
||||
};
|
||||
# This is highly advised, and will prevent many possible mistakes
|
||||
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib;
|
||||
|
||||
agenix-rekey = inputs.agenix-rekey.configure {
|
||||
userFlake = self;
|
||||
nixosConfigurations = self.nixosConfigurations;
|
||||
};
|
||||
|
||||
formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.alejandra;
|
||||
};
|
||||
}
|
17
hosts/cepheus/caddy.nix
Normal file
17
hosts/cepheus/caddy.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{ inputs, ... }: {
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
|
||||
virtualHosts."nothing.run, www.nothing.run".extraConfig = ''
|
||||
header /.well-known/matrix/* Content-Type application/json
|
||||
header /.well-known/matrix/* Access-Control-Allow-Origin *
|
||||
respond /.well-known/matrix/server `{"m.server": "matrix.nothing.run:443"}`
|
||||
respond /.well-known/matrix/client `{"m.homeserver":{"base_url":"https://matrix.nothing.run"},"org.matrix.msc3575.proxy":{"url":"https://matrix.nothing.run"}}`
|
||||
|
||||
root * ${inputs.website.website}
|
||||
file_server
|
||||
'';
|
||||
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
}
|
37
hosts/cepheus/couchdb.nix
Normal file
37
hosts/cepheus/couchdb.nix
Normal file
@@ -0,0 +1,37 @@
|
||||
{ pkgs, lib, ... }: {
|
||||
containers.couchdb = {
|
||||
autoStart = true;
|
||||
bindMounts = {
|
||||
"/var/lib/couchdb" = { hostPath = "/nix/persist/services/couchdb"; isReadOnly = false; };
|
||||
};
|
||||
hostAddress = "192.168.105.10";
|
||||
localAddress = "192.168.105.11";
|
||||
privateNetwork = true;
|
||||
|
||||
config = { ... }: {
|
||||
services.couchdb = {
|
||||
enable = true;
|
||||
bindAddress = "192.168.105.11";
|
||||
port = 5984;
|
||||
databaseDir = "/var/lib/couchdb";
|
||||
viewIndexDir = "/var/lib/couchdb";
|
||||
|
||||
adminUser = lib.removeSuffix "\n" ("admin_" + pkgs.lib.readFile "${pkgs.runCommand "timestamp" {} "echo `head -c 12 /dev/urandom | base64 | sed 's/[+=\\/A-Z]//g'` > $out"}");
|
||||
adminPass = pkgs.lib.readFile "${pkgs.runCommand "timestamp" {} "echo `head -c 32 /dev/urandom | base64 | sed 's/[+=\\/A-Z]//g'` > $out"}";
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ 5984 ];
|
||||
};
|
||||
system.stateVersion = "25.05";
|
||||
};
|
||||
};
|
||||
|
||||
services.caddy.virtualHosts = {
|
||||
"couchdb.nothing.run".extraConfig = ''
|
||||
reverse_proxy http://192.168.105.11:5984
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
37
hosts/cepheus/default.nix
Normal file
37
hosts/cepheus/default.nix
Normal file
@@ -0,0 +1,37 @@
|
||||
{ lib, config, ... }: {
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
boot.initrd.availableKernelModules = [
|
||||
"nvme"
|
||||
"xhci_pci"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
"ata_piix"
|
||||
"virtio_pci"
|
||||
"virtio_scsi"
|
||||
"sr_mod"
|
||||
];
|
||||
|
||||
age.secrets.cepheus_userhjkl_password = {
|
||||
rekeyFile = ./secrets/password.age;
|
||||
owner = "userhjkl";
|
||||
group = "users";
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
n.host = {
|
||||
hardware.cpu = "virt";
|
||||
bootloader = "grub";
|
||||
|
||||
domain = "nothing.run";
|
||||
hostId = "0b6ce634";
|
||||
users."userhjkl" = lib.mkUser config.age.secrets.cepheus_userhjkl_password.path true;
|
||||
defaultUser = "userhjkl";
|
||||
types = [ "server" ];
|
||||
};
|
||||
|
||||
imports = [
|
||||
(lib.fs.ext4 "/" "/dev/disk/by-uuid/8c2eee33-ab23-42b5-b22c-777fbede1ccf" null)
|
||||
(lib.fs.vfat "/boot" "/dev/disk/by-uuid/8B83-5678" null)
|
||||
];
|
||||
}
|
195
hosts/cepheus/gitea.nix
Normal file
195
hosts/cepheus/gitea.nix
Normal file
@@ -0,0 +1,195 @@
|
||||
{ config, pkgs, lib, ... }: {
|
||||
age.secrets.kanidm-oauth2-gitea = lib.mkSecret "kanidm";
|
||||
services.kanidm.provision = {
|
||||
groups."gitea.access" = {};
|
||||
groups."gitea.admins" = {};
|
||||
systems.oauth2.gitea = {
|
||||
displayName = "gitea";
|
||||
originUrl = "https://tea.nothing.run/user/oauth2/kanidm/callback";
|
||||
originLanding = "https://tea.nothing.run/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-gitea.path;
|
||||
scopeMaps."gitea.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
allowInsecureClientDisablePkce = true;
|
||||
preferShortUsername = true;
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup."gitea.admins" = [ "admins" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
containers.gitea = let host-config = config; in {
|
||||
autoStart = true;
|
||||
bindMounts = {
|
||||
"/var/lib/gitea" = { hostPath = "/nix/persist/services/gitea"; isReadOnly = false; };
|
||||
# "${config.age.secretsDir}" = { hostPath = config.age.secretsDir; isReadOnly = true; };
|
||||
"/run/agenix" = { hostPath = "/run/agenix"; isReadOnly = false; };
|
||||
};
|
||||
# tmpfs = [ "/" ];
|
||||
hostAddress = "192.168.102.10";
|
||||
localAddress = "192.168.102.11";
|
||||
|
||||
# forwardPorts = [
|
||||
# {
|
||||
# containerPort = 22;
|
||||
# hostPort = 9922;
|
||||
# protocol = "tcp";
|
||||
# }
|
||||
# ];
|
||||
privateNetwork = true;
|
||||
|
||||
config = { lib, config, ... }: {
|
||||
imports = [
|
||||
../../modules/global/dnscrypt-proxy.nix
|
||||
];
|
||||
|
||||
users.groups.kanidm = {};
|
||||
users.groups.git = { };
|
||||
users.users.git = {
|
||||
isSystemUser = true;
|
||||
useDefaultShell = true;
|
||||
group = "git";
|
||||
extraGroups = [ "kanidm" ];
|
||||
home = config.services.gitea.stateDir;
|
||||
openssh.authorizedKeys.keys = lib.mkForce host-config.users.users.root.openssh.authorizedKeys.keys;
|
||||
};
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
# settings = {
|
||||
# PasswordAuthentication = false;
|
||||
# KbdInteractiveAuthentication = false;
|
||||
# PermitRootLogin = "prohibit-password";
|
||||
# };
|
||||
# openFirewall = true;
|
||||
# ports = [ 22 ];
|
||||
# settings.AcceptEnv = "GIT_PROTOCOL";
|
||||
};
|
||||
|
||||
services.gitea = {
|
||||
enable = true;
|
||||
package = pkgs.gitea;
|
||||
user = "git";
|
||||
group = "git";
|
||||
settings = {
|
||||
DEFAULT.APP_NAME = "Hollow Tea";
|
||||
mailer.ENABLED = false;
|
||||
metrics.ENABLED = false;
|
||||
oauth2_client = {
|
||||
ACCOUNT_LINKING = "login";
|
||||
USERNAME = "nickname";
|
||||
ENABLE_AUTO_REGISTRATION = false;
|
||||
REGISTER_EMAIL_CONFIRM = false;
|
||||
UPDATE_AVATAR = true;
|
||||
};
|
||||
repository = {
|
||||
DEFAULT_PRIVATE = "private";
|
||||
ENABLE_PUSH_CREATE_USER = true;
|
||||
ENABLE_PUSH_CREATE_ORG = true;
|
||||
};
|
||||
server = {
|
||||
HTTP_ADDR = "0.0.0.0";
|
||||
HTTP_PORT = 3000;
|
||||
DOMAIN = "tea.nothing.run";
|
||||
ROOT_URL = "https://tea.nothing.run";
|
||||
LANDING_PAGE = "login";
|
||||
SSH_PORT = 9922;
|
||||
SSH_USER = "git";
|
||||
};
|
||||
service = {
|
||||
DISABLE_REGISTRATION = false;
|
||||
ALLOW_ONLY_INTERNAL_REGISTRATION = false;
|
||||
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
|
||||
SHOW_REGISTRATION_BUTTON = false;
|
||||
REGISTER_EMAIL_CONFIRM = false;
|
||||
ENABLE_NOTIFY_MAIL = false;
|
||||
};
|
||||
"service.explore" = {
|
||||
REQUIRE_SIGNIN_VIEW = true;
|
||||
DISABLE_USERS_PAGE = false;
|
||||
DISABLE_ORGANIZATIONS_PAGE = true;
|
||||
DISABLE_CODE_PAGE = true;
|
||||
};
|
||||
admin.DISABLE_REGULAR_ORG_CREATION = true; # Prohibit creation of organizations by non-admin users
|
||||
session.COOKIE_SECURE = true;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.gitea = {
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig.RestartSec = "60"; # Retry every minute
|
||||
preStart =
|
||||
let
|
||||
exe = lib.getExe config.services.gitea.package;
|
||||
providerName = "kanidm";
|
||||
clientId = "gitea";
|
||||
args = lib.escapeShellArgs (
|
||||
lib.concatLists [
|
||||
[
|
||||
"--name"
|
||||
providerName
|
||||
]
|
||||
[
|
||||
"--provider"
|
||||
"openidConnect"
|
||||
]
|
||||
[
|
||||
"--key"
|
||||
clientId
|
||||
]
|
||||
[
|
||||
"--auto-discover-url"
|
||||
"https://idm.nothing.run/oauth2/openid/${clientId}/.well-known/openid-configuration"
|
||||
]
|
||||
[
|
||||
"--scopes"
|
||||
"email"
|
||||
]
|
||||
[
|
||||
"--scopes"
|
||||
"profile"
|
||||
]
|
||||
[
|
||||
"--group-claim-name"
|
||||
"groups"
|
||||
]
|
||||
[
|
||||
"--admin-group"
|
||||
"admin"
|
||||
]
|
||||
[ "--skip-local-2fa" ]
|
||||
]
|
||||
);
|
||||
in
|
||||
lib.mkAfter ''
|
||||
provider_id=$(${exe} admin auth list | ${pkgs.gnugrep}/bin/grep -w '${providerName}' | cut -f1)
|
||||
SECRET="$(< ${host-config.age.secrets.kanidm-oauth2-gitea.path})"
|
||||
if [[ -z "$provider_id" ]]; then
|
||||
${exe} admin auth add-oauth ${args} --secret "$SECRET"
|
||||
else
|
||||
${exe} admin auth update-oauth --id "$provider_id" ${args} --secret "$SECRET"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ 3000 22 ];
|
||||
};
|
||||
system.stateVersion = "25.05";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 9922 ];
|
||||
|
||||
services.caddy.virtualHosts = {
|
||||
"tea.nothing.run".extraConfig = ''
|
||||
reverse_proxy http://192.168.102.11:3000
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
36
hosts/cepheus/hedgedoc.nix
Executable file
36
hosts/cepheus/hedgedoc.nix
Executable file
@@ -0,0 +1,36 @@
|
||||
{ config, ... }:
|
||||
let
|
||||
inherit (config.networking) domain;
|
||||
service_port = 8259;
|
||||
db = "hedgedoc";
|
||||
in {
|
||||
services.hedgedoc = {
|
||||
# enable = true; # TODO
|
||||
enable = false;
|
||||
settings = {
|
||||
# TODO: kanidm auth
|
||||
port = service_port;
|
||||
protocolUseSSL = true;
|
||||
domain = "pad.${domain}";
|
||||
host = "127.0.0.1";
|
||||
allowGravatar = false;
|
||||
allowPDFExport = true;
|
||||
dbURL = "postgres://${db}:${db}@localhost:${toString config.services.postgresql.settings.port}/${db}";
|
||||
|
||||
allowEmailRegister = false;
|
||||
allowAnonymous = false;
|
||||
|
||||
loglevel = "none";
|
||||
};
|
||||
};
|
||||
|
||||
imp.dirs = [
|
||||
{ directory = "/var/lib/hedgedoc"; user = "hedgedoc"; group = "hedgedoc"; mode = "u=rwx,g=rx,o="; }
|
||||
];
|
||||
|
||||
services.caddy.virtualHosts = {
|
||||
"pad.${domain}".extraConfig = ''
|
||||
reverse_proxy http://127.0.0.1:${toString service_port}
|
||||
'';
|
||||
};
|
||||
}
|
107
hosts/cepheus/kanidm.nix
Normal file
107
hosts/cepheus/kanidm.nix
Normal file
@@ -0,0 +1,107 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
kanidmPort = 1888;
|
||||
in {
|
||||
age.secrets.kanidm-admin-password = lib.mkSecret "kanidm";
|
||||
age.secrets.kanidm-idm-admin-password = lib.mkSecret "kanidm";
|
||||
users.groups.kanidm = {};
|
||||
users.users.kanidm.group = "kanidm";
|
||||
users.users.kanidm.isSystemUser = true;
|
||||
|
||||
containers.kanidm = {
|
||||
autoStart = true;
|
||||
bindMounts = {
|
||||
"/certs" = { hostPath = "/nix/persist/services/kanidm/certs"; isReadOnly = false; };
|
||||
"/var/lib/kanidm" = { hostPath = "/nix/persist/services/kanidm/db"; isReadOnly = false; };
|
||||
# "${config.age.secretsDir}" = { hostPath = config.age.secretsDir; isReadOnly = true; };
|
||||
"/run/agenix" = { hostPath = "/run/agenix"; isReadOnly = false; };
|
||||
};
|
||||
# tmpfs = [ "/" ];
|
||||
hostAddress = "192.168.101.10";
|
||||
localAddress = "192.168.101.11";
|
||||
privateNetwork = true;
|
||||
# privateNetwork = false;
|
||||
|
||||
config = { lib, ... }: {
|
||||
imports = [
|
||||
# ../../modules/global/nix.nix
|
||||
../../modules/global/dnscrypt-proxy.nix
|
||||
];
|
||||
|
||||
services.kanidm = {
|
||||
enableServer = true;
|
||||
package = pkgs.kanidmWithSecretProvisioning;
|
||||
enableClient = true;
|
||||
serverSettings = {
|
||||
domain = "idm.nothing.run";
|
||||
origin = "https://idm.nothing.run";
|
||||
# bindaddress = "127.0.0.1:${toString kanidmPort}";
|
||||
bindaddress = "0.0.0.0:${toString kanidmPort}";
|
||||
log_level = "trace";
|
||||
trust_x_forward_for = true;
|
||||
|
||||
tls_chain = "/certs/chain.pem";
|
||||
tls_key = "/certs/key.pem";
|
||||
};
|
||||
clientSettings = {
|
||||
uri = "https://127.0.0.1:${toString kanidmPort}";
|
||||
verify_ca = false;
|
||||
verify_hostnames = false;
|
||||
};
|
||||
provision = lib.mkMerge [
|
||||
{ enable = lib.mkForce true; }
|
||||
config.services.kanidm.provision
|
||||
];
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ kanidmPort ];
|
||||
};
|
||||
system.stateVersion = "25.05";
|
||||
};
|
||||
};
|
||||
|
||||
services.kanidm.provision = {
|
||||
acceptInvalidCerts = true;
|
||||
instanceUrl = "https://127.0.0.1:${toString kanidmPort}";
|
||||
|
||||
adminPasswordFile = config.age.secrets.kanidm-admin-password.path;
|
||||
idmAdminPasswordFile = config.age.secrets.kanidm-idm-admin-password.path;
|
||||
groups.admins = {};
|
||||
|
||||
persons = {
|
||||
"thary" = {
|
||||
"displayName" = "Thary";
|
||||
"mailAddresses" = [
|
||||
"thary@riseup.net"
|
||||
"thary@nothing.run"
|
||||
];
|
||||
groups = [
|
||||
"gitea.access" "gitea.admins"
|
||||
"miniflux.access"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
imp.home.dirs = [ ".cache/kanidm_tokens" ];
|
||||
services.kanidm.enableClient = true;
|
||||
services.kanidm.clientSettings = {
|
||||
uri = "https://idm.nothing.run";
|
||||
verify_ca = true;
|
||||
verify_hostnames = true;
|
||||
};
|
||||
|
||||
services.caddy.virtualHosts = {
|
||||
"idm.nothing.run".extraConfig = ''
|
||||
reverse_proxy https://192.168.101.11:${toString kanidmPort} {
|
||||
transport http {
|
||||
tls
|
||||
tls_insecure_skip_verify
|
||||
}
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
34
hosts/cepheus/matrix-web-clients.nix
Normal file
34
hosts/cepheus/matrix-web-clients.nix
Normal file
@@ -0,0 +1,34 @@
|
||||
{ pkgs, ... }: {
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
|
||||
virtualHosts."cinny.nothing.run".extraConfig = ''
|
||||
root * ${pkgs.cinny.override {conf = {
|
||||
defaultHomeserver = 0;
|
||||
homeserverList = [ "matrix.nothing.run" "matrix.inex.rocks" ];
|
||||
allowCustomHomeservers = false;
|
||||
};}}
|
||||
file_server
|
||||
'';
|
||||
virtualHosts."element.nothing.run".extraConfig = ''
|
||||
root * ${pkgs.element-web.override {
|
||||
conf = {
|
||||
default_server_config = {
|
||||
"m.homeserver".base_url = "https://nothing.run";
|
||||
"m.identity_server" = {};
|
||||
};
|
||||
disable_custom_urls = true;
|
||||
brand = "Nothing Chat";
|
||||
default_theme = "dark";
|
||||
jitsi.preferred_domain = "https://jitsi.inex.rocks"; # TODO: host jitsi
|
||||
};}}
|
||||
file_server
|
||||
'';
|
||||
virtualHosts."riot.nothing.run".extraConfig = ''
|
||||
redir https://element.nothing.run
|
||||
'';
|
||||
|
||||
# TODO: schildichat-web (there is no package in nixpkgs)
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
}
|
76
hosts/cepheus/miniflux.nix
Normal file
76
hosts/cepheus/miniflux.nix
Normal file
@@ -0,0 +1,76 @@
|
||||
{ config, pkgs, lib, ... }: {
|
||||
age.secrets.kanidm-oauth2-miniflux = lib.mkSecret "kanidm";
|
||||
services.kanidm.provision = {
|
||||
groups."miniflux.access" = {};
|
||||
systems.oauth2.miniflux = {
|
||||
displayName = "miniflux";
|
||||
originUrl = "https://rss.nothing.run/oauth2/oidc/callback";
|
||||
originLanding = "https://rss.nothing.run/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-miniflux.path;
|
||||
scopeMaps."miniflux.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
allowInsecureClientDisablePkce = true;
|
||||
preferShortUsername = true;
|
||||
};
|
||||
};
|
||||
|
||||
age.secrets.miniflux-admin-credentials = {
|
||||
generator.script = _: ''
|
||||
echo "ADMIN_USERNAME = 'admin_fmA4ei32f'"
|
||||
echo "ADMIN_PASSWORD = '$(head -c 32 /dev/urandom | base64)'"
|
||||
'';
|
||||
group = "kanidm";
|
||||
mode = "444";
|
||||
};
|
||||
|
||||
containers.miniflux = {
|
||||
autoStart = true;
|
||||
bindMounts = {
|
||||
"/run/postgresql" = { hostPath = "/nix/persist/services/miniflux"; isReadOnly = false; };
|
||||
"/run/agenix" = { hostPath = "/run/agenix"; isReadOnly = false; };
|
||||
};
|
||||
hostAddress = "192.168.103.10";
|
||||
localAddress = "192.168.103.11";
|
||||
privateNetwork = true;
|
||||
|
||||
config = { ... }: {
|
||||
imports = [ ../../modules/global/dnscrypt-proxy.nix ];
|
||||
|
||||
users.groups.kanidm = {};
|
||||
users.users.postgres.extraGroups = [ "kanidm" ];
|
||||
|
||||
services.miniflux = {
|
||||
enable = true;
|
||||
createDatabaseLocally = true;
|
||||
adminCredentialsFile = config.age.secrets.miniflux-admin-credentials.path;
|
||||
config = {
|
||||
LISTEN_ADDR = "192.168.103.11:8080";
|
||||
CREATE_ADMIN = 1;
|
||||
|
||||
OAUTH2_PROVIDER = "oidc";
|
||||
OAUTH2_CLIENT_ID = "miniflux";
|
||||
OAUTH2_CLIENT_SECRET = config.age.secrets.kanidm-oauth2-miniflux.path;
|
||||
OAUTH2_REDIRECT_URL = "https://rss.nothing.run/oauth2/oidc/callback";
|
||||
OAUTH2_OIDC_DISCOVERY_ENDPOINT = "https://idm.nothing.run/oauth2/openid/miniflux";
|
||||
OAUTH2_USER_CREATION = 1;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ 8080 ];
|
||||
};
|
||||
system.stateVersion = "25.05";
|
||||
};
|
||||
};
|
||||
|
||||
services.caddy.virtualHosts = {
|
||||
"rss.nothing.run".extraConfig = ''
|
||||
reverse_proxy http://192.168.103.11:8080
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
4
hosts/cepheus/postgres.nix
Normal file
4
hosts/cepheus/postgres.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ ... }: {
|
||||
services.postgresql.enable = true;
|
||||
imp.dirs = [ "/var/lib/postgresql" ];
|
||||
}
|
8
hosts/cepheus/secrets/matrix_admin_api_token.age
Normal file
8
hosts/cepheus/secrets/matrix_admin_api_token.age
Normal file
@@ -0,0 +1,8 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 8IT6eg yX9WPef2jwkv9rsWS1Zz37qNwP/7AXVwwR3y7sy5/0k
|
||||
d6IIsuuPi+ZZA/HDyDYgbjL7AiFtEEx+Ez3IWeVYo5Y
|
||||
-> d6L4.Y&D-grease *z=Q"@Cb f{ VN
|
||||
3IcbB/YPlZaTqaKIYjkvYmxlLVSBkOnLPMm3uPQrzA2i9bTNH6tjGVG0c64jYif4
|
||||
GXbSIKn1wkTmkYBX3FQAPsPwBQ
|
||||
--- u4kYHCN4Flk12expFXLzogEmv0LleaTExylppjkLdJg
|
||||
<EFBFBD>k6<>\<5C>Z,<2C><>o<EFBFBD>V<>OOh<4F><68><15>+<2B><14>"<22><1F><><EFBFBD><EFBFBD> \<5C><>N)&M8<><38>&x1g&Zxn<78><6E><EFBFBD>!<21><02><>Aȅ,\<5C><>飩-<2D>o<EFBFBD><6F><EFBFBD>m<EFBFBD>r<EFBFBD>iD1<>D<EFBFBD>e<EFBFBD>_4
|
7
hosts/cepheus/secrets/password.age
Normal file
7
hosts/cepheus/secrets/password.age
Normal file
@@ -0,0 +1,7 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 8IT6eg OGouWD06nC1BworHWu+bhrnwb5Q4skSrOKU703Rqr2E
|
||||
/T0+bnhxRzgry7nVdlHFoYGEXc/6Q3dIxtvlATMl/3s
|
||||
-> `-grease
|
||||
+LfEGtXt+5BOYK5njRUFRhQix/yPMIs
|
||||
--- Hxczp2zWnEqT0MQYjPc3O7Dva8r9pUOXkXHuv2DuIP4
|
||||
<EFBFBD>`<60>FF<46><46>#g֗<67>t<EFBFBD><0B>Ŗ<EFBFBD><C596><EFBFBD>K:)<29>g\<5C>gC<67>R3*0<0B><>V<EFBFBD>vt<76><74>:t70w<19>ND<01><><EFBFBD>)x<><78>"מ<><D79E>IP<49><50><EFBFBD>u<1F><>6<><36><EFBFBD>@<40>hf<68>ag[<5B><0C>ܺ<EFBFBD><DCBA><EFBFBD><EFBFBD>
|
9
hosts/cepheus/synapse-admin.nix
Executable file
9
hosts/cepheus/synapse-admin.nix
Executable file
@@ -0,0 +1,9 @@
|
||||
{ pkgs, config, ... }: {
|
||||
services.caddy = {
|
||||
virtualHosts."synapse-admin.${config.networking.domain}".extraConfig = ''
|
||||
encode zstd gzip
|
||||
root * ${pkgs.synapse-admin-etkecc}
|
||||
file_server
|
||||
'';
|
||||
};
|
||||
}
|
37
hosts/cepheus/synapse-revitalization.nix
Normal file
37
hosts/cepheus/synapse-revitalization.nix
Normal file
@@ -0,0 +1,37 @@
|
||||
{ pkgs, config, ... }: {
|
||||
age.secrets.matrix_admin_api_token = {
|
||||
rekeyFile = ./secrets/matrix_admin_api_token.age;
|
||||
owner = "matrix-synapse";
|
||||
group = "matrix-synapse";
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
systemd.services."synapse-revitalization" =
|
||||
let pkg = "${pkgs.synapse-revitalization}/bin/synapse-revitalization";
|
||||
script = pkgs.writeShellScript "synapse-revitalization-script" ''
|
||||
journalctl -f -u matrix-synapse -o cat |
|
||||
while read -r line; do
|
||||
echo "$line" | grep "as we're not in the room" && ${pkg} "$line" &
|
||||
echo "$line" | grep "Ignoring PDU for unknown room_id" && ${pkg} "$line" &
|
||||
done
|
||||
'';
|
||||
in {
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
# User = "matrix-synapse";
|
||||
# Group = "matrix-synapse";
|
||||
User = "root";
|
||||
Group = "root";
|
||||
ExecStart = script;
|
||||
Restart = "always";
|
||||
};
|
||||
environment = {
|
||||
"SYNAPSE_REVITALIZATION_ADMIN_AUTH_TOKEN_FILE" = config.age.secrets.matrix_admin_api_token.path;
|
||||
"SYNAPSE_REVITALIZATION_SERVER_KEY_FILE" = "/var/lib/matrix-synapse/homeserver.signing.key";
|
||||
"SYNAPSE_REVITALIZATION_SERVER_NAME" = "nothing.run";
|
||||
"SYNAPSE_REVITALIZATION_SERVER_ADDRESS" = "matrix.nothing.run";
|
||||
};
|
||||
};
|
||||
}
|
216
hosts/cepheus/synapse.nix
Executable file
216
hosts/cepheus/synapse.nix
Executable file
@@ -0,0 +1,216 @@
|
||||
{ lib, config, pkgs, ... }:
|
||||
let
|
||||
domain = "nothing.run";
|
||||
ulid = "01K2FWKJXXG713J0PERVHJ54S3";
|
||||
in {
|
||||
environment.systemPackages = with pkgs; [ synapse synadm ];
|
||||
|
||||
age.secrets.kanidm-oauth2-mas = lib.mkSecret "kanidm";
|
||||
services.kanidm.provision = {
|
||||
groups."matrix.access" = {};
|
||||
# groups."matrix.admins" = {};
|
||||
systems.oauth2.matrix = {
|
||||
displayName = "matrix";
|
||||
originUrl = "https://mas.nothing.run/upstream/callback/${ulid}";
|
||||
originLanding = "https://mas.nothing.run/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-mas.path;
|
||||
scopeMaps."matrix.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
allowInsecureClientDisablePkce = false;
|
||||
# enableLegacyCrypto = true;
|
||||
preferShortUsername = true;
|
||||
# claimMaps.groups = {
|
||||
# joinType = "array";
|
||||
# valuesByGroup."matrix.admins" = [ "admins" ];
|
||||
# };
|
||||
};
|
||||
};
|
||||
|
||||
# containers.matrix-synapse = {
|
||||
# autoStart = true;
|
||||
# bindMounts = {
|
||||
# "/var/lib/matrix-synapse" = { hostPath = "/nix/persist/services/synapse/data"; isReadOnly = false; };
|
||||
# "/var/lib/postgresql" = { hostPath = "/nix/persist/services/synapse/db"; isReadOnly = false; };
|
||||
# "/run/agenix" = { hostPath = "/run/agenix"; isReadOnly = false; };
|
||||
# };
|
||||
# hostAddress = "192.168.107.10";
|
||||
# localAddress = "192.168.107.11";
|
||||
#
|
||||
# privateNetwork = true;
|
||||
#
|
||||
# config = { ... }: {
|
||||
systemd.services.matrix-authentication-service =
|
||||
let config = pkgs.writeText "mas-configuration.json" (builtins.toJSON {
|
||||
upstream_oauth2.providers = [
|
||||
{
|
||||
id = ulid;
|
||||
issuer = "https://idm.nothing.run/oauth2/openid/matrix";
|
||||
token_endpoint_auth_method = "client_secret_basic";
|
||||
human_name = "matrix";
|
||||
client_id = "matrix";
|
||||
scope = "openid email profile";
|
||||
pkce_method = "always";
|
||||
|
||||
claims_imports.localpart.action = "require";
|
||||
claims_imports.displayname.action = "ignore";
|
||||
claims_imports.email.action = "require";
|
||||
}
|
||||
];
|
||||
|
||||
http = {
|
||||
public_base = "https://mas.nothing.run";
|
||||
listeners = [{
|
||||
name = "web";
|
||||
resources = [
|
||||
{ name = "discovery"; }
|
||||
{ name = "human"; }
|
||||
{ name = "oauth"; }
|
||||
{ name = "compat"; }
|
||||
{ name = "graphql"; }
|
||||
{
|
||||
name = "assets";
|
||||
path = "${pkgs.matrix-authentication-service}/share/matrix-authentication-service/assets";
|
||||
} # What is it?
|
||||
];
|
||||
|
||||
binds = [{
|
||||
host = "127.0.0.1";
|
||||
port = 8086;
|
||||
}];
|
||||
proxy_protocol = false;
|
||||
}];
|
||||
};
|
||||
# database.uri = "postgresql:///matrix-authentication-service?host=/run/postgresql";
|
||||
database.uri = "postgresql://matrix-authentication-service@127.0.0.1:5432/matrix-authentication-service";
|
||||
matrix = {
|
||||
kind = "synapse";
|
||||
homeserver = "nothing.run";
|
||||
endpoint = "https://matrix.nothing.run:443";
|
||||
};
|
||||
passwords = {
|
||||
enabled = true;
|
||||
schemes = [
|
||||
{
|
||||
version = 2;
|
||||
algorithm = "argon2id";
|
||||
}
|
||||
{
|
||||
version = 1;
|
||||
algorithm = "bcrypt";
|
||||
unicode_normalization = true;
|
||||
}
|
||||
];
|
||||
minimum_complexity = 8;
|
||||
};
|
||||
|
||||
});
|
||||
in {
|
||||
enable = true;
|
||||
description = "Matrix Authentication Service";
|
||||
# wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${lib.getExe pkgs.matrix-authentication-service} --config ${config}";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
};
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
ensureDatabases = [ "matrix-authentication-service" ];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "matrix-authentication-service";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.matrix-synapse = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server_name = domain;
|
||||
enable_metrics = true;
|
||||
listeners = [
|
||||
{ port = 8008;
|
||||
bind_addresses = [ "0.0.0.0" ];
|
||||
type = "http";
|
||||
tls = false;
|
||||
x_forwarded = true;
|
||||
resources = [ {
|
||||
names = [ "client" "federation" ];
|
||||
compress = true;
|
||||
} ];
|
||||
}
|
||||
|
||||
# { port = 3002; # Metrics
|
||||
# bind_addresses = [ "0.0.0.0" ];
|
||||
# # type = "metrics";
|
||||
# type = "http";
|
||||
# tls = false;
|
||||
# x_forwarded = true;
|
||||
# resources = [ {
|
||||
# names = [ "metrics" ];
|
||||
# compress = true;
|
||||
# } ];
|
||||
# }
|
||||
];
|
||||
database = {
|
||||
name = "psycopg2";
|
||||
args = let db = "matrix-synapse"; in {
|
||||
user = db;
|
||||
database = db;
|
||||
};
|
||||
};
|
||||
# registration_shared_secret = secrets.matrix.shared_secret;
|
||||
registration_shared_secret = pkgs.lib.readFile "${pkgs.runCommand "timestamp" {} "echo `cat /dev/random | head -c 50 | base64` > $out"}";
|
||||
max_upload_size = "20M";
|
||||
enable_authenticated_media = true;
|
||||
require_auth_for_profile_requests = true;
|
||||
enable_registration_captcha = false;
|
||||
enable_registration = false;
|
||||
};
|
||||
|
||||
# log.root.level = "ERROR";
|
||||
log.root.level = "INFO";
|
||||
};
|
||||
# networking.firewall.allowedTCPPorts = [ 8008 8080 ];
|
||||
# };
|
||||
# };
|
||||
|
||||
# services.caddy = {
|
||||
# virtualHosts = {
|
||||
# "matrix.${domain}".extraConfig = ''
|
||||
# reverse_proxy /_matrix/* http://192.168.107.11:8008
|
||||
# reverse_proxy /_synapse/client/* http://192.168.107.11:8008
|
||||
# reverse_proxy /client/* http://192.168.107.11:8008
|
||||
# reverse_proxy /_matrix/client/unstable/org.matrix.msc3575/sync/* http://192.168.107.11:8008
|
||||
# reverse_proxy /_synapse/admin/* http://192.168.107.11:8008
|
||||
# '';
|
||||
# # Add `reverse_proxy /_synapse/admin/* http://127.0.0.1:8008` to allow access to the admin API
|
||||
#
|
||||
# "mas.${domain}".extraConfig = ''
|
||||
# reverse_proxy http://192.168.107.11:8080
|
||||
# '';
|
||||
# };
|
||||
# };
|
||||
services.caddy = {
|
||||
virtualHosts = {
|
||||
"matrix.${domain}".extraConfig = ''
|
||||
reverse_proxy /_matrix/* http://127.0.0.1:8008
|
||||
reverse_proxy /_synapse/client/* http://127.0.0.1:8008
|
||||
reverse_proxy /client/* http://127.0.0.1:8008
|
||||
reverse_proxy /_matrix/client/unstable/org.matrix.msc3575/sync/* http://127.0.0.1:8008
|
||||
reverse_proxy /_synapse/admin/* http://127.0.0.1:8008
|
||||
'';
|
||||
# Add `reverse_proxy /_synapse/admin/* http://127.0.0.1:8008` to allow access to the admin API
|
||||
|
||||
"mas.${domain}".extraConfig = ''
|
||||
reverse_proxy http://127.0.0.1:8086
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
6
hosts/naos/caddy.nix
Normal file
6
hosts/naos/caddy.nix
Normal file
@@ -0,0 +1,6 @@
|
||||
{ ... }: {
|
||||
# services.caddy = {
|
||||
# enable = true;
|
||||
# };
|
||||
# networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
}
|
38
hosts/naos/default.nix
Normal file
38
hosts/naos/default.nix
Normal file
@@ -0,0 +1,38 @@
|
||||
{ lib, config, ... }: {
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
boot.initrd.availableKernelModules = [
|
||||
"ata_piix"
|
||||
"usb_storage"
|
||||
"usbhid"
|
||||
"sd_mod"
|
||||
];
|
||||
|
||||
age.secrets.naos_userasdf_password = {
|
||||
rekeyFile = ./secrets/password.age;
|
||||
owner = "userasdf";
|
||||
group = "users";
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
n.host = {
|
||||
hardware.cpu = "intel";
|
||||
bootloader = "sysdboot";
|
||||
|
||||
hostId = "553fb274";
|
||||
users."userasdf" = lib.mkUser config.age.secrets.naos_userasdf_password.path true;
|
||||
defaultUser = "userasdf";
|
||||
types = [ "server" ];
|
||||
};
|
||||
|
||||
imports = [
|
||||
(lib.fs.zfs "/nix" "rpool/nix" null)
|
||||
(lib.fs.luks "cryptroot"
|
||||
"/dev/disk/by-partuuid/ed673238-50b1-4ebf-b6fc-4a25568917c6"
|
||||
{ allowDiscards = true; # Used if primary device is a SSD
|
||||
preLVM = true; })
|
||||
|
||||
(lib.fs.tmpfs "/" "none" [ "mode=755" "size=30%" ])
|
||||
(lib.fs.vfat "/boot" "/dev/disk/by-uuid/CDA1-7D4A" null)
|
||||
];
|
||||
}
|
16
hosts/naos/jellyfin.nix
Normal file
16
hosts/naos/jellyfin.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{ pkgs, ... }: {
|
||||
# imp.dirs = [ "/nix/persist/services/jellyfin" ];
|
||||
# services.jellyfin = {
|
||||
# enable = true;
|
||||
# dataDir = "/nix/persist/films";
|
||||
# configDir = "/nix/persist/services/jellyfin/cfg";
|
||||
# cacheDir = "/nix/persist/services/jellyfin/cache";
|
||||
# logDir = "/nix/persist/services/jellyfin/log";
|
||||
# openFirewall = false;
|
||||
# };
|
||||
# environment.systemPackages = [
|
||||
# pkgs.jellyfin
|
||||
# pkgs.jellyfin-web
|
||||
# pkgs.jellyfin-ffmpeg
|
||||
# ];
|
||||
}
|
19
hosts/naos/luks.nix
Normal file
19
hosts/naos/luks.nix
Normal file
@@ -0,0 +1,19 @@
|
||||
{ ... }: {
|
||||
# boot.kernelParams = [ "ip=dhcp" ];
|
||||
boot.initrd = {
|
||||
availableKernelModules = [ "r8169" ];
|
||||
network = {
|
||||
enable = true;
|
||||
udhcpc.enable = true;
|
||||
ssh = {
|
||||
enable = true;
|
||||
port = 22;
|
||||
authorizedKeys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDEDqpSiQpbSsClh6UGb7Z2DA1Hy+EyePzTy+5hEVD/A" ];
|
||||
hostKeys = [ "/nix/keys/identity" ];
|
||||
};
|
||||
postCommands = ''
|
||||
echo 'cryptsetup-askpass || echo "Unlock was successful; exiting SSH session" && exit 1' >> /root/.profile
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
7
hosts/naos/secrets/password.age
Normal file
7
hosts/naos/secrets/password.age
Normal file
@@ -0,0 +1,7 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 8IT6eg a5gQkLDKM9tbEe0ZSqRKjLz7u0iOUwaxVeetTjTkbDU
|
||||
w4V3IBC/MC7Pxn/92aTLNp24uZz623vEUa9wK5pS0wk
|
||||
-> @Mkd`z-grease ?mx2I=/d
|
||||
XDeroqJTqWJmt+aS2vLar9WtRzG3a2SlKoTwCx6s
|
||||
--- ml0i3EekhNXcxocnc5Z+RQp4t9bo8qUZRAQJeWw4soE
|
||||
7
|
41
hosts/phoenix/chromium.nix
Normal file
41
hosts/phoenix/chromium.nix
Normal file
@@ -0,0 +1,41 @@
|
||||
{ pkgs, ... }: {
|
||||
hm = {
|
||||
programs.chromium = {
|
||||
enable = true;
|
||||
package = pkgs.ungoogled-chromium;
|
||||
commandLineArgs = [
|
||||
"--enable-features=WebUIDarkMode,OzonePlatform,EncryptedClientHello,TouchpadOverscrollHistoryNavigation,VaapiVideoDecoder,WebAssembly"
|
||||
"--disable-features=UserAgentClientHint"
|
||||
"--force-webrtc-ip-handling-policy=default_public_interface_only"
|
||||
"--force-dark-mode"
|
||||
"--disable-beforeunload"
|
||||
"--disable-search-engine-collection"
|
||||
"--extension-mime-request-handling=download-as-regular-file"
|
||||
"--disable-top-sites"
|
||||
"--disable-file-system"
|
||||
"--disable-default-apps"
|
||||
"--disable-grease-tls"
|
||||
"--ozone-platform=wayland"
|
||||
# ''--js-flags="--jitless"''
|
||||
''
|
||||
--user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"''
|
||||
''
|
||||
--http-accept-header="text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"''
|
||||
"--fingerprinting-canvas-image-data-noise"
|
||||
"--fingerprinting-canvas-measuretext-noise"
|
||||
"--fingerprinting-client-rects-noise"
|
||||
"--enable-quic"
|
||||
"--gtk-version=4"
|
||||
];
|
||||
# extensions = [
|
||||
#
|
||||
# ];
|
||||
};
|
||||
};
|
||||
imp.home.dirs = [ ".config/chromium" ];
|
||||
|
||||
nodes.phoenix.hardware.graphics.extraPackages = with pkgs; [
|
||||
nvidia-vaapi-driver
|
||||
libvdpau-va-gl
|
||||
];
|
||||
}
|
35
hosts/phoenix/default.nix
Normal file
35
hosts/phoenix/default.nix
Normal file
@@ -0,0 +1,35 @@
|
||||
{ lib, config, ... }: {
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usb_storage" "sd_mod" ];
|
||||
|
||||
age.secrets.phoenix_user_password = {
|
||||
rekeyFile = ./secrets/password.age;
|
||||
owner = "user";
|
||||
group = "users";
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
n.host = {
|
||||
hardware.cpu = "amd";
|
||||
bootloader = "lanzaboote";
|
||||
|
||||
hostId = "053c9578";
|
||||
users."user" = lib.mkUser config.age.secrets.phoenix_user_password.path true;
|
||||
defaultUser = "user";
|
||||
types = [ "desktop" ];
|
||||
};
|
||||
|
||||
imports = [
|
||||
(lib.fs.zfs "/nix" "rpool/nix" null)
|
||||
(lib.fs.luks "crypted"
|
||||
"/dev/disk/by-partuuid/0f262ab8-0aad-5f42-8ee5-493f68465aff"
|
||||
{ header = "/dev/disk/by-partuuid/11ca2df8-17c3-47a2-8ba0-49976273008f";
|
||||
allowDiscards = true; # Used if primary device is a SSD
|
||||
preLVM = true; })
|
||||
|
||||
(lib.fs.tmpfs "/" "none" [ "mode=755" "size=40%" ])
|
||||
(lib.fs.vfat "/boot" "/dev/disk/by-uuid/6D12-D841" null)
|
||||
(lib.fs.swap "/dev/disk/by-uuid/391c74f2-8703-4d17-af3b-1f8087f8ad0a")
|
||||
];
|
||||
}
|
100
hosts/phoenix/games.nix
Normal file
100
hosts/phoenix/games.nix
Normal file
@@ -0,0 +1,100 @@
|
||||
{ pkgs, lib, inputs, username, ... }: {
|
||||
hm.home.packages = (with pkgs; [
|
||||
# steam-tui
|
||||
steamcmd
|
||||
steam-run
|
||||
xwayland-satellite
|
||||
# wineWow64Packages.waylandFull
|
||||
bottles
|
||||
|
||||
glfw3-minecraft
|
||||
prismlauncher
|
||||
|
||||
openspades
|
||||
# zeroad
|
||||
superTuxKart
|
||||
wine64Packages.waylandFull
|
||||
(pkgs.writeShellScriptBin "rungame"
|
||||
''export __NV_PRIME_RENDER_OFFLOAD=1
|
||||
export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0
|
||||
export __GLX_VENDOR_LIBRARY_NAME=nvidia
|
||||
export __VK_LAYER_NV_optimus=NVIDIA_only
|
||||
exec "${pkgs.gamemode}/bin/gamemoderun" "$@"''
|
||||
)
|
||||
]) ++ (
|
||||
let
|
||||
mkNixPak = inputs.nixpak.lib.nixpak { inherit pkgs; inherit lib; };
|
||||
mkGameRunner' = name: rw': exe: network: mkNixPak {
|
||||
config = { sloth, ... }:
|
||||
let runfile = pkgs.writeScriptBin name ''
|
||||
${exe}
|
||||
'';
|
||||
in {
|
||||
dbus.enable = false;
|
||||
gpu.enable = true;
|
||||
gpu.provider = "nixos";
|
||||
bubblewrap = {
|
||||
inherit network;
|
||||
sockets.pulse = true;
|
||||
sockets.wayland = true;
|
||||
bind.rw = rw';
|
||||
bind.ro = [ "/etc" "/sys" "/lib64" "${runfile}" "/bin" ];
|
||||
tmpfs = [ "/tmp" ];
|
||||
bind.dev = [ "/dev/nvidia0" "/dev/nvidiactl" "/dev/nvidia-modeset" ];
|
||||
};
|
||||
app.package = runfile;
|
||||
};
|
||||
};
|
||||
|
||||
mkWineGameRunner' = name: workdir: exe: network: (mkGameRunner' name [workdir]
|
||||
''WINEPREFIX="${workdir}/wineprefix" ${lib.getExe pkgs.wine64Packages.waylandFull} ${workdir}/${exe}'' network);
|
||||
mkSteamrunGameRunner' = name: workdir: exe: network: (mkGameRunner' name [workdir]
|
||||
''DISPLAY=:0 ${lib.getExe pkgs.steam-run} ${workdir}/${exe}'' network);
|
||||
mkWineGameRunner = name: workdir: exe: [
|
||||
((mkWineGameRunner' "${name}-run" workdir exe false).config.script)
|
||||
((mkWineGameRunner' "${name}-run-inet" workdir exe true).config.script)
|
||||
];
|
||||
mkSteamrunGameRunner = name: workdir: exe: [
|
||||
(mkSteamrunGameRunner' "${name}-run" workdir exe false).config.script
|
||||
(mkSteamrunGameRunner' "${name}-run-inet" workdir exe true).config.script
|
||||
];
|
||||
|
||||
dirs = ["/home/${username}/Games" "/mnt/gd" "/home/${username}/.wine"];
|
||||
in
|
||||
(mkWineGameRunner "littlenighmares" "/home/${username}/Games/LittleNightmares/1" "game_info/data/Atlas/Binaries/Win64/LittleNightmares.exe")
|
||||
|
||||
# (mkGameRunner' "wine-basic-run" dirs "${lib.getExe pkgs.wine64Packages.waylandFull} $@" false ).config.script
|
||||
# (mkGameRunner' "wine-basic-run-inet" dirs "${lib.getExe pkgs.wine64Packages.waylandFull} $@" true ).config.script
|
||||
);
|
||||
|
||||
programs = {
|
||||
steam = {
|
||||
enable = true;
|
||||
remotePlay.openFirewall = false; # Open ports in the firewall for Steam Remote Play
|
||||
# extest.enable = true;
|
||||
};
|
||||
|
||||
gamemode = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
boot.kernel.sysctl."kernel.unprivileged_userns_clone" = true;
|
||||
|
||||
imp.home.dirs = [
|
||||
".local/share/Steam" ".steam"
|
||||
".local/share/bottles"
|
||||
".local/share/PrismLauncher"
|
||||
".local/share/Paradox Interactive"
|
||||
".local/share/openspades"
|
||||
];
|
||||
|
||||
n.misc.unfreePackages = [
|
||||
"steam"
|
||||
"steam-unwrapped"
|
||||
"steamcmd"
|
||||
"steam-run"
|
||||
];
|
||||
}
|
139
hosts/phoenix/gnome.nix
Normal file
139
hosts/phoenix/gnome.nix
Normal file
@@ -0,0 +1,139 @@
|
||||
{ pkgs, lib, ... }: {
|
||||
services.xserver.desktopManager.gnome.enable = true;
|
||||
environment.gnome.excludePackages = (with pkgs; [
|
||||
gnome-tour
|
||||
yelp # Help view
|
||||
# ]) ++ (with pkgs.gnome; [
|
||||
tali # poker game
|
||||
iagno # go game
|
||||
hitori # sudoku game
|
||||
atomix # puzzle game
|
||||
]);
|
||||
programs.dconf.enable = true;
|
||||
|
||||
imp.home.dirs = [ ".local/share/keyrings" ];
|
||||
|
||||
hm = let
|
||||
extensions = with pkgs.gnomeExtensions; [
|
||||
# gnomeExtensions.user-themes
|
||||
blur-my-shell
|
||||
pop-shell
|
||||
vitals
|
||||
];
|
||||
# inherit (lib.hm.gvariant) mkTuple;
|
||||
in {
|
||||
dconf.settings = {
|
||||
"org/gnome/desktop/input-sources" = {
|
||||
# sources = [ (mkTuple [ "xkb" "us" ]) (mkTuple [ "xkb" "by+ru" ]) ];
|
||||
xkb-options = [ "grp:caps_toggle" "compose:rctrl" ];
|
||||
};
|
||||
|
||||
"org/gnome/desktop/interface" = {
|
||||
color-scheme = "prefer-dark";
|
||||
enable-hot-corners = false;
|
||||
# gtk-theme = "adw-gtk3-dark";
|
||||
show-battery-percentage = true;
|
||||
toolkit-accessibility = false;
|
||||
};
|
||||
|
||||
"org/gnome/desktop/peripherals/touchpad" = {
|
||||
tap-to-click = true;
|
||||
two-finger-scrolling-enabled = true;
|
||||
};
|
||||
|
||||
"org/gnome/desktop/wm/keybindings" = let
|
||||
binds = map (x: { "switch-to-workspace-${toString x}" = [ "<Super>${toString x}" ];
|
||||
"move-to-workspace-${toString x}" = [ "<Shift><Super>${toString x}" ]; }) [1 2 3 4 5 6 7 8 9];
|
||||
in lib.mkMerge (binds ++ [{
|
||||
close = [ "<Shift><Super>q" ];
|
||||
minimize = [ "<Super>minus" ];
|
||||
switch-input-source = [];
|
||||
switch-input-source-backward = [];
|
||||
toggle-fullscreen = [ "<Super>F11" ];
|
||||
}]);
|
||||
|
||||
"org/gnome/mutter" = {
|
||||
dynamic-workspaces = false;
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/color" = {
|
||||
night-light-enabled = true;
|
||||
night-light-schedule-automatic = true;
|
||||
night-light-schedule-from = 20.0;
|
||||
night-light-schedule-to = 9.0;
|
||||
night-light-temperature = 3469;
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys" = {
|
||||
calculator = [ "Calculator" ];
|
||||
custom-keybindings = [ "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/" ];
|
||||
mic-mute = [ "AudioMicMute" ];
|
||||
screensaver = [ "ScreenSaver" ];
|
||||
volume-down = [ "AudioLowerVolume" ];
|
||||
volume-mute = [ "AudioMute" ];
|
||||
volume-up = [ "AudioRaiseVolume" ];
|
||||
www = [ "<Super>b" ];
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
|
||||
binding = "<Super>Return";
|
||||
command = lib.getExe pkgs.gnome-terminal;
|
||||
name = "GNOME Terminal";
|
||||
};
|
||||
|
||||
"org/gnome/shell/extensions/pop-shell" = {
|
||||
active-hint = false;
|
||||
fullscreen-launcher = false;
|
||||
mouse-cursor-follows-active-window = true;
|
||||
show-skip-taskbar = true;
|
||||
show-title = true;
|
||||
smart-gaps = true;
|
||||
snap-to-grid = true;
|
||||
stacking-with-mouse = true;
|
||||
tile-by-default = true;
|
||||
tile-enter = [ "<Super>r" ];
|
||||
};
|
||||
|
||||
"org/gnome/shell/extensions/vitals" = {
|
||||
alphabetize = false;
|
||||
fixed-widths = true;
|
||||
hide-icons = false;
|
||||
hide-zeros = true;
|
||||
hot-sensors = [ "_memory_usage_" "_processor_usage_" "_storage_free_" ];
|
||||
memory-measurement = 1;
|
||||
menu-centered = false;
|
||||
position-in-panel = 2;
|
||||
};
|
||||
|
||||
"org/gnome/shell/keybindings" = {
|
||||
toggle-application-view = [ "<Super>d" ];
|
||||
toggle-quick-settings = [ "<Shift><Super>d" ];
|
||||
};
|
||||
|
||||
# "org/gnome/shell.favorite-apps" = [
|
||||
# # "chromium.desktop"
|
||||
# "org.gnome.terminal.desktop"
|
||||
# "org.gnome.nautilus.desktop"
|
||||
# ];
|
||||
|
||||
"org/gnome/shell" = {
|
||||
disable-user-extensions = false;
|
||||
enabled-extensions = map (x: x.extensionUuid) extensions;
|
||||
};
|
||||
};
|
||||
|
||||
home = {
|
||||
packages = (with pkgs; [
|
||||
# pinentry-gnome # maybe I'll delete it
|
||||
# cava
|
||||
adw-gtk3
|
||||
dconf
|
||||
gnome-tweaks
|
||||
]) ++ extensions;
|
||||
|
||||
sessionVariables.GTK_THEME = "adw-gtk3-dark";
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc."lemurs/wayland/gnome".source = pkgs.writeShellScript "gnome.sh" "${pkgs.gnome-shell}/bin/niri";
|
||||
}
|
41
hosts/phoenix/gpu.nix
Normal file
41
hosts/phoenix/gpu.nix
Normal file
@@ -0,0 +1,41 @@
|
||||
{ lib, config, ... }: {
|
||||
boot.initrd.kernelModules = [ "nvidia" ];
|
||||
boot.extraModulePackages = [ config.boot.kernelPackages.nvidia_x11 ];
|
||||
services.xserver.videoDrivers = [ "nvidia" "modesetting" ];
|
||||
|
||||
hardware = {
|
||||
nvidia = {
|
||||
modesetting.enable = true;
|
||||
powerManagement.enable = false;
|
||||
powerManagement.finegrained = false;
|
||||
open = false; # Use open kernel module, not nouveau
|
||||
nvidiaSettings = true;
|
||||
package = config.boot.kernelPackages.nvidiaPackages.stable;
|
||||
# package = config.boot.kernelPackages.nvidiaPackages.stable.override {
|
||||
# disable32Bit = true;
|
||||
# };
|
||||
|
||||
|
||||
prime = {
|
||||
amdgpuBusId = "PCI:5:0:0";
|
||||
nvidiaBusId = "PCI:1:0:0";
|
||||
|
||||
offload = {
|
||||
enable = true;
|
||||
enableOffloadCmd = true;
|
||||
};
|
||||
reverseSync.enable = lib.mkForce false;
|
||||
sync.enable = lib.mkForce false;
|
||||
};
|
||||
};
|
||||
|
||||
graphics.enable = true; # OpenGL
|
||||
};
|
||||
|
||||
nixpkgs.config.nvidia.acceptLicense = true;
|
||||
n.misc.unfreePackages = [
|
||||
"nvidia-x11"
|
||||
"nvidia-settings"
|
||||
"nvidia-persistenced"
|
||||
];
|
||||
}
|
12
hosts/phoenix/obsidian.nix
Normal file
12
hosts/phoenix/obsidian.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{ pkgs, ... }: {
|
||||
# nixpkgs.overlays = [
|
||||
# (final: prev: {
|
||||
# electron = final.electron_33-bin;
|
||||
# electron_34 = final.electron_33-bin;
|
||||
# })
|
||||
# ];
|
||||
|
||||
n.misc.unfreePackages = [ "obsidian" ];
|
||||
hm.home.packages = [ pkgs.obsidian ];
|
||||
imp.home.dirs = [ ".config/obsidian" "Knowledge" ];
|
||||
}
|
4
hosts/phoenix/postgres.nix
Normal file
4
hosts/phoenix/postgres.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ ... }: {
|
||||
services.postgresql.enable = true;
|
||||
imp.dirs = [ "/var/lib/postgresql" ];
|
||||
}
|
9
hosts/phoenix/secrets/password.age
Normal file
9
hosts/phoenix/secrets/password.age
Normal file
@@ -0,0 +1,9 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 8IT6eg zOyK3R9L2wLc3j24BeClZfV0qreGhCUEAKe5I/ek/RQ
|
||||
p8Cs+J6Wr2gqbuxk9pBHzswsVu3hFBsi69fkxvGxNIE
|
||||
-> zh:p3}L;-grease 0r+81 g
|
||||
Fd+eCNxUNT6oCVS+ljiPObC9d0oIZQSwkXIhIaEyugAdMBRIfvniO9nkHiHn
|
||||
--- TsFWr7WQ1ublsHFf0In5XgH+THVqE9w7B3AWv4WthTo
|
||||
+,
|
||||
|
||||
ձ<EFBFBD>7<EFBFBD><EFBFBD><EFBFBD><EFBFBD>>f<<3C><><EFBFBD>5<EFBFBD>^<5E>Y<EFBFBD><59>w<EFBFBD>Ȁ<EFBFBD>9m|\͉?<3F><>\<1A>kaVk<56>W<>ܒo<DC92><6F>S*<2A>q.<2E><>]`<60>[6<>5,Mϟ<4D><CF9F>ZƊB<><42><EFBFBD>di4<69><34>җ<EFBFBD><D297>N<EFBFBD><4E>d<EFBFBD>
|
36
hosts/tureis/default.nix
Normal file
36
hosts/tureis/default.nix
Normal file
@@ -0,0 +1,36 @@
|
||||
{ lib, config, ... }: {
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
|
||||
boot.initrd.kernelModules = [ "usb_storage" ];
|
||||
boot.kernelModules = [ "usb_storage" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
# age.secrets.tureis_user_password = {
|
||||
# rekeyFile = ./secrets/password.age;
|
||||
# owner = "user";
|
||||
# group = "users";
|
||||
# mode = "0400";
|
||||
# };
|
||||
|
||||
n.host = {
|
||||
# hardware.cpu = "intel"; # TODO
|
||||
bootloader = "lanzaboote";
|
||||
|
||||
hostId = "db4713ee";
|
||||
users."user" = lib.mkUser "" true;
|
||||
defaultUser = "user";
|
||||
types = [ "desktop" ];
|
||||
};
|
||||
|
||||
imports = [
|
||||
(lib.fs.luks "nix" "/dev/sda4" {})
|
||||
|
||||
(lib.fs.tmpfs "/" "none" [ "mode=755" "size=40%" ])
|
||||
(lib.fs.vfat "/boot" "/dev/disk/by-uuid/5B0A-68EA" [ "fmask=0022" "dmask=0022" ])
|
||||
(lib.fs.ext4 "/nix" "/dev/mapper/nix" null)
|
||||
];
|
||||
|
||||
boot.initrd.supportedFilesystems.vfat = true;
|
||||
}
|
9
hosts/tureis/secrets/password.age
Normal file
9
hosts/tureis/secrets/password.age
Normal file
@@ -0,0 +1,9 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 8IT6eg zOyK3R9L2wLc3j24BeClZfV0qreGhCUEAKe5I/ek/RQ
|
||||
p8Cs+J6Wr2gqbuxk9pBHzswsVu3hFBsi69fkxvGxNIE
|
||||
-> zh:p3}L;-grease 0r+81 g
|
||||
Fd+eCNxUNT6oCVS+ljiPObC9d0oIZQSwkXIhIaEyugAdMBRIfvniO9nkHiHn
|
||||
--- TsFWr7WQ1ublsHFf0In5XgH+THVqE9w7B3AWv4WthTo
|
||||
+,
|
||||
|
||||
ձ<EFBFBD>7<EFBFBD><EFBFBD><EFBFBD><EFBFBD>>f<<3C><><EFBFBD>5<EFBFBD>^<5E>Y<EFBFBD><59>w<EFBFBD>Ȁ<EFBFBD>9m|\͉?<3F><>\<1A>kaVk<56>W<>ܒo<DC92><6F>S*<2A>q.<2E><>]`<60>[6<>5,Mϟ<4D><CF9F>ZƊB<><42><EFBFBD>di4<69><34>җ<EFBFBD><D297>N<EFBFBD><4E>d<EFBFBD>
|
5
lib/default.nix
Normal file
5
lib/default.nix
Normal file
@@ -0,0 +1,5 @@
|
||||
final: prev: {
|
||||
fs = import ./fs.nix final prev;
|
||||
mkSecret = import ./mkSecret.nix;
|
||||
}
|
||||
// (import ./mkUser.nix { lib = final; })
|
24
lib/fs.nix
Normal file
24
lib/fs.nix
Normal file
@@ -0,0 +1,24 @@
|
||||
final: prev:
|
||||
let
|
||||
filesystem = fsType: path: device: options: {
|
||||
fileSystems.${path} =
|
||||
{ inherit device fsType; }
|
||||
// final.optionalAttrs (options != null) { inherit options; };
|
||||
};
|
||||
|
||||
in {
|
||||
btrfs = filesystem "btrfs";
|
||||
ntfs = filesystem "ntfs-3g";
|
||||
ext4 = filesystem "ext4";
|
||||
vfat = filesystem "vfat";
|
||||
zfs = filesystem "zfs";
|
||||
tmpfs = filesystem "tmpfs";
|
||||
|
||||
swap = device: {swapDevices = [{inherit device;}];};
|
||||
|
||||
luks = mapper: device: additional: {
|
||||
boot.initrd.luks.devices.${mapper} = {
|
||||
inherit device;
|
||||
} // additional;
|
||||
};
|
||||
}
|
5
lib/mkSecret.nix
Normal file
5
lib/mkSecret.nix
Normal file
@@ -0,0 +1,5 @@
|
||||
group: {
|
||||
generator.script = "alnum";
|
||||
mode = "440";
|
||||
inherit group;
|
||||
}
|
8
lib/mkUser.nix
Normal file
8
lib/mkUser.nix
Normal file
@@ -0,0 +1,8 @@
|
||||
{ lib }: {
|
||||
mkUser = password: wheel: {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "video" "libvirtd" "lp" (if wheel then "wheel" else "") ];
|
||||
} // (if (lib.hasPrefix "/" password)
|
||||
then {hashedPasswordFile = password;}
|
||||
else {hashedPassword = password;});
|
||||
}
|
35
modules/desktop/apps.nix
Normal file
35
modules/desktop/apps.nix
Normal file
@@ -0,0 +1,35 @@
|
||||
{ pkgs, ... }: {
|
||||
hm.home.packages = with pkgs; [
|
||||
# qtox
|
||||
# jami
|
||||
# session-desktop
|
||||
# briar-desktop
|
||||
dino
|
||||
# retroshare
|
||||
# mumble
|
||||
telegram-desktop
|
||||
thunderbird
|
||||
# fractal
|
||||
|
||||
keepassxc
|
||||
monero-gui
|
||||
libreoffice-fresh
|
||||
anki
|
||||
|
||||
playerctl
|
||||
android-tools
|
||||
libqalculate
|
||||
deploy-rs
|
||||
|
||||
mpv
|
||||
];
|
||||
|
||||
imp.home.dirs = [
|
||||
".local/share/TelegramDesktop"
|
||||
".local/share/fractal" ".cache/fractal"
|
||||
".cache/keepassxc" ".config/keepassxc"
|
||||
".config/qalculate"
|
||||
".local/share/Anki2" ".local/share/Anki"
|
||||
".local/share/dino"
|
||||
];
|
||||
}
|
7
modules/desktop/avahi.nix
Normal file
7
modules/desktop/avahi.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
{ ... }: {
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
nssmdns4 = true;
|
||||
nssmdns6 = true;
|
||||
};
|
||||
}
|
29
modules/desktop/bluetooth.nix
Normal file
29
modules/desktop/bluetooth.nix
Normal file
@@ -0,0 +1,29 @@
|
||||
{ pkgs, ... }: {
|
||||
hardware.bluetooth = {
|
||||
enable = true;
|
||||
settings = {
|
||||
General = {
|
||||
Enable = "Source,Sink,Media,Socket";
|
||||
};
|
||||
Policy = {
|
||||
AutoEnable = "true";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
imp.dirs = [ "/var/lib/bluetooth" ];
|
||||
|
||||
hm = {
|
||||
home.packages = with pkgs; [ bluetuith ];
|
||||
systemd.user.enable = true;
|
||||
systemd.user.services.mpris-proxy = {
|
||||
Unit = {
|
||||
Description = "Mpris proxy";
|
||||
After = [ "bluetooth.target" "sound.target" ];
|
||||
};
|
||||
Service.ExecStart = "${pkgs.bluez}/bin/mpris-proxy";
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
imp.home.files = [ ".cache/.bluetoothctl_history" ];
|
||||
}
|
29
modules/desktop/cinny.nix
Executable file
29
modules/desktop/cinny.nix
Executable file
@@ -0,0 +1,29 @@
|
||||
{ lib, pkgs, ... }: {
|
||||
services.caddy = {
|
||||
enable = lib.mkDefault true;
|
||||
virtualHosts."http://localhost:1989".extraConfig = ''
|
||||
encode zstd gzip
|
||||
root * ${pkgs.cinny}
|
||||
|
||||
|
||||
file_server
|
||||
@index {
|
||||
not path /index.html
|
||||
not path /public/*
|
||||
not path /assets/*
|
||||
|
||||
not path /config.json
|
||||
|
||||
not path /manifest.json
|
||||
not path /pdf.worker.min.js
|
||||
not path /olm.wasm
|
||||
not path /sw.js
|
||||
|
||||
path /*
|
||||
}
|
||||
|
||||
rewrite /*/olm.wasm /olm.wasm
|
||||
rewrite @index /index.html
|
||||
'';
|
||||
};
|
||||
}
|
36
modules/desktop/cups.nix
Normal file
36
modules/desktop/cups.nix
Normal file
@@ -0,0 +1,36 @@
|
||||
{ pkgs, username, ... }: {
|
||||
services.printing = {
|
||||
enable = true;
|
||||
drivers = [
|
||||
pkgs.splix # Xerox Phaser 3117
|
||||
pkgs.pantum-driver # Pantum M6500W
|
||||
];
|
||||
};
|
||||
hardware.printers = {
|
||||
ensurePrinters = [
|
||||
{
|
||||
name = "Pantum";
|
||||
location = "Home";
|
||||
deviceUri = "ipps://pantum._ipps._tcp.local/";
|
||||
model = "Pantum/Pantum-M6500W-Series.ppd";
|
||||
ppdOptions = {
|
||||
PageSize = "A4";
|
||||
};
|
||||
}
|
||||
];
|
||||
ensureDefaultPrinter = "Pantum";
|
||||
};
|
||||
|
||||
services.saned.enable = true;
|
||||
hardware.sane = {
|
||||
enable = true;
|
||||
extraBackends = [ pkgs.pantum-driver pkgs.sane-airscan ];
|
||||
};
|
||||
services.udev.packages = [ pkgs.sane-airscan ];
|
||||
|
||||
n.misc.unfreePackages = [
|
||||
"pantum-driver-1.1.123"
|
||||
"pantum-driver"
|
||||
];
|
||||
users.users.${username}.extraGroups = [ "scanner" "lp" ];
|
||||
}
|
133
modules/desktop/firefox.nix
Normal file
133
modules/desktop/firefox.nix
Normal file
@@ -0,0 +1,133 @@
|
||||
{ inputs, pkgs, ... }: {
|
||||
n.misc.defaults.firefox = [
|
||||
"text/html"
|
||||
"x-scheme-handler/http"
|
||||
"x-scheme-handler/https"
|
||||
"application/pdf"
|
||||
];
|
||||
|
||||
hm = {
|
||||
imports = [ inputs.arkenfox.hmModules.arkenfox ];
|
||||
stylix.targets.firefox = {
|
||||
enable = true;
|
||||
profileNames = [ "default" ];
|
||||
};
|
||||
|
||||
programs.firefox = {
|
||||
enable = true;
|
||||
# arkenfox.enable = true; # TODO: configure arkenfox
|
||||
|
||||
profiles.default = {
|
||||
id = 0;
|
||||
isDefault = true;
|
||||
|
||||
search = {
|
||||
default = "ddg";
|
||||
engines =
|
||||
let
|
||||
getIcon = url: sha256: pkgs.fetchurl { inherit url sha256; };
|
||||
nixicon = getIcon "https://nixos.org/favicon.ico" "sha256-58CkYxFA9Baioz3+avCQocft/AW9sgOLTPV71gxKD2g=";
|
||||
in {
|
||||
|
||||
# Github
|
||||
"GitHub" = {
|
||||
urls = [ { template = "https://github.com/search?q={searchTerms}"; } ];
|
||||
icon = getIcon "https://github.githubassets.com/favicons/favicon-dark.svg" "sha256-qu/d9ftvsntplFuxw9RFL8BpI9b2g5b6xfeGw6Ekh6w=";
|
||||
definedAliases = [ "@github" "@gh" ];
|
||||
};
|
||||
|
||||
# Knihi.com
|
||||
"Knihi.com" = {
|
||||
urls = [ { template = "https://knihi.com/search.html#{searchTerms}"; } ];
|
||||
icon = getIcon "https://knihi.com/img/logo.svg" "sha256-wTpuVFhstRE6HXSWvrom49Wl0NNEw7jB+3dQDcLEWFI=";
|
||||
definedAliases = [ "@knihi" "@knihi.com" ];
|
||||
};
|
||||
|
||||
# NixOS Packages
|
||||
"NixOS Packages" = {
|
||||
urls = [ { template = "https://search.nixos.org/packages?channel=unstable&query={searchTerms}"; } ];
|
||||
icon = nixicon;
|
||||
definedAliases = [ "@nixpkgs" "@np" "@pkg" ];
|
||||
};
|
||||
|
||||
# NixOS Options
|
||||
"NixOS Options" = {
|
||||
urls = [ { template = "https://search.nixos.org/options?channel=unstable&query={searchTerms}"; } ];
|
||||
icon = nixicon;
|
||||
definedAliases = [ "@nixopts" "@no" "@opt" ];
|
||||
};
|
||||
|
||||
# NixOS Wiki
|
||||
"NixOS Wiki" = {
|
||||
urls = [ { template = "https://nixos.wiki/index.php?search={searchTerms}"; } ];
|
||||
icon = getIcon "https://nixos.wiki/favicon.png" "sha256-Sw3Sysk6x/xDTwz6q2/HWaCZtffapsAuMMFjYN0FhIk=";
|
||||
definedAliases = [ "@nixoswiki" "@nw" ];
|
||||
};
|
||||
|
||||
# Home Manager options
|
||||
"Home Manager Options" = {
|
||||
urls = [ { template = "https://home-manager-options.extranix.com/?query={searchTerms}"; } ];
|
||||
icon = getIcon "https://nixos.wiki/favicon.png" "sha256-Sw3Sysk6x/xDTwz6q2/HWaCZtffapsAuMMFjYN0FhIk=";
|
||||
definedAliases = [ "@hm" ];
|
||||
};
|
||||
|
||||
# Noogle (nix-functions search)
|
||||
"Noogle" = {
|
||||
urls = [ { template = "https://noogle.dev/q?term={searchTerms}"; } ];
|
||||
icon = getIcon "https://noogle.dev/favicon.png" "sha256-5VjB+MeP1c25DQivVzZe77NRjKPkrJdYAd07Zm0nNVM=";
|
||||
definedAliases = [ "@noogle" "@f" "@l" "@func" ];
|
||||
};
|
||||
|
||||
# Rutracker
|
||||
"Rutracker" = {
|
||||
urls = [ { template = "https://rutracker.org/forum/tracker.php?nm={searchTerms}"; } ];
|
||||
icon = getIcon "https://rutracker.org/favicon.ico" "sha256-p6PGZMIvLUX38QL5LnHGDr0X1SfNes5JiRdh4WNj6Zg=";
|
||||
definedAliases = [ "@rutracker" "@rutr" "@torrent" "@tr" ];
|
||||
};
|
||||
|
||||
# Flibusta
|
||||
"Flibusta" = {
|
||||
urls = [ { template = "https://flibusta.is/booksearch?ask={searchTerms}"; } ];
|
||||
icon = getIcon "https://flibusta.is/sites/default/files/bluebreeze_favicon.ico" "sha256-Ksq+eviBPAVULOXOPAxhJJ5jx9iQqIiQ4dak9twng+I=";
|
||||
definedAliases = [ "@rutracker" "@rutr" "@torrent" "@tr" ];
|
||||
};
|
||||
|
||||
# Wiktionary
|
||||
"Wiktionary" = {
|
||||
urls = [ { template = "https://en.wiktionary.org/w/index.php?title=Special:Search&search={searchTerms}"; } ];
|
||||
icon = getIcon "https://en.wiktionary.org/static/favicon/piece.ico" "sha256-Mz5Z9nz+gPlNqo8SerFgQSAMN76557yWZp4rgbjkPv8=";
|
||||
definedAliases = [ "@wiktionary" "@w" ];
|
||||
};
|
||||
|
||||
# Verbum
|
||||
"Verbum" = {
|
||||
urls = [ { template = "https://verbum.by/?q={searchTerms}"; } ];
|
||||
icon = getIcon "https://verbum.by/statics/favicon.png" "sha256-/P3zuoHbL5Rb7MYxPeehVCmfoB/V73edTvGrHTA8hJ4=";
|
||||
definedAliases = [ "@verbum" "@v" ];
|
||||
};
|
||||
|
||||
# Sloŭnik.org
|
||||
"Slounik.org" = {
|
||||
urls = [ { template = "https://slounik.org/search?dict=&search={searchTerms}"; } ];
|
||||
icon = getIcon "https://slounik.org/icon.svg" "sha256-jDvQ0iNMZ8pFp6+uvzTBuEOuVstZP2t1+hzDDx7oCAk=";
|
||||
definedAliases = [ "@slounik" "@sl" ];
|
||||
};
|
||||
|
||||
# Youtube
|
||||
"Youtube" = {
|
||||
urls = [ { template = "https://www.youtube.com/results?search_query={searchTerms}"; } ];
|
||||
icon = getIcon "https://www.youtube.com/s/desktop/280a3f09/img/favicon.ico" "sha256-i7HQ+kOhdDbVndVG9vdMdtxEc13vdSLCLYAxFm24kR0=";
|
||||
definedAliases = [ "@youtube" "@yt" "@y" ];
|
||||
};
|
||||
|
||||
# Disable crap
|
||||
"bing".metaData.hidden = true;
|
||||
"google".metaData.hidden = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
imp.home.dirs = [ ".mozilla" ];
|
||||
}
|
54
modules/desktop/fish.nix
Normal file
54
modules/desktop/fish.nix
Normal file
@@ -0,0 +1,54 @@
|
||||
{ pkgs, config, ...}: {
|
||||
globals.hm = {
|
||||
programs.carapace = {
|
||||
enableFishIntegration = true;
|
||||
enable = true;
|
||||
};
|
||||
home.packages = with pkgs; [ grc fzf ];
|
||||
|
||||
# home.file.".config/fish/config.fish".force = lib.mkForce true;
|
||||
programs.fish = {
|
||||
enable = true;
|
||||
shellAliases = config.n.misc.aliases;
|
||||
|
||||
interactiveShellInit = ''
|
||||
set fish_greeting
|
||||
fish_vi_key_bindings
|
||||
'';
|
||||
|
||||
plugins = with pkgs.fishPlugins; [
|
||||
# Colorized command output
|
||||
{ name = "grc"; src = grc.src; }
|
||||
# Fzf integration
|
||||
{ name = "fzf"; src = fzf-fish.src; }
|
||||
{ name = "forgit"; src = forgit.src; }
|
||||
# Usage frequency-based directory jumping
|
||||
{ name = "z"; src = z.src; }
|
||||
];
|
||||
|
||||
functions = {
|
||||
fish_prompt = "string join '' -- (set_color --bold green) (prompt_login) (set_color normal) ' ['(prompt_pwd)']' (set_color green) (fish_git_prompt) ' '(fish_default_mode_prompt)\\n(set_color blue)'> '(set_color normal)";
|
||||
fish_mode_prompt = "";
|
||||
fish_default_mode_prompt = ''
|
||||
switch $fish_bind_mode
|
||||
case default
|
||||
set_color red
|
||||
echo '[N]'
|
||||
case insert
|
||||
set_color green
|
||||
echo '[I]'
|
||||
case replace_one
|
||||
set_color green
|
||||
echo '[R]'
|
||||
case visual
|
||||
set_color brmagenta
|
||||
echo '[V]'
|
||||
end
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
imp.home.dirs = [ ".local/share/fish" ];
|
||||
users.defaultUserShell = pkgs.fish;
|
||||
programs.fish.enable = true;
|
||||
}
|
28
modules/desktop/fonts.nix
Normal file
28
modules/desktop/fonts.nix
Normal file
@@ -0,0 +1,28 @@
|
||||
{ pkgs, ... }: {
|
||||
fonts = {
|
||||
packages = with pkgs; ([
|
||||
# fira-code
|
||||
# fira-code-symbols
|
||||
noto-fonts-emoji
|
||||
]
|
||||
++ (with nerd-fonts; [
|
||||
fira-code
|
||||
fira-sans
|
||||
fira-mono
|
||||
noto
|
||||
font-awesome
|
||||
cozette
|
||||
source-han-sans
|
||||
ubuntu
|
||||
]));
|
||||
|
||||
fontconfig = {
|
||||
defaultFonts = {
|
||||
monospace = ["FiraCode Nerd Font Mono" "Noto Color Emoji"];
|
||||
sansSerif = ["FiraCode Nerd Font" "Noto Color Emoji"];
|
||||
serif = ["FiraCode Nerd Font" "Noto Color Emoji"];
|
||||
emoji = ["Noto Color Emoji"];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
6
modules/desktop/foot.nix
Normal file
6
modules/desktop/foot.nix
Normal file
@@ -0,0 +1,6 @@
|
||||
{ ... }: {
|
||||
hm.programs.foot = {
|
||||
enable = true;
|
||||
server.enable = true;
|
||||
};
|
||||
}
|
10
modules/desktop/gpg.nix
Normal file
10
modules/desktop/gpg.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{ pkgs, ... }: {
|
||||
hm.programs.gpg.enable = true;
|
||||
|
||||
hm.services.gpg-agent = {
|
||||
enable = true;
|
||||
enableSshSupport = false;
|
||||
pinentry.package = pkgs.pinentry-tty;
|
||||
enableFishIntegration = true;
|
||||
};
|
||||
}
|
3
modules/desktop/gvfs.nix
Normal file
3
modules/desktop/gvfs.nix
Normal file
@@ -0,0 +1,3 @@
|
||||
{ ... }: {
|
||||
services.gvfs.enable = true;
|
||||
}
|
20
modules/desktop/loupe.nix
Normal file
20
modules/desktop/loupe.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{ pkgs, ... }: {
|
||||
hm.home.packages = with pkgs; [ loupe ];
|
||||
n.misc.defaults."org.gnome.Loupe" = [
|
||||
"image/avif"
|
||||
"image/bmp"
|
||||
"image/gif"
|
||||
"image/jp2"
|
||||
"image/jpeg"
|
||||
"image/jpg"
|
||||
"image/jpm"
|
||||
"image/jpx"
|
||||
"image/jxl"
|
||||
"image/png"
|
||||
"image/tiff"
|
||||
"image/vnd.microsoft.icon"
|
||||
"image/webp"
|
||||
"image/webp"
|
||||
"image/x-tga"
|
||||
];
|
||||
}
|
5
modules/desktop/network-manager.nix
Normal file
5
modules/desktop/network-manager.nix
Normal file
@@ -0,0 +1,5 @@
|
||||
{ username, ... }: {
|
||||
networking.networkmanager.enable = true;
|
||||
users.users.${username}.extraGroups = [ "networkmanager" "netdev" ];
|
||||
imp.dirs = [ "/etc/NetworkManager" "/var/lib/NetworkManager" ];
|
||||
}
|
290
modules/desktop/niri.nix
Normal file
290
modules/desktop/niri.nix
Normal file
@@ -0,0 +1,290 @@
|
||||
{ lib, pkgs, config, inputs, username, ... }: {
|
||||
imports = [ inputs.niri.nixosModules.niri ];
|
||||
hm.imports = [ inputs.ags.homeManagerModules.ags ];
|
||||
|
||||
nixpkgs.overlays = [
|
||||
inputs.niri.overlays.niri
|
||||
(final: prev: {
|
||||
c.niri = final.niri-unstable;
|
||||
})
|
||||
];
|
||||
|
||||
programs.light.enable = true;
|
||||
programs.niri = {
|
||||
enable = true;
|
||||
package = pkgs.c.niri;
|
||||
};
|
||||
|
||||
hm.home.packages = with pkgs; [ mako wofi wl-clipboard wl-clipboard-x11 swaybg swayidle swaylock yambar ];
|
||||
hm.programs.niri.settings = {
|
||||
environment = {
|
||||
QT_QPA_PLATFORM = "wayland";
|
||||
NIXOS_OZONE_WL = "1";
|
||||
GSK_RENDERER = "gl";
|
||||
};
|
||||
|
||||
input = {
|
||||
touchpad = {
|
||||
natural-scroll = false;
|
||||
scroll-method = "two-finger";
|
||||
tap = true;
|
||||
};
|
||||
|
||||
keyboard = {
|
||||
xkb = {
|
||||
layout = "pl,by(ru)";
|
||||
options = "grp:caps_toggle,compose:menu";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
spawn-at-startup = [
|
||||
{ command = [ "${lib.getExe pkgs.mako}" ]; }
|
||||
{ command = [ "${lib.getExe pkgs.xwayland-satellite}" ]; }
|
||||
{ command = [ "${lib.getExe pkgs.swaybg}" "--image" "/home/${username}/Pictures/Wallpapers/1.png" ]; }
|
||||
{ command = let
|
||||
swaylock = "${lib.getExe pkgs.swaylock} -f -c 000000";
|
||||
niri = lib.getExe pkgs.niri;
|
||||
light = lib.getExe pkgs.light;
|
||||
script = pkgs.writeShellScript "lockscript.sh"
|
||||
''
|
||||
${lib.getExe pkgs.swayidle} -w \
|
||||
lock '${swaylock} && ${niri} msg action power-off-monitors' \
|
||||
unlock '${niri} msg action power-on-monitors' \
|
||||
timeout 200 '${swaylock}' \
|
||||
timeout 210 '${niri} msg action power-off-monitors' \
|
||||
resume '${niri} msg action power-on-monitors' \
|
||||
timeout 195 '${light} -U 50' \
|
||||
resume '${light} -A 50' \
|
||||
before-sleep '${swaylock}'
|
||||
'';
|
||||
in [ "sh" "-e" "${script}" ];
|
||||
}
|
||||
{ command = [ "${lib.getExe pkgs.yambar}" ]; }
|
||||
];
|
||||
binds = with config.hm.lib.niri.actions; let
|
||||
workspaces = [1 2 3 4 5 6 7 8 9];
|
||||
tags-binds = map (x: { "Mod+${toString x}".action = focus-workspace x;
|
||||
"Mod+Shift+${toString x}".action = move-column-to-index x;
|
||||
}) workspaces;
|
||||
in lib.mkMerge (tags-binds ++ [{
|
||||
# Volume
|
||||
"XF86AudioRaiseVolume" = {
|
||||
action = spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.01+";
|
||||
allow-when-locked = true;
|
||||
};
|
||||
"XF86AudioLowerVolume".action = spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.01-";
|
||||
"XF86AudioMute".action = spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle";
|
||||
"XF86AudioMicMute".action = spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle";
|
||||
|
||||
"XF86Calculator".action = spawn "foot" "-e" "qalc";
|
||||
|
||||
"XF86MonBrightnessUp".action = spawn "${lib.getExe pkgs.light}" "-A" "2";
|
||||
"XF86MonBrightnessDown".action = spawn "${lib.getExe pkgs.light}" "-U" "2";
|
||||
"XF86ScreenSaver".action = let session = "loginctl session-status | awk '{ print $1 }' | head -n 1";
|
||||
in spawn "loginctl lock-session $(${session})";
|
||||
|
||||
|
||||
"Mod+Shift+Q".action = close-window;
|
||||
"Mod+Shift+E".action = quit;
|
||||
"Mod+Space".action = toggle-window-floating;
|
||||
"Mod+O".action = toggle-overview;
|
||||
"Mod+Slash".action = show-hotkey-overlay;
|
||||
"Mod+P".action = toggle-window-rule-opacity;
|
||||
|
||||
"Mod+Minus".action = set-column-width "-10%";
|
||||
"Mod+Equal".action = set-column-width "+10%";
|
||||
"Mod+Shift+Minus".action = set-window-height "-10%";
|
||||
"Mod+Shift+Equal".action = set-window-height "+10%";
|
||||
|
||||
"Mod+W".action = toggle-column-tabbed-display;
|
||||
"Mod+Ctrl+H".action = consume-or-expel-window-left;
|
||||
"Mod+Ctrl+L".action = consume-or-expel-window-right;
|
||||
|
||||
"Mod+R".action = switch-preset-column-width;
|
||||
"Mod+Shift+R".action = reset-window-height;
|
||||
"Mod+F".action = maximize-column;
|
||||
"Mod+Shift+F".action = fullscreen-window;
|
||||
"Mod+C".action = center-column;
|
||||
|
||||
# Mouse
|
||||
"Mod+WheelScrollUp".action = focus-workspace-up;
|
||||
"Mod+WheelScrollDown".action = focus-workspace-down;
|
||||
|
||||
"Mod+Shift+WheelScrollDown".action = focus-column-right;
|
||||
"Mod+Shift+WheelScrollUp".action = focus-column-left;
|
||||
"Mod+Ctrl+Shift+WheelScrollDown".action = move-column-right;
|
||||
"Mod+Ctrl+Shift+WheelScrollUp".action = move-column-left;
|
||||
|
||||
# Focus window or workspace
|
||||
"Mod+Left".action = focus-column-left;
|
||||
"Mod+Down".action = focus-window-or-workspace-down;
|
||||
"Mod+Up".action = focus-window-or-workspace-up;
|
||||
"Mod+Right".action = focus-column-right;
|
||||
|
||||
"Mod+H".action = focus-column-left;
|
||||
"Mod+J".action = focus-window-or-workspace-down;
|
||||
"Mod+K".action = focus-window-or-workspace-up;
|
||||
"Mod+L".action = focus-column-right;
|
||||
|
||||
# Move window or workspace
|
||||
"Mod+Shift+Left".action = move-column-left;
|
||||
"Mod+Shift+Down".action = move-window-down-or-to-workspace-down;
|
||||
"Mod+Shift+Up".action = move-window-up-or-to-workspace-up;
|
||||
"Mod+Shift+Right".action = move-column-right;
|
||||
|
||||
"Mod+Shift+H".action = move-column-left;
|
||||
"Mod+Shift+J".action = move-window-down-or-to-workspace-down;
|
||||
"Mod+Shift+K".action = move-window-up-or-to-workspace-up;
|
||||
"Mod+Shift+L".action = move-column-right;
|
||||
|
||||
# Move workspace
|
||||
"Mod+U".action = move-workspace-down;
|
||||
"Mod+I".action = move-workspace-up;
|
||||
|
||||
"Mod+Ctrl+J".action = move-workspace-down;
|
||||
"Mod+Ctrl+K".action = move-workspace-up;
|
||||
|
||||
"Mod+Ctrl+Down".action = move-workspace-down;
|
||||
"Mod+Ctrl+Up".action = move-workspace-up;
|
||||
|
||||
# Screenshots
|
||||
"Print".action = screenshot;
|
||||
# "Ctrl+Print".action = screenshot-screen; # Only on niri-stable
|
||||
"Alt+Print".action = screenshot-window;
|
||||
|
||||
# "Mod+B".action = spawn "${lib.getExe pkgs.ungoogled-chromium}";
|
||||
"Mod+B".action = spawn "${lib.getExe pkgs.firefox}";
|
||||
"Mod+Shift+B".action = spawn "${lib.getExe pkgs.ungoogled-chromium}";
|
||||
"Mod+D".action = spawn "${lib.getExe pkgs.wofi}" "--show" "drun";
|
||||
# "Mod+Return".action = spawn "footclient";
|
||||
"Mod+Return".action = spawn "${lib.getExe pkgs.foot}";
|
||||
}]);
|
||||
|
||||
window-rules = [
|
||||
{
|
||||
matches = [
|
||||
{ title = "Cinny"; }
|
||||
{ title = "cinny"; }
|
||||
{ title = "Element"; }
|
||||
{ title = "element"; }
|
||||
{ title = "Library"; }
|
||||
{ title = "YouTube"; }
|
||||
{ title = "Invidious"; }
|
||||
{ title = "Piped"; }
|
||||
{ app-id = "org\.keepassxc\.KeePassXC"; }
|
||||
{ app-id = "org\.gnome\.World\.Secrets"; }
|
||||
{ app-id = "org\.gnome\.Nautilus"; }
|
||||
|
||||
{ title = "File Upload"; }
|
||||
{ title = "Open File"; }
|
||||
{ title = "Open Folder"; }
|
||||
{ app-id = "xdg-desktop-portal-gnome"; }
|
||||
|
||||
{ title = "Telegram"; }
|
||||
{ app-id= "io\.github\.tdesktop_x64\.TDesktop"; }
|
||||
];
|
||||
block-out-from = "screencast";
|
||||
}
|
||||
|
||||
{ matches = [
|
||||
{ app-id = "librewolf"; }
|
||||
{ app-id = "firefox"; }
|
||||
];
|
||||
open-maximized = true; }
|
||||
{ matches = [
|
||||
{ app-id = "alacritty"; }
|
||||
{ app-id = "foot"; }
|
||||
{ app-id = "footclient"; }
|
||||
];
|
||||
default-column-width = { proportion = 0.50; }; }
|
||||
|
||||
{
|
||||
matches = [
|
||||
{ is-active = false; }
|
||||
];
|
||||
opacity = 0.9;
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
{ is-active = true; }
|
||||
];
|
||||
opacity = 1.0;
|
||||
}
|
||||
|
||||
{
|
||||
matches = [
|
||||
{ is-window-cast-target = true; }
|
||||
];
|
||||
focus-ring.active.gradient = { # TODO: set colors using stylix
|
||||
from = "#f38ba8";
|
||||
to = "#7d0d2d70";
|
||||
};
|
||||
focus-ring.inactive.color = "#7d0d2d";
|
||||
shadow = {
|
||||
enable = true;
|
||||
color = "#7d0d2d70";
|
||||
};
|
||||
}
|
||||
|
||||
{ geometry-corner-radius = {
|
||||
top-left = 3.0;
|
||||
top-right = 3.0;
|
||||
bottom-left = 0.0;
|
||||
bottom-right = 0.0;
|
||||
};
|
||||
clip-to-geometry = true;
|
||||
}
|
||||
];
|
||||
|
||||
layer-rules = [
|
||||
{
|
||||
matches = [
|
||||
{ namespace = "waybar"; }
|
||||
{ namespace = "yambar"; }
|
||||
];
|
||||
|
||||
opacity = 0.8;
|
||||
shadow = {
|
||||
enable = true;
|
||||
softness = 40;
|
||||
spread = 5;
|
||||
offset.x = 0;
|
||||
offset.y = 5;
|
||||
draw-behind-window = true;
|
||||
color = "#00000064";
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
hotkey-overlay.skip-at-startup = true;
|
||||
|
||||
prefer-no-csd = true;
|
||||
animations = {
|
||||
workspace-switch.spring = {
|
||||
damping-ratio = 1.000000;
|
||||
epsilon = 0.000100;
|
||||
stiffness = 1000;
|
||||
};
|
||||
};
|
||||
|
||||
layout = {
|
||||
border.enable = false;
|
||||
focus-ring = {
|
||||
enable = true;
|
||||
width = 2;
|
||||
active.color = config.lib.stylix.colors.base0D;
|
||||
};
|
||||
|
||||
tab-indicator = {
|
||||
enable = true;
|
||||
gap = 5;
|
||||
width = 4;
|
||||
gaps-between-tabs = 3;
|
||||
active.color = config.lib.stylix.colors.base05;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc."lemurs/wayland/niri".source = pkgs.writeShellScript "niri.sh" "${pkgs.niri}/bin/niri-session";
|
||||
}
|
121
modules/desktop/nvim/default.nix
Normal file
121
modules/desktop/nvim/default.nix
Normal file
@@ -0,0 +1,121 @@
|
||||
{ pkgs, config, ...}: {
|
||||
hm = {
|
||||
imports = [
|
||||
./lsp.nix
|
||||
./oil.nix
|
||||
];
|
||||
|
||||
programs.neovim = {
|
||||
enable = true;
|
||||
defaultEditor = true;
|
||||
viAlias = true;
|
||||
vimAlias = true;
|
||||
|
||||
extraLuaConfig = ''
|
||||
require "nvim.icons"
|
||||
require "nvim.keybinds"
|
||||
require "nvim.bufferline"
|
||||
require "nvim.cyrillic"
|
||||
-------------------
|
||||
local bind = vim.keymap.set
|
||||
local opt = vim.opt
|
||||
local g = vim.g
|
||||
local o = vim.o
|
||||
local cmd = vim.cmd
|
||||
-------------------
|
||||
|
||||
-- cmd [[colorscheme gruvbox]]
|
||||
|
||||
o.expandtab = true
|
||||
o.smarttab = true
|
||||
o.cindent = true
|
||||
o.autoindent = true
|
||||
|
||||
o.ignorecase = true
|
||||
o.smartcase = true
|
||||
|
||||
o.backup = false
|
||||
o.writebackup = false
|
||||
o.undofile = true
|
||||
o.swapfile = false
|
||||
|
||||
opt.relativenumber = true
|
||||
opt.number = true
|
||||
opt.tabstop = 2
|
||||
opt.shiftwidth = 2
|
||||
opt.spelllang = { "en_us", "ru", "by" }
|
||||
opt.mouse = "a"
|
||||
opt.termguicolors = true
|
||||
opt.clipboard = "unnamedplus"
|
||||
'';
|
||||
|
||||
plugins = with pkgs.vimPlugins; [
|
||||
nvim-tree-lua
|
||||
gruvbox-nvim
|
||||
which-key-nvim
|
||||
nvim-autopairs
|
||||
{ plugin = nvim-highlight-colors; type = "lua";
|
||||
config = "require('nvim-highlight-colors').setup({})"; }
|
||||
{ plugin = comment-nvim; type = "lua";
|
||||
config = "require('Comment').setup()"; }
|
||||
{ plugin = nvim-autopairs; type = "lua";
|
||||
config = ''require("nvim-autopairs").setup{}''; }
|
||||
{ plugin = lualine-nvim; type = "lua";
|
||||
config = ''require "nvim.lualine"''; }
|
||||
nvim-web-devicons
|
||||
vim-startuptime
|
||||
{ plugin = nvim-tree-lua; type = "lua";
|
||||
config = ''require "nvim.filemanager"''; }
|
||||
|
||||
{ plugin = telescope-nvim; type = "lua";
|
||||
config = ''
|
||||
require('telescope').load_extension('fzf')
|
||||
local telescope = require('telescope.builtin')
|
||||
-- Old keybinds
|
||||
bind('n', 'gfc', telescope.find_files, {})
|
||||
bind('n', 'gfs', telescope.live_grep, {})
|
||||
bind('n', 'gfb', telescope.buffers, {})
|
||||
-- New keybinds
|
||||
bind('n', '<space>/', telescope.live_grep, {})
|
||||
bind('n', '<space>h', telescope.help_tags, {})
|
||||
bind('n', '<space>b', telescope.buffers, {})
|
||||
bind('n', '<space>e', telescope.buffers, {})
|
||||
bind('n', '<space>f', telescope.find_files, {})
|
||||
''; }
|
||||
{ plugin = editorconfig-nvim; type = "lua";
|
||||
config = ''require "editorconfig"''; }
|
||||
telescope-fzf-native-nvim
|
||||
bufferline-nvim # ./lua/nvim/bufferline.lua
|
||||
];
|
||||
};
|
||||
|
||||
home = {
|
||||
file.".config/nvim/lua" = {
|
||||
enable = true;
|
||||
source = ./lua;
|
||||
target = ".config/nvim/lua";
|
||||
recursive = true;
|
||||
};
|
||||
};
|
||||
|
||||
editorconfig = {
|
||||
enable = true;
|
||||
settings = {
|
||||
"*" = {
|
||||
charset = "utf-8";
|
||||
end_of_line = "lf";
|
||||
trim_trailing_whitespace = true;
|
||||
insert_final_newline = true;
|
||||
max_line_width = 78;
|
||||
indent_style = "space";
|
||||
indent_size = 2;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
home.sessionVariables = {
|
||||
# EDITOR = lib.mkForce lib.getExe pkgs.neovim;
|
||||
MANPAGER = "${config.hm.home.sessionVariables.EDITOR} +Man!";
|
||||
};
|
||||
};
|
||||
}
|
24
modules/desktop/nvim/lsp.nix
Executable file
24
modules/desktop/nvim/lsp.nix
Executable file
@@ -0,0 +1,24 @@
|
||||
{ pkgs, ... }: {
|
||||
home.packages = with pkgs; [
|
||||
rust-analyzer
|
||||
pyright
|
||||
nixd
|
||||
lua-language-server
|
||||
nodePackages.typescript-language-server
|
||||
nodePackages.vscode-langservers-extracted
|
||||
gopls
|
||||
nimlsp
|
||||
clang-tools
|
||||
];
|
||||
|
||||
programs.neovim.plugins = with pkgs.vimPlugins; [
|
||||
{ plugin = nvim-lspconfig; type = "lua";
|
||||
config = ''require "nvim.lsp"''; }
|
||||
nvim-cmp
|
||||
luasnip
|
||||
cmp-nvim-lsp
|
||||
cmp_luasnip
|
||||
cmp-path
|
||||
cmp-buffer
|
||||
];
|
||||
}
|
43
modules/desktop/nvim/lua/nvim/bufferline.lua
Executable file
43
modules/desktop/nvim/lua/nvim/bufferline.lua
Executable file
@@ -0,0 +1,43 @@
|
||||
require("bufferline").setup{
|
||||
options = {
|
||||
diagnostics = "nvim_lsp",
|
||||
diagnostics_indicator = function(count, level, diagnostics_dict, context)
|
||||
local icon = level:match("error") and " " or " "
|
||||
return " " .. icon .. count
|
||||
end,
|
||||
|
||||
numbers = function(opts)
|
||||
return string.format('%s)', opts.ordinal, opts.id)
|
||||
end,
|
||||
|
||||
-- groups = {
|
||||
-- options = {
|
||||
-- toggle_hidden_on_enter = true -- when you re-enter a hidden group this options re-opens that group so the buffer is visible
|
||||
-- },
|
||||
-- items = {
|
||||
-- {
|
||||
-- name = "Code", -- Mandatory
|
||||
-- highlight = {underline = true, sp = "blue"}, -- Optional
|
||||
-- priority = 1,
|
||||
-- icon = "",
|
||||
-- matcher = function(buf)
|
||||
-- return buf.filename:match('%.rs') or buf.filename:match('%.py') or buf.filename:match('%.nix') or buf.filename:match('%.lua')
|
||||
-- end,
|
||||
-- },
|
||||
-- {
|
||||
-- name = "Docs",
|
||||
-- highlight = {undercurl = true, sp = "green"},
|
||||
-- auto_close = false,
|
||||
-- icon = "", -- Optional
|
||||
-- priority = 2,
|
||||
-- matcher = function(buf)
|
||||
-- return buf.filename:match('%.md') or buf.filename:match('%.txt') or buf.filename:match('LICENSE')
|
||||
-- end,
|
||||
-- separator = { -- Optional
|
||||
-- style = require('bufferline.groups').separator.tab
|
||||
-- },
|
||||
-- }
|
||||
-- }
|
||||
-- }
|
||||
}
|
||||
}
|
612
modules/desktop/nvim/lua/nvim/cyrillic.lua
Normal file
612
modules/desktop/nvim/lua/nvim/cyrillic.lua
Normal file
@@ -0,0 +1,612 @@
|
||||
-- Author: nrv
|
||||
-- Version: 1.0
|
||||
-- License: GPLv3
|
||||
-- URL: http://github.com/nativerv/cyrillic.nvim
|
||||
-- Description: Adds some support for Cyrillic keyboard
|
||||
-- layouts (Ukrainian, Russian) in Neovim
|
||||
|
||||
vim.cmd [[
|
||||
cabbrev <expr> ив getcmdtype()==':' && getcmdline()=="ив" ? "bd" : "ив"
|
||||
cabbrev <expr> ит getcmdtype()==':' && getcmdline()=="ит" ? "bn" : "ит"
|
||||
cabbrev <expr> й getcmdtype()==':' && getcmdline()=="й" ? "q" : "й"
|
||||
cabbrev <expr> йф getcmdtype()==':' && getcmdline()=="йф" ? "qa" : "йф"
|
||||
cabbrev <expr> ц getcmdtype()==':' && getcmdline()=="ц" ? "w" : "ц"
|
||||
cabbrev <expr> цй getcmdtype()==':' && getcmdline()=="цй" ? "wq" : "цй"
|
||||
]]
|
||||
|
||||
vim.keymap.set('', 'ё', '`', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '’', '`', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'й', 'q', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ц', 'w', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'у', 'e', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'к', 'r', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'е', 't', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'н', 'y', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'г', 'u', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ш', 'i', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'щ', 'o', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'з', 'p', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'х', '[', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъ', ']', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ї', ']', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ф', 'a', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ы', 's', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'і', 's', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'в', 'd', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'а', 'f', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'п', 'g', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'р', 'h', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'о', 'j', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'л', 'k', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'д', 'l', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ж', ';', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'э', "'", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'є', "'", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'я', 'z', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ч', 'x', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'с', 'c', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'м', 'v', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'и', 'b', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'т', 'n', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ь', 'm', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'б', ',', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ю', '.', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Ё', '~', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Й', 'Q', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Ц', 'W', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'У', 'E', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'К', 'R', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Е', 'T', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Н', 'Y', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Г', 'U', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Ш', 'I', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Щ', 'O', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'З', 'P', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Х', '{', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Ъ', '}', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Ї', '}', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Ф', 'A', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Ы', 'S', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'І', 'S', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'В', 'D', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'А', 'F', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'П', 'G', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Р', 'H', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'О', 'J', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Л', 'K', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Д', 'L', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Ж', ':', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Э', '"', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Є', '"', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Я', 'Z', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Ч', 'X', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'С', 'C', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'М', 'V', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'И', 'B', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Т', 'N', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Ь', 'M', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Б', '<', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Ю', '>', { desc = 'which_key_ignore' })
|
||||
|
||||
vim.keymap.set('', 'ЯЯ', 'ZZ', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЯЙ', 'ZQ', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'йЖ', 'q:', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'й.', 'q/', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'й,', 'q?', { desc = 'which_key_ignore' })
|
||||
|
||||
vim.keymap.set('', 'ёё', '``', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёБ', '`<', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЮ', '`>', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёх', '`[', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёъ', '`]', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёХ', '`{', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЪ', '`}', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ээ', "''", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эБ', "'<", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЮ', "'>", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эх', "'[", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эъ', "']", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эХ', "'{", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЪ', "'}", { desc = 'which_key_ignore' })
|
||||
|
||||
vim.keymap.set('', 'хэ', "['", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хё', '[`', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хВ', '[D', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хШ', '[I', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хЗ', '[P', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хх', '[[', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хъ', '[]', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хс', '[c', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хв', '[d', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ха', '[f', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хш', '[i', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хь', '[m', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хз', '[p', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хы', '[s', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хя', '[z', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'хХ', '[{', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъэ', "]'", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъё', ']`', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъВ', ']D', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъШ', ']I', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъЗ', ']P', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъх', '][', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъъ', ']]', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъс', ']c', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъв', ']d', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъа', ']f', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъш', ']i', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъь', ']m', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъз', ']p', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъы', ']s', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъя', ']z', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ъХ', ']{', { desc = 'which_key_ignore' })
|
||||
|
||||
vim.keymap.set('', 'ьФ', 'mA', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёФ', '`A', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эФ', "'A", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёФ', 'g`A', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэФ', "g'A", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьИ', 'mB', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёИ', '`B', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эИ', "'B", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёИ', 'g`B', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэИ', "g'B", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьС', 'mC', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёС', '`C', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эС', "'C", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёС', 'g`C', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэС', "g'C", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьВ', 'mD', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёВ', '`D', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эВ', "'D", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёВ', 'g`D', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэВ', "g'D", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьУ', 'mE', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёУ', '`E', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эУ', "'E", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёУ', 'g`E', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэУ', "g'E", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьА', 'mF', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёА', '`F', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эА', "'F", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёА', 'g`F', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэА', "g'F", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьП', 'mG', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёП', '`G', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эП', "'G", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёП', 'g`G', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэП', "g'G", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьР', 'mH', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёР', '`H', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эР', "'H", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёР', 'g`H', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэР', "g'H", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьШ', 'mI', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёШ', '`I', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эШ', "'I", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёШ', 'g`I', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэШ', "g'I", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьО', 'mJ', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёО', '`J', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эО', "'J", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёО', 'g`J', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэО', "g'J", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьЛ', 'mK', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЛ', '`K', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЛ', "'K", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёЛ', 'g`K', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэЛ', "g'K", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьД', 'mL', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёД', '`L', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эД', "'L", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёД', 'g`L', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэД', "g'L", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьЬ', 'mM', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЬ', '`M', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЬ', "'M", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёЬ', 'g`M', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэЬ', "g'M", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьТ', 'mN', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёТ', '`N', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эТ', "'N", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёТ', 'g`N', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэТ', "g'N", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьЩ', 'mO', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЩ', '`O', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЩ', "'O", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёЩ', 'g`O', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэЩ', "g'O", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьЗ', 'mP', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЗ', '`P', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЗ', "'P", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёЗ', 'g`P', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэЗ', "g'P", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьЙ', 'mQ', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЙ', '`Q', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЙ', "'Q", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёЙ', 'g`Q', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэЙ', "g'Q", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьК', 'mR', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёК', '`R', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эК', "'R", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёК', 'g`R', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэК', "g'R", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьЫ', 'mS', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЫ', '`S', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЫ', "'S", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёЫ', 'g`S', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэЫ', "g'S", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьЕ', 'mT', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЕ', '`T', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЕ', "'T", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёЕ', 'g`T', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэЕ', "g'T", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьГ', 'mU', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёГ', '`U', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эГ', "'U", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёГ', 'g`U', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэГ', "g'U", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьМ', 'mV', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёМ', '`V', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эМ', "'V", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёМ', 'g`V', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэМ', "g'V", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьЦ', 'mW', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЦ', '`W', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЦ', "'W", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёЦ', 'g`W', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэЦ', "g'W", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьЧ', 'mX', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЧ', '`X', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЧ', "'X", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёЧ', 'g`X', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэЧ', "g'X", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьН', 'mY', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёН', '`Y', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эН', "'Y", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёН', 'g`Y', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэН', "g'Y", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьЯ', 'mZ', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёЯ', '`Z', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эЯ', "'Z", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёЯ', 'g`Z', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэЯ', "g'Z", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьф', 'ma', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёф', '`a', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эф', "'a", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёф', 'g`a', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэф', "g'a", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьи', 'mb', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёи', '`b', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эи', "'b", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёи', 'g`b', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэи', "g'b", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьс', 'mc', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёс', '`c', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эс', "'c", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёс', 'g`c', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэс', "g'c", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьв', 'md', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёв', '`d', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эв', "'d", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёв', 'g`d', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэв', "g'd", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьу', 'me', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёу', '`e', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эу', "'e", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёу', 'g`e', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэу', "g'e", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьа', 'mf', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёа', '`f', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эа', "'f", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёа', 'g`f', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэа', "g'f", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьп', 'mg', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёп', '`g', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эп', "'g", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёп', 'g`g', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэп', "g'g", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьр', 'mh', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёр', '`h', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эр', "'h", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёр', 'g`h', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэр', "g'h", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьш', 'mi', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёш', '`i', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эш', "'i", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёш', 'g`i', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэш', "g'i", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьо', 'mj', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёо', '`j', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эо', "'j", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёо', 'g`j', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэо', "g'j", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьл', 'mk', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёл', '`k', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эл', "'k", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёл', 'g`k', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэл', "g'k", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьд', 'ml', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёд', '`l', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эд', "'l", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёд', 'g`l', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэд', "g'l", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьь', 'mm', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёь', '`m', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эь', "'m", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёь', 'g`m', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэь', "g'm", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьт', 'mn', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёт', '`n', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эт', "'n", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёт', 'g`n', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэт', "g'n", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьщ', 'mo', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёщ', '`o', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эщ', "'o", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёщ', 'g`o', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэщ', "g'o", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьз', 'mp', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёз', '`p', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эз', "'p", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёз', 'g`p', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэз', "g'p", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьй', 'mq', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёй', '`q', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эй', "'q", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёй', 'g`q', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэй', "g'q", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьк', 'mr', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёк', '`r', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эк', "'r", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёк', 'g`r', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэк', "g'r", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьы', 'ms', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёы', '`s', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эы', "'s", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёы', 'g`s', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэы', "g's", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ье', 'mt', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёе', '`t', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эе', "'t", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёе', 'g`t', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэе', "g't", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьг', 'mu', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёг', '`u', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эг', "'u", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёг', 'g`u', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэг', "g'u", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьм', 'mv', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ём', '`v', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эм', "'v", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пём', 'g`v', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэм', "g'v", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьц', 'mw', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёц', '`w', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эц', "'w", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёц', 'g`w', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэц', "g'w", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьч', 'mx', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёч', '`x', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эч', "'x", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёч', 'g`x', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэч', "g'x", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ьн', 'my', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ён', '`y', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эн', "'y", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пён', 'g`y', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэн', "g'y", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ья', 'mz', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ёя', '`z', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'эя', "'z", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пёя', 'g`z', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пэя', "g'z", { desc = 'which_key_ignore' })
|
||||
|
||||
vim.keymap.set('', 'ЭЭ', '""', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭЖ', '":', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эю', '".', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭФ', '"A', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭИ', '"B', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭС', '"C', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭВ', '"D', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭУ', '"E', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭА', '"F', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭП', '"G', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭР', '"H', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭШ', '"I', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭО', '"J', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭЛ', '"K', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭД', '"L', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭЬ', '"M', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭТ', '"N', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭЩ', '"O', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭЗ', '"P', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭЙ', '"Q', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭК', '"R', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭЫ', '"S', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭЕ', '"T', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭГ', '"U', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭМ', '"V', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭЦ', '"W', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭЧ', '"X', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭН', '"Y', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ЭЯ', '"Z', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эф', '"a', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эи', '"b', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эс', '"c', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эв', '"d', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эу', '"e', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эа', '"f', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эп', '"g', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эр', '"h', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эш', '"i', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эо', '"j', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эл', '"k', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эд', '"l', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эь', '"m', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эт', '"n', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эщ', '"o', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эз', '"p', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эй', '"q', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эк', '"r', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эы', '"s', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эе', '"t', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эг', '"u', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эм', '"v', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эц', '"w', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эч', '"x', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эн', '"y', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'Эя', '"z', { desc = 'which_key_ignore' })
|
||||
|
||||
vim.keymap.set('', 'пБ', 'g<', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пВ', 'gD', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пУ', 'gE', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пР', 'gH', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пШ', 'gI', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пО', 'gJ', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пТ', 'gN', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пЗ', 'gP', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пЙ', 'gQ', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пК', 'gR', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пЕ', 'gT', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пГ', 'gU', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пМ', 'gV', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пъ', 'g]', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пф', 'ga', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пв', 'gd', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пу', 'ge', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'па', 'gf', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пА', 'gF', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пп', 'gg', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пр', 'gh', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пш', 'gi', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'по', 'gj', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пл', 'gk', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пт', 'gn', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пь', 'gm', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пщ', 'go', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пз', 'gp', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пй', 'gq', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пк', 'gr', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пы', 'gs', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пе', 'gt', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пг', 'gu', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пм', 'gv', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пц', 'gw', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пч', 'gx', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'пЁ', 'g~', { desc = 'which_key_ignore' })
|
||||
|
||||
vim.keymap.set('', 'яю', 'z.', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яФ', 'zA', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яС', 'zC', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яВ', 'zD', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яУ', 'zE', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яА', 'zF', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яП', 'zG', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яР', 'zH', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яД', 'zL', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яЬ', 'zM', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яТ', 'zN', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яЩ', 'zO', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яК', 'zR', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яЦ', 'zW', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яЧ', 'zX', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яф', 'za', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яи', 'zb', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яс', 'zc', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яв', 'zd', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яу', 'ze', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яа', 'zf', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яп', 'zg', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яр', 'zh', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яш', 'zi', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яо', 'zj', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ял', 'zk', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яд', 'zl', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яь', 'zm', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ят', 'zn', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ящ', 'zo', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'як', 'zr', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яы', 'zs', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яе', 'zt', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ям', 'zv', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яц', 'zw', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яч', 'zx', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'яя', 'zz', { desc = 'which_key_ignore' })
|
||||
|
||||
vim.keymap.set('', 'фЭ', 'a"', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шЭ', 'i"', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фэ', "a'", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шэ', "i'", { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фБ', 'a<', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шБ', 'i<', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фЮ', 'a>', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шЮ', 'i>', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фИ', 'aB', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шИ', 'iB', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фЦ', 'aW', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шЦ', 'iW', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фх', 'a[', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шх', 'i[', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фъ', 'a]', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шъ', 'i]', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фё', 'a`', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шё', 'i`', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фи', 'ab', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ши', 'ib', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фз', 'ap', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шз', 'ip', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фы', 'as', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шы', 'is', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фе', 'at', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'ше', 'it', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фц', 'aw', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шц', 'iw', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фХ', 'a{', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шХ', 'i{', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'фЪ', 'a}', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', 'шЪ', 'i}', { desc = 'which_key_ignore' })
|
||||
|
||||
vim.keymap.set('', '<C-W>Б', '<C-W><', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>Ю', '<C-W>>', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>Р', '<C-W>H', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>О', '<C-W>J', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>Л', '<C-W>K', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>Д', '<C-W>L', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>З', '<C-W>P', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>К', '<C-W>R', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>Ы', '<C-W>S', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>Е', '<C-W>T', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>Ц', '<C-W>W', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>ъ', '<C-W>]', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>и', '<C-W>b', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>с', '<C-W>c', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>в', '<C-W>d', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>а', '<C-W>f', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>А', '<C-W>F', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>п', '<C-W>g', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>пъ', '<C-W>g]', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>пЪ', '<C-W>g}', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>па', '<C-W>gf', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>пА', '<C-W>gF', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>р', '<C-W>h', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>ш', '<C-W>i', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>о', '<C-W>j', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>л', '<C-W>k', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>д', '<C-W>l', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>т', '<C-W>n', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>щ', '<C-W>o', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>з', '<C-W>p', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>й', '<C-W>q', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>к', '<C-W>r', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>ы', '<C-W>s', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>е', '<C-W>t', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>м', '<C-W>v', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>ц', '<C-W>w', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>ч', '<C-W>x', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>я', '<C-W>z', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('', '<C-W>Ъ', '<C-W>}', { desc = 'which_key_ignore' })
|
||||
|
||||
vim.keymap.set('n', '№', '#', { desc = 'which_key_ignore' })
|
||||
vim.keymap.set('n', ';', '$', { desc = 'which_key_ignore' })
|
13
modules/desktop/nvim/lua/nvim/filemanager.lua
Executable file
13
modules/desktop/nvim/lua/nvim/filemanager.lua
Executable file
@@ -0,0 +1,13 @@
|
||||
local g = vim.g
|
||||
local bind = vim.keymap.set
|
||||
local nvimTree = require('nvim-tree.api')
|
||||
|
||||
g.loaded_netrw = 1
|
||||
g.loaded_netrwPlugin = 1
|
||||
g.netrw_banner = 0
|
||||
g.netrw_liststyle = 3
|
||||
g.netrw_browse_split = 3
|
||||
|
||||
require("nvim-tree").setup()
|
||||
|
||||
bind('n', 'tt', nvimTree.tree.toggle, {})
|
27
modules/desktop/nvim/lua/nvim/icons.lua
Executable file
27
modules/desktop/nvim/lua/nvim/icons.lua
Executable file
@@ -0,0 +1,27 @@
|
||||
require'nvim-web-devicons'.setup {
|
||||
override = {
|
||||
zsh = {
|
||||
icon = "",
|
||||
color = "#428850",
|
||||
cterm_color = "65",
|
||||
name = "Zsh"
|
||||
}
|
||||
};
|
||||
color_icons = true;
|
||||
default = true;
|
||||
strict = true;
|
||||
override_by_filename = {
|
||||
[".gitignore"] = {
|
||||
icon = "",
|
||||
color = "#f1502f",
|
||||
name = "Gitignore"
|
||||
}
|
||||
};
|
||||
-- override_by_extension = {
|
||||
-- ["log"] = {
|
||||
-- icon = "",
|
||||
-- color = "#81e043",
|
||||
-- name = "Log"
|
||||
-- }
|
||||
-- };
|
||||
}
|
8
modules/desktop/nvim/lua/nvim/keybinds.lua
Executable file
8
modules/desktop/nvim/lua/nvim/keybinds.lua
Executable file
@@ -0,0 +1,8 @@
|
||||
local bind = vim.keymap.set
|
||||
----------------------------
|
||||
|
||||
bind('n', '<space>1', ':b 1', {})
|
||||
bind('n', '<space>2', ':b 2', {})
|
||||
bind('n', '<space>3', ':b 3', {})
|
||||
bind('n', '<space>4', ':b 4', {})
|
||||
bind('n', '<space>5', ':b 5', {})
|
108
modules/desktop/nvim/lua/nvim/lsp.lua
Executable file
108
modules/desktop/nvim/lua/nvim/lsp.lua
Executable file
@@ -0,0 +1,108 @@
|
||||
local lspconfig = require('lspconfig')
|
||||
-- local luasnip = require 'luasnip'
|
||||
local cmp = require 'cmp'
|
||||
local capabilities = require("cmp_nvim_lsp").default_capabilities()
|
||||
|
||||
local servers = { 'pyright', 'rust_analyzer', 'nixd', 'lua_ls', 'ts_ls', 'html', 'cssls', 'gopls', 'nimls', 'clangd' }
|
||||
for _, lsp in ipairs(servers) do
|
||||
lspconfig[lsp].setup {
|
||||
-- on_attach = my_custom_on_attach,
|
||||
capabilities = capabilities,
|
||||
}
|
||||
end
|
||||
|
||||
-- lspconfig.lua_ls.setup {
|
||||
-- settings = {
|
||||
-- Lua = {
|
||||
-- runtime = {
|
||||
-- version = 'LuaJIT',
|
||||
-- },
|
||||
-- diagnostics = {
|
||||
-- globals = {'vim'},
|
||||
-- },
|
||||
-- workspace = {
|
||||
-- library = vim.api.nvim_get_runtime_file("", true),
|
||||
-- },
|
||||
-- telemetry = {
|
||||
-- enable = false,
|
||||
-- },
|
||||
-- },
|
||||
-- },
|
||||
-- }
|
||||
|
||||
-- Global mappings.
|
||||
-- See `:help vim.diagnostic.*` for documentation on any of the below functions
|
||||
vim.keymap.set('n', '<space>d', vim.diagnostic.open_float)
|
||||
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev)
|
||||
vim.keymap.set('n', ']d', vim.diagnostic.goto_next)
|
||||
vim.keymap.set('n', '<space>q', vim.diagnostic.setloclist)
|
||||
|
||||
-- Use LspAttach autocommand to only map the following keys
|
||||
-- after the language server attaches to the current buffer
|
||||
vim.api.nvim_create_autocmd('LspAttach', {
|
||||
group = vim.api.nvim_create_augroup('UserLspConfig', {}),
|
||||
callback = function(ev)
|
||||
-- Enable completion triggered by <c-x><c-o>
|
||||
vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc'
|
||||
|
||||
-- Buffer local mappings.
|
||||
-- See `:help vim.lsp.*` for documentation on any of the below functions
|
||||
local opts = { buffer = ev.buf }
|
||||
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts)
|
||||
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
|
||||
vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
|
||||
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts)
|
||||
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, opts)
|
||||
vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, opts)
|
||||
vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, opts)
|
||||
vim.keymap.set('n', '<space>wl', function()
|
||||
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
|
||||
end, opts)
|
||||
vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, opts)
|
||||
vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, opts)
|
||||
vim.keymap.set({ 'n', 'v' }, '<space>ca', vim.lsp.buf.code_action, opts)
|
||||
vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts)
|
||||
end,
|
||||
})
|
||||
|
||||
cmp.setup {
|
||||
-- snippet = {
|
||||
-- expand = function(args)
|
||||
-- luasnip.lsp_expand(args.nody)
|
||||
-- end,
|
||||
-- },
|
||||
mapping = cmp.mapping.preset.insert({
|
||||
['<C-u>'] = cmp.mapping.scroll_docs(-4), -- Up
|
||||
['<C-d>'] = cmp.mapping.scroll_docs(4), -- Down
|
||||
-- C-b (back) C-f (forward) for snippet placeholder navigation.
|
||||
['<C-Space>'] = cmp.mapping.complete(),
|
||||
['<CR>'] = cmp.mapping.confirm {
|
||||
behavior = cmp.ConfirmBehavior.Replace,
|
||||
select = true,
|
||||
},
|
||||
-- ['<Tab>'] = cmp.mapping(function(fallback)
|
||||
-- if cmp.visible() then
|
||||
-- cmp.select_next_item()
|
||||
-- elseif luasnip.expand_or_jumpable() then
|
||||
-- luasnip.expand_or_jump()
|
||||
-- else
|
||||
-- fallback()
|
||||
-- end
|
||||
-- end, { 'i', 's' }),
|
||||
-- ['<S-Tab>'] = cmp.mapping(function(fallback)
|
||||
-- if cmp.visible() then
|
||||
-- cmp.select_prev_item()
|
||||
-- elseif luasnip.jumpable(-1) then
|
||||
-- luasnip.jump(-1)
|
||||
-- else
|
||||
-- fallback()
|
||||
-- end
|
||||
-- end, { 'i', 's' }),
|
||||
}),
|
||||
sources = {
|
||||
{ name = 'nvim_lsp' },
|
||||
-- { name = 'luasnip' },
|
||||
{ name = 'path' },
|
||||
{ name = 'buffer' },
|
||||
},
|
||||
}
|
24
modules/desktop/nvim/lua/nvim/lualine.lua
Executable file
24
modules/desktop/nvim/lua/nvim/lualine.lua
Executable file
@@ -0,0 +1,24 @@
|
||||
require('lualine').setup {
|
||||
options = {
|
||||
theme = "everforest",
|
||||
component_separators = '|',
|
||||
},
|
||||
sections = {
|
||||
lualine_a = { 'mode' },
|
||||
lualine_b = { 'filename', 'location' },
|
||||
lualine_c = { 'branch', 'diff', 'diagnostics'},
|
||||
lualine_x = { 'filetype' },
|
||||
lualine_y = { 'progress' },
|
||||
lualine_z = {{ 'fileformat', left_padding = 2 },},
|
||||
},
|
||||
inactive_sections = {
|
||||
lualine_a = { 'filename' },
|
||||
lualine_b = {},
|
||||
lualine_c = {},
|
||||
lualine_x = {},
|
||||
lualine_y = {},
|
||||
lualine_z = { 'location' },
|
||||
},
|
||||
tabline = {},
|
||||
extensions = { 'nvim-tree' },
|
||||
}
|
162
modules/desktop/nvim/oil.nix
Executable file
162
modules/desktop/nvim/oil.nix
Executable file
@@ -0,0 +1,162 @@
|
||||
{ pkgs, ... }: {
|
||||
programs.neovim.plugins = with pkgs.vimPlugins; [
|
||||
{ plugin = oil-nvim; type = "lua";
|
||||
config = ''
|
||||
require("oil").setup({
|
||||
-- Oil will take over directory buffers (e.g. `vim .` or `:e src/`)
|
||||
-- Set to false if you still want to use netrw.
|
||||
default_file_explorer = true,
|
||||
-- Id is automatically added at the beginning, and name at the end
|
||||
-- See :help oil-columns
|
||||
columns = {
|
||||
"icon",
|
||||
-- "permissions",
|
||||
-- "size",
|
||||
-- "mtime",
|
||||
},
|
||||
-- Buffer-local options to use for oil buffers
|
||||
buf_options = {
|
||||
buflisted = false,
|
||||
bufhidden = "hide",
|
||||
},
|
||||
-- Window-local options to use for oil buffers
|
||||
win_options = {
|
||||
wrap = false,
|
||||
signcolumn = "no",
|
||||
cursorcolumn = false,
|
||||
foldcolumn = "0",
|
||||
spell = false,
|
||||
list = false,
|
||||
conceallevel = 3,
|
||||
concealcursor = "nvic",
|
||||
},
|
||||
-- Send deleted files to the trash instead of permanently deleting them (:help oil-trash)
|
||||
delete_to_trash = false,
|
||||
-- Skip the confirmation popup for simple operations (:help oil.skip_confirm_for_simple_edits)
|
||||
skip_confirm_for_simple_edits = false,
|
||||
-- Selecting a new/moved/renamed file or directory will prompt you to save changes first
|
||||
-- (:help prompt_save_on_select_new_entry)
|
||||
prompt_save_on_select_new_entry = true,
|
||||
-- Oil will automatically delete hidden buffers after this delay
|
||||
-- You can set the delay to false to disable cleanup entirely
|
||||
-- Note that the cleanup process only starts when none of the oil buffers are currently displayed
|
||||
cleanup_delay_ms = 2000,
|
||||
lsp_file_methods = {
|
||||
-- Time to wait for LSP file operations to complete before skipping
|
||||
timeout_ms = 1000,
|
||||
-- Set to true to autosave buffers that are updated with LSP willRenameFiles
|
||||
-- Set to "unmodified" to only save unmodified buffers
|
||||
autosave_changes = false,
|
||||
},
|
||||
-- Constrain the cursor to the editable parts of the oil buffer
|
||||
-- Set to `false` to disable, or "name" to keep it on the file names
|
||||
constrain_cursor = "editable",
|
||||
-- Set to true to watch the filesystem for changes and reload oil
|
||||
experimental_watch_for_changes = false,
|
||||
-- Keymaps in oil buffer. Can be any value that `vim.keymap.set` accepts OR a table of keymap
|
||||
-- options with a `callback` (e.g. { callback = function() ... end, desc = "", mode = "n" })
|
||||
-- Additionally, if it is a string that matches "actions.<name>",
|
||||
-- it will use the mapping at require("oil.actions").<name>
|
||||
-- Set to `false` to remove a keymap
|
||||
-- See :help oil-actions for a list of all available actions
|
||||
keymaps = {
|
||||
["g?"] = "actions.show_help",
|
||||
["<CR>"] = "actions.select",
|
||||
["<C-s>"] = "actions.select_vsplit",
|
||||
["<C-h>"] = "actions.select_split",
|
||||
["<C-t>"] = "actions.select_tab",
|
||||
["<C-p>"] = "actions.preview",
|
||||
["<C-c>"] = "actions.close",
|
||||
["<C-l>"] = "actions.refresh",
|
||||
["-"] = "actions.parent",
|
||||
["_"] = "actions.open_cwd",
|
||||
["`"] = "actions.cd",
|
||||
["~"] = "actions.tcd",
|
||||
["gs"] = "actions.change_sort",
|
||||
["gx"] = "actions.open_external",
|
||||
["g."] = "actions.toggle_hidden",
|
||||
["g\\"] = "actions.toggle_trash",
|
||||
},
|
||||
-- Configuration for the floating keymaps help window
|
||||
keymaps_help = {
|
||||
border = "rounded",
|
||||
},
|
||||
-- Set to false to disable all of the above keymaps
|
||||
use_default_keymaps = true,
|
||||
view_options = {
|
||||
-- Show files and directories that start with "."
|
||||
show_hidden = false,
|
||||
-- This function defines what is considered a "hidden" file
|
||||
is_hidden_file = function(name, bufnr)
|
||||
return vim.startswith(name, ".")
|
||||
end,
|
||||
-- This function defines what will never be shown, even when `show_hidden` is set
|
||||
is_always_hidden = function(name, bufnr)
|
||||
return false
|
||||
end,
|
||||
sort = {
|
||||
-- sort order can be "asc" or "desc"
|
||||
-- see :help oil-columns to see which columns are sortable
|
||||
{ "type", "asc" },
|
||||
{ "name", "asc" },
|
||||
},
|
||||
},
|
||||
-- Configuration for the floating window in oil.open_float
|
||||
float = {
|
||||
-- Padding around the floating window
|
||||
padding = 2,
|
||||
max_width = 0,
|
||||
max_height = 0,
|
||||
border = "rounded",
|
||||
win_options = {
|
||||
winblend = 0,
|
||||
},
|
||||
-- This is the config that will be passed to nvim_open_win.
|
||||
-- Change values here to customize the layout
|
||||
override = function(conf)
|
||||
return conf
|
||||
end,
|
||||
},
|
||||
-- Configuration for the actions floating preview window
|
||||
preview = {
|
||||
-- Width dimensions can be integers or a float between 0 and 1 (e.g. 0.4 for 40%)
|
||||
-- min_width and max_width can be a single value or a list of mixed integer/float types.
|
||||
-- max_width = {100, 0.8} means "the lesser of 100 columns or 80% of total"
|
||||
max_width = 0.9,
|
||||
-- min_width = {40, 0.4} means "the greater of 40 columns or 40% of total"
|
||||
min_width = { 40, 0.4 },
|
||||
-- optionally define an integer/float for the exact width of the preview window
|
||||
width = nil,
|
||||
-- Height dimensions can be integers or a float between 0 and 1 (e.g. 0.4 for 40%)
|
||||
-- min_height and max_height can be a single value or a list of mixed integer/float types.
|
||||
-- max_height = {80, 0.9} means "the lesser of 80 columns or 90% of total"
|
||||
max_height = 0.9,
|
||||
-- min_height = {5, 0.1} means "the greater of 5 columns or 10% of total"
|
||||
min_height = { 5, 0.1 },
|
||||
-- optionally define an integer/float for the exact height of the preview window
|
||||
height = nil,
|
||||
border = "rounded",
|
||||
win_options = {
|
||||
winblend = 0,
|
||||
},
|
||||
-- Whether the preview window is automatically updated when the cursor is moved
|
||||
update_on_cursor_moved = true,
|
||||
},
|
||||
-- Configuration for the floating progress window
|
||||
progress = {
|
||||
max_width = 0.9,
|
||||
min_width = { 40, 0.4 },
|
||||
width = nil,
|
||||
max_height = { 10, 0.9 },
|
||||
min_height = { 5, 0.1 },
|
||||
height = nil,
|
||||
border = "rounded",
|
||||
minimized_border = "none",
|
||||
win_options = {
|
||||
winblend = 0,
|
||||
},
|
||||
},
|
||||
})
|
||||
''; }
|
||||
];
|
||||
}
|
62
modules/desktop/openssh.nix
Normal file
62
modules/desktop/openssh.nix
Normal file
@@ -0,0 +1,62 @@
|
||||
{ config, lib, pkgs, username, ... }:
|
||||
let socket = "/run/${username}/1000/ssh-agent";
|
||||
in {
|
||||
hm = {
|
||||
programs.ssh = {
|
||||
enable = true;
|
||||
hashKnownHosts = true;
|
||||
|
||||
matchBlocks = {
|
||||
"cepheus" = {
|
||||
hostname = "nothing.run";
|
||||
user = "root";
|
||||
port = 22;
|
||||
};
|
||||
};
|
||||
|
||||
extraConfig = "ObscureKeystrokeTiming yes";
|
||||
forwardAgent = true;
|
||||
addKeysToAgent = "yes";
|
||||
};
|
||||
services.ssh-agent.enable = true;
|
||||
home.sessionVariables = {
|
||||
# SSH_ASKPASS = lib.mkForce pkgs.kdePackages.ksshaskpass;
|
||||
SSH_AUTH_SOCK = socket;
|
||||
};
|
||||
};
|
||||
imp.home.dirs = [ ".ssh" ];
|
||||
services.openssh = {
|
||||
enable = lib.mkDefault false;
|
||||
openFirewall = lib.mkDefault false;
|
||||
};
|
||||
|
||||
systemd.user.services.ssh-agent-delete-keys =
|
||||
let
|
||||
ssh-add = "${pkgs.openssh}/bin/ssh-add";
|
||||
script = pkgs.writeShellScript "ssh-agent-delete-keys" ''
|
||||
while true; do
|
||||
state="$(${ssh-add} -l)"
|
||||
# if (echo $state | grep -i "The agent has no identities"); then
|
||||
if [[ $state != *"The agent has no identities"* ]]; then
|
||||
echo "Detected adding of key: $(${ssh-add} -l)"
|
||||
sleep $SSH_AGENT_KEY_LIFETIME
|
||||
${ssh-add} -D
|
||||
echo "Deleted the key: $(${ssh-add} -l)"
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
'';
|
||||
in {
|
||||
enable = true;
|
||||
after = [ "ssh-agent.service" ];
|
||||
wantedBy = [ "default.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = script;
|
||||
};
|
||||
environment = {
|
||||
SSH_AUTH_SOCK = socket;
|
||||
SSH_AGENT_KEY_LIFETIME = "180";
|
||||
};
|
||||
};
|
||||
}
|
19
modules/desktop/pipewire.nix
Normal file
19
modules/desktop/pipewire.nix
Normal file
@@ -0,0 +1,19 @@
|
||||
{ pkgs, ... }: {
|
||||
services.pulseaudio.enable = false;
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
alsa = {
|
||||
enable = true;
|
||||
support32Bit = true;
|
||||
};
|
||||
pulse.enable = true;
|
||||
jack.enable = true;
|
||||
wireplumber.enable = true;
|
||||
};
|
||||
|
||||
hm.home.packages = with pkgs; [
|
||||
pavucontrol
|
||||
helvum
|
||||
pulseaudio
|
||||
];
|
||||
}
|
35
modules/desktop/qbittorrent.nix
Normal file
35
modules/desktop/qbittorrent.nix
Normal file
@@ -0,0 +1,35 @@
|
||||
{ username, pkgs, ... }: {
|
||||
systemd.services.qbittorrent-nox = let
|
||||
port = 1999;
|
||||
in {
|
||||
enable = true;
|
||||
description = "QBitTorrent server";
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
Type = "exec";
|
||||
User = username;
|
||||
ExecStart = "${pkgs.qbittorrent-nox}/bin/qbittorrent-nox --profile=\"/home/${username}/Torrent\" --configuration=\"/home/${username}/Torrent/config\" --webui-port=${toString port}";
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
# WebUI\LocalHostAuth=false
|
||||
|
||||
imp.home.dirs = [ "Torrent" ];
|
||||
|
||||
systemd.services.gdisk = {
|
||||
enable = true;
|
||||
description = "Automounting additional disk";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "root";
|
||||
ExecStart = pkgs.writeShellScript "mount-gdisk.sh" ''
|
||||
systemd-cryptsetup attach gd /dev/sda /nix/disks/gd/key header=/nix/disks/gd/header
|
||||
mkdir -p /mnt/gd
|
||||
mount /dev/mapper/gd /mnt/gd -o compress=zstd:2
|
||||
'';
|
||||
RemainAfterExit = true;
|
||||
ExecStop = "umount /dev/gd && systemd-cryptsetup detach gd";
|
||||
};
|
||||
};
|
||||
}
|
18
modules/desktop/stylix.nix
Normal file
18
modules/desktop/stylix.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{ inputs, pkgs, config, ... }: {
|
||||
imports = [ inputs.stylix.nixosModules.stylix ];
|
||||
stylix = {
|
||||
enable = true;
|
||||
base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-dark-hard.yaml";
|
||||
polarity = "dark";
|
||||
image = ../../assets/Wallpaper.jpg;
|
||||
|
||||
fonts = {
|
||||
serif = config.stylix.fonts.monospace;
|
||||
sansSerif = config.stylix.fonts.monospace;
|
||||
monospace = {
|
||||
package = pkgs.nerd-fonts.fira-code;
|
||||
name = "FiraCode Nerd Font";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
51
modules/desktop/xcompose.nix
Normal file
51
modules/desktop/xcompose.nix
Normal file
@@ -0,0 +1,51 @@
|
||||
{ lib, pkgs, ... }:
|
||||
let
|
||||
makebinds = attrs: lib.pipe attrs [
|
||||
(attr: builtins.mapAttrs (_: keys: (builtins.map (key: "<${key}>") keys)) attr)
|
||||
(attr: (builtins.mapAttrs (_: keys: (builtins.concatStringsSep " " keys)) attr))
|
||||
(attr: (lib.attrsets.mapAttrsToList (sum: keys: ''<Multi_key> ${keys} : "${sum}"'') attr))
|
||||
(attr: builtins.concatStringsSep "\n" attr)
|
||||
];
|
||||
|
||||
binds = lib.concatStringsSep "\n" [
|
||||
# ''include "%L"''
|
||||
(makebinds {
|
||||
"ě" = [ "e" "j" ];
|
||||
|
||||
"ѣ" = [ "Cyrillic_ie" "Cyrillic_ie" ];
|
||||
"Ѣ" = [ "Cyrillic_IE" ];
|
||||
"ѳ" = [ "Cyrillic_ef" ];
|
||||
"ѵ" = [ "Cyrillic_i" ];
|
||||
"ґ" = [ "Cyrillic_ghe" ];
|
||||
"є" = [ "Cyrillic_ie" "Cyrillic_e" ];
|
||||
|
||||
"љ" = [ "Cyrillic_el" "Cyrillic_el" ];
|
||||
"њ" = [ "Cyrillic_en" "Cyrillic_en" ];
|
||||
|
||||
"ѧ" = [ "Cyrillic_e" "Cyrillic_en" ];
|
||||
"ѩ" = [ "Cyrillic_ie" "Cyrillic_en" ];
|
||||
"ѫ" = [ "Cyrillic_o" "Cyrillic_en" ];
|
||||
"ѭ" = [ "Cyrillic_io" "Cyrillic_en" ];
|
||||
|
||||
"¨" = [ "Colon" ];
|
||||
|
||||
"α" = [ "g" "a" ];
|
||||
"β" = [ "g" "b" ];
|
||||
"γ" = [ "g" "g" ];
|
||||
"λ" = [ "g" "l" ];
|
||||
})
|
||||
];
|
||||
|
||||
in {
|
||||
environment.variables.XCOMPOSEFILE = ".XCompose";
|
||||
hm = {
|
||||
home.file.".XCompose" = {
|
||||
enable = true;
|
||||
target = ".XCompose";
|
||||
recursive = false;
|
||||
text = binds;
|
||||
};
|
||||
|
||||
programs.niri.settings.input.keyboard.xkb.file = toString (pkgs.writeText "compose.xkb" binds);
|
||||
};
|
||||
}
|
690
modules/desktop/yambar.nix
Normal file
690
modules/desktop/yambar.nix
Normal file
@@ -0,0 +1,690 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
host,
|
||||
...
|
||||
}: let
|
||||
niri = lib.getExe pkgs.c.niri;
|
||||
jq = lib.getExe pkgs.jq;
|
||||
workspaces_script = pkgs.writeShellScript "workspaces.sh" ''
|
||||
workspaces_num () {
|
||||
IFS=$'\n'
|
||||
local r=$(${niri} msg -j workspaces | ${jq} '.[].idx' | sort -nr | head -n1)
|
||||
echo $r
|
||||
}
|
||||
|
||||
get_idx () {
|
||||
local r=$(${niri} msg -j workspaces)
|
||||
for (( i=0; i<$(workspaces_num); i+=1 ))
|
||||
do
|
||||
local act=$(echo $r | ${jq} .[$i].id)
|
||||
if [ $act -eq $1 ]; then
|
||||
local idx=$(echo $r | ${jq} .[$i].idx)
|
||||
echo $idx
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
get_before () {
|
||||
if [ $1 -eq "1" ]; then
|
||||
echo ""
|
||||
else
|
||||
a=
|
||||
for (( i=1; i<$1; i++ )) do
|
||||
a="$a $i"
|
||||
done
|
||||
echo $a
|
||||
fi
|
||||
}
|
||||
|
||||
get_after () {
|
||||
if [ $1 -eq $2 ]; then
|
||||
echo ""
|
||||
else
|
||||
a=
|
||||
for (( i=$1+1; i<=$2; i++ )) do
|
||||
a="$a $i"
|
||||
done
|
||||
echo $a
|
||||
fi
|
||||
}
|
||||
|
||||
ret_add () {
|
||||
echo "before|string|$(get_before $1)"
|
||||
echo "after|string|$(get_after $1 $2)"
|
||||
}
|
||||
|
||||
bnum=$(workspaces_num)
|
||||
echo "number|int|$bnum"
|
||||
|
||||
beg=$(${niri} msg -j workspaces)
|
||||
|
||||
cf () {
|
||||
for (( i=0; i<$2; i+=1 ))
|
||||
do
|
||||
bact=$(echo $1 | ${jq} .[$i].is_active)
|
||||
if [[ "$bact" == "true" ]]; then
|
||||
bf=$(echo $1 | ${jq} .[$i].idx)
|
||||
echo "$bf"
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
sf=`cf "$beg" "$bnum"`
|
||||
echo "focused|int|$sf"
|
||||
ret_add $sf $bnum
|
||||
|
||||
echo ""
|
||||
|
||||
${niri} msg -j event-stream | while read -r line; do
|
||||
current=$(echo $line | ${jq} .WorkspaceActivated.id)
|
||||
if [[ "$current" != "null" ]]; then
|
||||
cn=$(workspaces_num)
|
||||
idx=$(get_idx $current)
|
||||
echo "number|int|$cn"
|
||||
echo "focused|int|$idx"
|
||||
ret_add $idx $cn
|
||||
echo ""
|
||||
fi
|
||||
|
||||
current=$(echo $line | ${jq} .WorkspacesChanged.workspaces)
|
||||
if [[ "$current" != "null" ]]; then
|
||||
cn=$(workspaces_num)
|
||||
c=$(cf "$current" "$cn")
|
||||
idx=$c
|
||||
echo "number|int|$cn"
|
||||
echo "focused|int|$idx"
|
||||
ret_add $c $cn
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
lang_script = pkgs.writeShellScript "current_layout.sh" ''
|
||||
startl=$(${niri} msg -j keyboard-layouts | ${jq} .current_idx)
|
||||
echo "lang|int|$startl"
|
||||
echo ""
|
||||
|
||||
${niri} msg -j event-stream | while read -r line; do
|
||||
|
||||
current=$(echo $line | ${jq} .KeyboardLayoutSwitched.idx)
|
||||
if [[ "$current" != "null" ]]; then
|
||||
echo "lang|string|$current"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
'';
|
||||
in {
|
||||
hm.programs.yambar = {
|
||||
enable = true;
|
||||
settings.bar = let
|
||||
# std_underline = {
|
||||
# underline = {
|
||||
# size = 2;
|
||||
# color = "ff0000ff";
|
||||
# };
|
||||
# };
|
||||
red = config.lib.stylix.colors.base08 + "ff";
|
||||
orange = config.lib.stylix.colors.base09 + "ff";
|
||||
yellow = config.lib.stylix.colors.base0A + "ff";
|
||||
white = config.lib.stylix.colors.base05 + "ff";
|
||||
grey = "999999ff";
|
||||
|
||||
awesome = "Font Awesome 6 Free:style=solid:pixelsize=14";
|
||||
in {
|
||||
font = "FiraCode Nerd Font:pixelsize=12";
|
||||
height = 26;
|
||||
location = "top";
|
||||
spacing = 8;
|
||||
margin = 7;
|
||||
foreground = white;
|
||||
background = config.lib.stylix.colors.base00 + "cc";
|
||||
left = [
|
||||
{
|
||||
script = {
|
||||
path = workspaces_script;
|
||||
args = [
|
||||
];
|
||||
content = [
|
||||
{
|
||||
string = {
|
||||
text = "{before}";
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = " {focused} ";
|
||||
foreground = orange;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "{after}";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
{
|
||||
foreign-toplevel = {
|
||||
content = {
|
||||
map = {
|
||||
conditions = {
|
||||
"~activated" = {
|
||||
empty = {
|
||||
};
|
||||
};
|
||||
activated = [
|
||||
{
|
||||
string = {
|
||||
text = "{app-id}";
|
||||
foreground = orange;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
center = [
|
||||
{
|
||||
clock = {
|
||||
time-format = "%H:%M";
|
||||
content = [
|
||||
{
|
||||
string = {
|
||||
text = "{time}";
|
||||
on-click = "${lib.getExe pkgs.playerctl} play-pause";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
right = [
|
||||
{
|
||||
network = {
|
||||
content = {
|
||||
map = {
|
||||
default = {
|
||||
empty = {
|
||||
};
|
||||
};
|
||||
conditions = {
|
||||
"name == enp2s0" = {
|
||||
map = {
|
||||
conditions = {
|
||||
"~carrier" = {
|
||||
empty = {
|
||||
};
|
||||
};
|
||||
carrier = {
|
||||
map = {
|
||||
default = {
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
foreground = white;
|
||||
};
|
||||
};
|
||||
conditions = {
|
||||
"state == up && ipv4 != \"\"" = {
|
||||
string = {
|
||||
text = "";
|
||||
foreground = red;
|
||||
font = awesome;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
network = {
|
||||
poll-interval = 1000;
|
||||
content = {
|
||||
map = {
|
||||
default = {
|
||||
empty = {
|
||||
};
|
||||
};
|
||||
conditions = {
|
||||
"name == wlan0" = {
|
||||
map = {
|
||||
default = {
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
foreground = white;
|
||||
};
|
||||
};
|
||||
conditions = {
|
||||
"state == down" = {
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
foreground = red;
|
||||
};
|
||||
};
|
||||
"state == up" = {
|
||||
map = {
|
||||
default = [
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
];
|
||||
conditions = {
|
||||
"ipv4 == \"\"" = [
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
foreground = red;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
pipewire = let
|
||||
volume.conditions = {
|
||||
muted = {
|
||||
string = {
|
||||
text = "{cubic_volume}%";
|
||||
foreground = "999999ff";
|
||||
};
|
||||
};
|
||||
"~muted" = {
|
||||
string = {
|
||||
text = "{cubic_volume}%";
|
||||
};
|
||||
};
|
||||
};
|
||||
in {
|
||||
content.list.items = [
|
||||
{
|
||||
map.conditions = {
|
||||
"type == \"sink\"".map.conditions = {
|
||||
"bus == \"bluetooth\"" = {
|
||||
string = {
|
||||
text = " ";
|
||||
font = awesome;
|
||||
};
|
||||
};
|
||||
muted = {
|
||||
string = {
|
||||
text = " ";
|
||||
font = awesome;
|
||||
foreground = grey;
|
||||
};
|
||||
};
|
||||
"~muted" = [
|
||||
{
|
||||
ramp = {
|
||||
tag = "cubic_volume";
|
||||
items = [
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"type == \"source\"" = {
|
||||
map.conditions = {
|
||||
muted = {
|
||||
string = {
|
||||
text = " ";
|
||||
font = awesome;
|
||||
foreground = grey;
|
||||
};
|
||||
};
|
||||
"~muted" = {
|
||||
string = {
|
||||
text = " 🎙";
|
||||
font = awesome;
|
||||
foreground = yellow;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
{map."<<" = volume;}
|
||||
];
|
||||
};
|
||||
}
|
||||
{
|
||||
backlight = {
|
||||
name = "amdgpu_bl2";
|
||||
content = [
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "{percent}%";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
{
|
||||
battery = let
|
||||
discharging = {
|
||||
list = {
|
||||
items = [
|
||||
{
|
||||
ramp = {
|
||||
tag = "capacity";
|
||||
items = [
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
foreground = "ff0000ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
foreground = "ff0000ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
foreground = "ffa600ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
foreground = "00ff00ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "{capacity}%";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
in {
|
||||
name = if host == "tureis" then "BAT1" else "BAT0";
|
||||
poll-interval = 250;
|
||||
content = {
|
||||
map = {
|
||||
conditions = {
|
||||
"state == unknown" = {
|
||||
"<<" = discharging;
|
||||
};
|
||||
"state == discharging" = {
|
||||
"<<" = discharging;
|
||||
};
|
||||
"state == charging" = [
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
foreground = "00ff00ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "{capacity}%";
|
||||
};
|
||||
}
|
||||
];
|
||||
"state == full" = [
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
foreground = "00ff00ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "{capacity}%";
|
||||
};
|
||||
}
|
||||
];
|
||||
"state == \"not charging\"" = [
|
||||
{
|
||||
ramp = {
|
||||
tag = "capacity";
|
||||
items = [
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
foreground = "ff0000ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
foreground = "ffa600ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
foreground = "00ff00ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
foreground = "00ff00ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
foreground = "00ff00ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
foreground = "00ff00ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
foreground = "00ff00ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
foreground = "00ff00ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
foreground = "00ff00ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = " ";
|
||||
foreground = "00ff00ff";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "{capacity}%";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
clock = {
|
||||
date-format = "%d %B, %A";
|
||||
content = [
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "{date}";
|
||||
right-margin = 5;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
{
|
||||
script = {
|
||||
path = lang_script;
|
||||
args = [
|
||||
];
|
||||
content = {
|
||||
map = {
|
||||
default = {
|
||||
string = {
|
||||
text = "{lang}";
|
||||
};
|
||||
};
|
||||
conditions = {
|
||||
"lang == 0" = [
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "en";
|
||||
};
|
||||
}
|
||||
];
|
||||
"lang == 1" = [
|
||||
{
|
||||
string = {
|
||||
text = "";
|
||||
font = awesome;
|
||||
};
|
||||
}
|
||||
{
|
||||
string = {
|
||||
text = "ru";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
45
modules/global/bash.nix
Normal file
45
modules/global/bash.nix
Normal file
@@ -0,0 +1,45 @@
|
||||
{ config, pkgs, ... }: {
|
||||
globals.hm.programs.carapace = {
|
||||
enable = true;
|
||||
enableBashIntegration = true;
|
||||
};
|
||||
|
||||
globals.hm.programs.bash = {
|
||||
enable = true;
|
||||
shellAliases = config.n.misc.aliases;
|
||||
enableCompletion = true;
|
||||
|
||||
initExtra = ''
|
||||
#colorscript -e square
|
||||
_fix_cursor() {
|
||||
echo -ne '\e[5 q'
|
||||
}
|
||||
precmd_functions+=(_fix_cursor)
|
||||
export TERM="xterm-256color"
|
||||
PS1="\e[1;32m\u@\h\e[m \e[1;34m[\t]\e[m [\w]\n\e[0;34m-> %\e[m \e[0;32m"
|
||||
'';
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
wget
|
||||
curl
|
||||
tree
|
||||
htop
|
||||
killall
|
||||
jq
|
||||
p7zip
|
||||
tldr
|
||||
unzip
|
||||
mtr
|
||||
iperf3
|
||||
lsd
|
||||
bat
|
||||
ncdu
|
||||
ripgrep
|
||||
dig
|
||||
pwgen
|
||||
inxi
|
||||
alejandra
|
||||
tokei
|
||||
];
|
||||
}
|
17
modules/global/dnscrypt-proxy.nix
Normal file
17
modules/global/dnscrypt-proxy.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{ ... }: {
|
||||
services.dnscrypt-proxy2 = {
|
||||
enable = true;
|
||||
settings = {
|
||||
# listen_addresses = [ "127.0.0.1:53" ];
|
||||
listen_addresses = [ "0.0.0.0:53" ];
|
||||
max_clients = 200;
|
||||
force_tcp = true;
|
||||
netprobe_address = "192.168.1.1:53";
|
||||
server_names = [ "libredns-noads" "njalla-doh" ];
|
||||
};
|
||||
};
|
||||
|
||||
networking = {
|
||||
nameservers = [ "127.0.0.1" ];
|
||||
};
|
||||
}
|
6
modules/global/firewall.nix
Normal file
6
modules/global/firewall.nix
Normal file
@@ -0,0 +1,6 @@
|
||||
{ ... }: {
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [];
|
||||
allowedUDPPorts = [];
|
||||
};
|
||||
}
|
29
modules/global/git.nix
Normal file
29
modules/global/git.nix
Normal file
@@ -0,0 +1,29 @@
|
||||
{ pkgs, lib, ... }: {
|
||||
hm.programs.git.enable = true;
|
||||
environment.systemPackages = [ pkgs.git ];
|
||||
|
||||
hm.programs.git = {
|
||||
userEmail = "thary@riseup.net";
|
||||
userName = "Thary";
|
||||
signing = {
|
||||
signByDefault = true;
|
||||
};
|
||||
};
|
||||
|
||||
nodes.phoenix.hm = {
|
||||
programs.git.extraConfig = {
|
||||
commit.gpgsign = true;
|
||||
gpg.format = "ssh";
|
||||
gpg.ssh.allowedSignersFile = "~/.ssh/allowed_signers";
|
||||
user.signingkey = "~/.ssh/id_ed25519.pub";
|
||||
};
|
||||
home.file.".ssh/allowed_signers".text =
|
||||
# "* ${builtins.readFile /home/${username}/.ssh/id_ed25519.pub}";
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDEDqpSiQpbSsClh6UGb7Z2DA1Hy+EyePzTy+5hEVD/A";
|
||||
};
|
||||
|
||||
lib.n.misc.shellAliases = {
|
||||
gc = "${lib.getExe pkgs.git} commit -m";
|
||||
ga = "${lib.getExe pkgs.git} add";
|
||||
};
|
||||
}
|
26
modules/global/home-manager.nix
Executable file
26
modules/global/home-manager.nix
Executable file
@@ -0,0 +1,26 @@
|
||||
{ lib, username, config, inputs, ... }:
|
||||
with lib;
|
||||
{
|
||||
imports = [
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
(lib.mkAliasOptionModule [ "hm" ] [
|
||||
"home-manager"
|
||||
"users"
|
||||
username
|
||||
])
|
||||
];
|
||||
|
||||
options.globals.hm = mkOption { type = types.attrs; };
|
||||
config = {
|
||||
home-manager = {
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
# backupFileExtension = "hm-backup-" + pkgs.lib.readFile "${pkgs.runCommand "timestamp" {} "echo -n `date '+%Y%m%d%H%M%S'` > $out"}";
|
||||
backupFileExtension = "hm-backup-$(date \"+%Y%m%d%H%M%S\")";
|
||||
sharedModules = [ config.globals.hm ];
|
||||
};
|
||||
hm.home = {
|
||||
inherit (config.system) stateVersion;
|
||||
};
|
||||
};
|
||||
}
|
23
modules/global/locales.nix
Executable file
23
modules/global/locales.nix
Executable file
@@ -0,0 +1,23 @@
|
||||
{ ... }:
|
||||
let
|
||||
locales = "en_US.UTF-8";
|
||||
timezone = "Europe/Minsk";
|
||||
in {
|
||||
time.timeZone = timezone;
|
||||
|
||||
i18n = {
|
||||
defaultLocale = locales;
|
||||
extraLocaleSettings = {
|
||||
# LC_ADDRESS = locales;
|
||||
# LC_MEASUREMENT = locales;
|
||||
# LC_MONETARY = locales;
|
||||
# LC_NAME = locales;
|
||||
# LC_NUMERIC = locales;
|
||||
# LC_PAPER = locales;
|
||||
# LC_TELEPHONE = locales;
|
||||
# LC_TIME = locales;
|
||||
LANGUAGE = locales;
|
||||
LC_ALL = locales;
|
||||
};
|
||||
};
|
||||
}
|
8
modules/global/networking.nix
Normal file
8
modules/global/networking.nix
Normal file
@@ -0,0 +1,8 @@
|
||||
{ ... }: {
|
||||
# nodes.cepheus.networking.interfaces.ens18 = {
|
||||
# ipv4.addresses = [{
|
||||
# address = "158.220.126.56";
|
||||
# prefixLength = 24;
|
||||
# }];
|
||||
# };
|
||||
}
|
29
modules/global/nix.nix
Normal file
29
modules/global/nix.nix
Normal file
@@ -0,0 +1,29 @@
|
||||
{ pkgs, lib, inputs, username, config, ... }: {
|
||||
# imp.home.dirs = [ ".local/share/nix" ]; # Nix Repl history
|
||||
nix = {
|
||||
package = pkgs.lix;
|
||||
settings = {
|
||||
allowed-users = ["root" "@wheel"];
|
||||
trusted-users = [ "root" username ];
|
||||
experimental-features = ["nix-command" "flakes"];
|
||||
build-dir = "/nix/builds";
|
||||
};
|
||||
registry = lib.mapAttrs (_: value: {flake = value;}) inputs // { n.flake = inputs.nixpkgs; };
|
||||
nixPath = lib.mapAttrsToList (key: value: "${key}=${value.to.path}") config.nix.registry;
|
||||
};
|
||||
|
||||
system.stateVersion = "23.05"; # My first nixos was 22.11
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(import ../../pkgs)
|
||||
];
|
||||
|
||||
# documentation = {
|
||||
# enable = true;
|
||||
# doc.enable = true;
|
||||
# dev.enable = true;
|
||||
# info.enable = true;
|
||||
# nixos.enable = true;
|
||||
# man.enable = true;
|
||||
# };
|
||||
}
|
44
modules/global/nvim.nix
Normal file
44
modules/global/nvim.nix
Normal file
@@ -0,0 +1,44 @@
|
||||
{ config, ...}: {
|
||||
globals.hm = {
|
||||
programs.neovim = {
|
||||
enable = true;
|
||||
defaultEditor = true;
|
||||
viAlias = true;
|
||||
vimAlias = true;
|
||||
|
||||
extraLuaConfig = ''
|
||||
local bind = vim.keymap.set
|
||||
local opt = vim.opt
|
||||
local g = vim.g
|
||||
local o = vim.o
|
||||
local cmd = vim.cmd
|
||||
|
||||
o.expandtab = true
|
||||
o.smarttab = true
|
||||
o.cindent = true
|
||||
o.autoindent = true
|
||||
|
||||
o.ignorecase = true
|
||||
o.smartcase = true
|
||||
|
||||
o.backup = false
|
||||
o.writebackup = false
|
||||
o.undofile = true
|
||||
o.swapfile = false
|
||||
|
||||
opt.relativenumber = true
|
||||
opt.number = true
|
||||
opt.tabstop = 2
|
||||
opt.shiftwidth = 2
|
||||
opt.mouse = "a"
|
||||
opt.termguicolors = true
|
||||
opt.clipboard = "unnamedplus"
|
||||
'';
|
||||
|
||||
home.sessionVariables = {
|
||||
# EDITOR = lib.mkForce lib.getExe pkgs.neovim;
|
||||
MANPAGER = "${config.hm.home.sessionVariables.EDITOR} +Man!";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
38
modules/global/secrets.nix
Normal file
38
modules/global/secrets.nix
Normal file
@@ -0,0 +1,38 @@
|
||||
{ inputs, host, lib, ... }:
|
||||
let
|
||||
keys = {
|
||||
phoenix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsrEEXQwcu4i7hOqCbpwd4EdC/+v9fAWm30MUXhVpp5";
|
||||
cepheus = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGm1PymMJ2JnE973UCaezWQFKyZi7lsAzHshUUwafa8F";
|
||||
naos = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIcR9C753wDWjg/oJxn6p9kLMaiaOPJFNT0xYPICXK52";
|
||||
};
|
||||
in {
|
||||
environment.systemPackages = [ inputs.agenix-rekey.packages.x86_64-linux.default ];
|
||||
imports = [
|
||||
inputs.agenix.nixosModules.default
|
||||
inputs.agenix-rekey.nixosModules.default
|
||||
];
|
||||
|
||||
age.identityPaths = [ "/nix/keys/identity" ]; # default key path
|
||||
age.rekey = {
|
||||
masterIdentities = [
|
||||
{ identity = "/home/user/.ssh/id_ed25519";
|
||||
pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDEDqpSiQpbSsClh6UGb7Z2DA1Hy+EyePzTy+5hEVD/A"; }
|
||||
];
|
||||
storageMode = "local";
|
||||
generatedSecretsDir = ../../secrets/generated/${host};
|
||||
localStorageDir = ../../secrets/rekeyed/${host};
|
||||
};
|
||||
|
||||
# services.openssh.enable = true;
|
||||
services.openssh.hostKeys = [{
|
||||
path = "/nix/keys/identity";
|
||||
type = "ed25519";
|
||||
}];
|
||||
|
||||
# TODO: define key via hosts/<name>/default.nix
|
||||
|
||||
nodes.phoenix.age.rekey.hostPubkey = keys.phoenix;
|
||||
nodes.cepheus.age.rekey.hostPubkey = keys.cepheus;
|
||||
# nodes.tureis.age.rekey.hostPubkey = ""; # TODO
|
||||
nodes.naos.age.rekey.hostPubkey = keys.naos;
|
||||
}
|
26
modules/global/security.nix
Normal file
26
modules/global/security.nix
Normal file
@@ -0,0 +1,26 @@
|
||||
{ username, pkgs, ... }: {
|
||||
security = {
|
||||
doas = {
|
||||
enable = true;
|
||||
wheelNeedsPassword = true;
|
||||
};
|
||||
sudo.enable = false;
|
||||
|
||||
# polkit.enable = lib.mkForce false;
|
||||
polkit.enable = true;
|
||||
};
|
||||
|
||||
|
||||
n.misc.aliases.sudo = "doas";
|
||||
|
||||
security.tpm2 = {
|
||||
enable = true;
|
||||
pkcs11.enable = true;
|
||||
pkcs11.package = pkgs.tpm2-pkcs11-fapi;
|
||||
tctiEnvironment.enable = true;
|
||||
};
|
||||
users.users.${username}.extraGroups = [ "tss" "admin" ];
|
||||
|
||||
environment.systemPackages = with pkgs; [ tpm2-pkcs11-fapi clevis tpm2-tools ];
|
||||
environment.variables.TPM2_PKCS11_BACKEND = "fapi";
|
||||
}
|
15
modules/n/aliases.nix
Normal file
15
modules/n/aliases.nix
Normal file
@@ -0,0 +1,15 @@
|
||||
{ lib, pkgs, ... }:
|
||||
with lib; {
|
||||
options.n.misc.aliases = mkOption {
|
||||
type = types.attrs;
|
||||
};
|
||||
config.n.misc.aliases = {
|
||||
ls = "${lib.getExe pkgs.lsd} --group-directories-first";
|
||||
la = "${lib.getExe pkgs.lsd} -l";
|
||||
cat = "${lib.getExe pkgs.bat}";
|
||||
dcat = "${lib.getExe pkgs.bat} --plain";
|
||||
list-generations = "nix-env -p /nix/var/nix/profiles/system --list-generations";
|
||||
delete-generations = "nix-env -p /nix/var/nix/profiles/system --delete-generations";
|
||||
myip = "${lib.getExe pkgs.curl} ipwho.de/json | ${lib.getExe pkgs.jq} .";
|
||||
};
|
||||
}
|
42
modules/n/bootloader.nix
Normal file
42
modules/n/bootloader.nix
Normal file
@@ -0,0 +1,42 @@
|
||||
{ lib, pkgs, config, inputs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.n.host.bootloader;
|
||||
in {
|
||||
options.n.host.bootloader = mkOption { type = types.str; };
|
||||
|
||||
imports = [ inputs.lanzaboote.nixosModules.lanzaboote ];
|
||||
config = mkMerge [
|
||||
(mkIf (cfg == "lanzaboote") {
|
||||
environment.systemPackages = [ pkgs.sbctl ];
|
||||
|
||||
boot = {
|
||||
loader = {
|
||||
systemd-boot.enable = lib.mkForce false;
|
||||
grub.enable = lib.mkForce false;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
bootspec.enable = true;
|
||||
lanzaboote = {
|
||||
enable = true;
|
||||
pkiBundle = "/var/lib/sbctl";
|
||||
};
|
||||
};
|
||||
|
||||
imp.dirs = [ { directory = "/var/lib/sbctl"; mode = "0400"; } ];
|
||||
})
|
||||
|
||||
(mkIf (cfg == "grub") {
|
||||
boot.loader.grub = {
|
||||
enable = true;
|
||||
efiSupport = lib.mkDefault false;
|
||||
# efiInstallAsRemovable = true; # TODO: what's it?
|
||||
device = "nodev";
|
||||
};
|
||||
boot.loader.systemd-boot.enable = lib.mkForce false;
|
||||
})
|
||||
(mkIf (cfg == "sysdboot") {
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
})
|
||||
];
|
||||
}
|
23
modules/n/default.nix
Normal file
23
modules/n/default.nix
Normal file
@@ -0,0 +1,23 @@
|
||||
{ lib, config, pkgs, host, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.n.host;
|
||||
in {
|
||||
options.n.host = {
|
||||
kernel = mkOption {
|
||||
type = types.raw;
|
||||
default = pkgs.linuxKernel.packages.linux_6_1_hardened;
|
||||
};
|
||||
|
||||
users = mkOption { type = with types; attrs; default = {}; };
|
||||
defaultUser = mkOption { type = type.str; };
|
||||
extras = mkOption { type = with types; listOf path; };
|
||||
types = mkOption { type = with types; listOf str; };
|
||||
};
|
||||
options.nodes = mkOption { type = with types; attrsOf attrs; };
|
||||
|
||||
config = {
|
||||
boot.kernelPackages = cfg.kernel;
|
||||
users.users = cfg.users;
|
||||
};
|
||||
}
|
16
modules/n/defaults.nix
Normal file
16
modules/n/defaults.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{ lib, config, ... }:
|
||||
with lib; { # Thanks to azahi!
|
||||
options.n.misc.defaults = mkOption {
|
||||
description = "Default applications.";
|
||||
type = with types; attrsOf (listOf str);
|
||||
default = {};
|
||||
};
|
||||
|
||||
config.hm.xdg = {
|
||||
enable = true;
|
||||
mimeApps = {
|
||||
enable = true;
|
||||
defaultApplications = mkMerge (mapAttrsToList (n: v: genAttrs v (_: [ "${n}.desktop" ])) config.n.misc.defaults);
|
||||
};
|
||||
};
|
||||
}
|
41
modules/n/hardware.nix
Normal file
41
modules/n/hardware.nix
Normal file
@@ -0,0 +1,41 @@
|
||||
{ lib, config, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.n.host.hardware;
|
||||
in {
|
||||
options.n.host.hardware = {
|
||||
cpu = mkOption { type = types.str; default = ""; };
|
||||
};
|
||||
config = mkMerge [
|
||||
(mkIf (cfg.cpu == "amd")
|
||||
{
|
||||
boot.kernelModules = [ "kvm-amd" ];
|
||||
hardware.cpu.amd.updateMicrocode = true;
|
||||
}
|
||||
)
|
||||
(mkIf (cfg.cpu == "intel")
|
||||
{
|
||||
hardware.cpu.intel.updateMicrocode = true;
|
||||
}
|
||||
)
|
||||
(mkIf (cfg.cpu == "virt")
|
||||
{
|
||||
boot.initrd.availableKernelModules = [
|
||||
"virtio_net"
|
||||
"virtio_pci"
|
||||
"virtio_mmio"
|
||||
"virtio_blk"
|
||||
"virtio_scsi"
|
||||
"9p"
|
||||
"9pnet_virtio"
|
||||
];
|
||||
boot.initrd.kernelModules = [
|
||||
"virtio_balloon"
|
||||
"virtio_console"
|
||||
"virtio_rng"
|
||||
"virtio_gpu"
|
||||
];
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
64
modules/n/impermanence.nix
Normal file
64
modules/n/impermanence.nix
Normal file
@@ -0,0 +1,64 @@
|
||||
{ lib, config, inputs, username, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.imp;
|
||||
in {
|
||||
imports = [
|
||||
inputs.impermanence.nixosModules.impermanence
|
||||
(mkAliasOptionModule [ "imp" "dirs" ] [
|
||||
"environment"
|
||||
"persistence"
|
||||
"/nix/persist"
|
||||
"directories"
|
||||
])
|
||||
];
|
||||
|
||||
options.imp.home = {
|
||||
files = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
};
|
||||
dirs = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
environment.persistence."/nix/persist" = {
|
||||
enable = true;
|
||||
directories = [
|
||||
"/var/lib/systemd/coredump"
|
||||
"/var/lib/nixos"
|
||||
];
|
||||
files = [
|
||||
"/etc/machine-id"
|
||||
];
|
||||
};
|
||||
|
||||
environment.persistence."/nix/persist".users."${username}" = {
|
||||
# environment.persistence."/nix/persist".users."user" = {
|
||||
directories = builtins.map (x: { directory = x; mode = "0700"; })
|
||||
[
|
||||
"Audiobooks"
|
||||
"Books"
|
||||
"Desktop"
|
||||
"Documents"
|
||||
# "Downloads"
|
||||
"Extensions"
|
||||
"Forks"
|
||||
"Games"
|
||||
"IdeaProjects"
|
||||
"Keybase"
|
||||
"Library"
|
||||
"Monero"
|
||||
"Music"
|
||||
"Phone"
|
||||
"Pictures"
|
||||
"Projects"
|
||||
"Videos"
|
||||
] ++ cfg.home.dirs;
|
||||
files = builtins.map (x: { file = x; parentDirectory = { mode = "0700"; }; }) cfg.home.files;
|
||||
};
|
||||
};
|
||||
}
|
22
modules/n/networking.nix
Normal file
22
modules/n/networking.nix
Normal file
@@ -0,0 +1,22 @@
|
||||
{ host, lib, config, ... }:
|
||||
with lib;
|
||||
let cfg = config.n.host;
|
||||
in {
|
||||
options.n.host = {
|
||||
hostId = mkOption { type = types.str; };
|
||||
domain = mkOption { type = types.str; default = "${host}.local"; };
|
||||
};
|
||||
|
||||
config = {
|
||||
networking = {
|
||||
hostName = host;
|
||||
hostId = cfg.hostId;
|
||||
domain = cfg.domain;
|
||||
dhcpcd.enable = true;
|
||||
useDHCP = lib.mkDefault true;
|
||||
};
|
||||
systemd.network.wait-online.enable = lib.mkForce false;
|
||||
boot.initrd.systemd.network.wait-online.enable = lib.mkForce false;
|
||||
systemd.services.NetworkManager-wait-online.enable = lib.mkForce false;
|
||||
};
|
||||
}
|
13
modules/n/unfree.nix
Normal file
13
modules/n/unfree.nix
Normal file
@@ -0,0 +1,13 @@
|
||||
{ lib, config, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.n.misc.unfreePackages;
|
||||
in {
|
||||
options.n.misc.unfreePackages = mkOption {
|
||||
type = with types; listOf str;
|
||||
};
|
||||
|
||||
config = {
|
||||
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) cfg;
|
||||
};
|
||||
}
|
36
modules/server/containers.nix
Normal file
36
modules/server/containers.nix
Normal file
@@ -0,0 +1,36 @@
|
||||
{ host, lib, config, ... }: {
|
||||
networking.nat = {
|
||||
enable = true;
|
||||
# Use "ve-*" when using nftables instead of iptables
|
||||
internalInterfaces = ["ve-+"];
|
||||
externalInterface = "ens18";
|
||||
enableIPv6 = false;
|
||||
};
|
||||
|
||||
containers =
|
||||
if builtins.pathExists ../../hosts/${host}/containers
|
||||
then let
|
||||
containers_files' = builtins.readDir ../../hosts/${host}/containers;
|
||||
containers_files = lib.concatMapAttrs
|
||||
(container: _: {
|
||||
${lib.removeSuffix ".nix" container} = {};
|
||||
}) containers_files';
|
||||
|
||||
in builtins.mapAttrs (container: _: {
|
||||
autoStart = true;
|
||||
bindMounts = builtins.mapAttrs (_: value: { hostPath = value; isReadOnly = false; }) config.container.${container}.config.binds;
|
||||
tmpfs = [ "/" ];
|
||||
config = { lib, ... }: with lib; {
|
||||
imports = [
|
||||
../../hosts/${host}/containers/${container}.nix
|
||||
# ../containers
|
||||
../global/nix.nix
|
||||
../global/dnscrypt-proxy.nix
|
||||
];
|
||||
options = {
|
||||
binds = mkOption { type = types.attrs; default = {}; };
|
||||
};
|
||||
};
|
||||
}) containers_files
|
||||
else {};
|
||||
}
|
19
modules/server/openssh.nix
Normal file
19
modules/server/openssh.nix
Normal file
@@ -0,0 +1,19 @@
|
||||
{ username, ... }: let
|
||||
keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINkHOpdBpYV3KJV+AtBK3jD6MLDZzAwh9HFt0LsLxBV0" # Old key
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDEDqpSiQpbSsClh6UGb7Z2DA1Hy+EyePzTy+5hEVD/A" # Main key
|
||||
];
|
||||
in {
|
||||
users.users.${username}.openssh.authorizedKeys.keys = keys;
|
||||
users.users.root.openssh.authorizedKeys.keys = keys;
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
PasswordAuthentication = false;
|
||||
KbdInteractiveAuthentication = false;
|
||||
PermitRootLogin = "prohibit-password";
|
||||
};
|
||||
ports = [ 22 ];
|
||||
openFirewall = true;
|
||||
};
|
||||
}
|
3
pkgs/SynapseRevitalization/.editorconfig
Normal file
3
pkgs/SynapseRevitalization/.editorconfig
Normal file
@@ -0,0 +1,3 @@
|
||||
[*.py]
|
||||
indent_style = space
|
||||
indent_size = 4
|
1
pkgs/SynapseRevitalization/.gitignore
vendored
Normal file
1
pkgs/SynapseRevitalization/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
__pycache__/
|
27
pkgs/SynapseRevitalization/default.nix
Normal file
27
pkgs/SynapseRevitalization/default.nix
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
python313Packages,
|
||||
python313,
|
||||
writeShellScript,
|
||||
}:
|
||||
python313Packages.buildPythonApplication rec {
|
||||
projectDir = ./.;
|
||||
pname = "synapse-revitalization";
|
||||
version = "0.1.0";
|
||||
pyproject = false;
|
||||
|
||||
src = ./.;
|
||||
|
||||
installPhase =
|
||||
let python = python313.withPackages (ps: with ps; [ requests signedjson systemd ]);
|
||||
script = writeShellScript "synapse-revitalization" "${python}/bin/python $out/main.py '$1'";
|
||||
in ''
|
||||
mkdir -p $out/bin
|
||||
cp $src/* $out
|
||||
# cp ${script} $out/bin
|
||||
cat > $out/bin/synapse-revitalization << EOF
|
||||
#!/bin/sh
|
||||
exec ${python}/bin/python $out/main.py "\$1"
|
||||
EOF
|
||||
chmod +x $out/bin/synapse-revitalization
|
||||
'';
|
||||
}
|
58
pkgs/SynapseRevitalization/flake.lock
generated
Normal file
58
pkgs/SynapseRevitalization/flake.lock
generated
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1692799911,
|
||||
"narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1750776420,
|
||||
"narHash": "sha256-/CG+w0o0oJ5itVklOoLbdn2dGB0wbZVOoDm4np6w09A=",
|
||||
"path": "/nix/store/1l4nm55xcq55cdp1xz3x5mfgr4c24058-source",
|
||||
"rev": "30a61f056ac492e3b7cdcb69c1e6abdcf00e39cf",
|
||||
"type": "path"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
20
pkgs/SynapseRevitalization/flake.nix
Normal file
20
pkgs/SynapseRevitalization/flake.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
description = "my project description";
|
||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem
|
||||
(
|
||||
system: let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in {
|
||||
devShells.default = pkgs.mkShell {
|
||||
packages = with pkgs; [python313Full python313Packages.signedjson python313Packages.requests python313Packages.systemd python313Packages.setuptools black];
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
20
pkgs/SynapseRevitalization/get_config.py
Normal file
20
pkgs/SynapseRevitalization/get_config.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import os
|
||||
|
||||
def read_vars():
|
||||
if os.environ.get("SYNAPSE_REVITALIZATION_AUTH_TOKEN_TERM") == None:
|
||||
auth_token_term = 180
|
||||
else:
|
||||
auth_token_term = os.environ["SYNAPSE_REVITALIZATION_AUTH_TOKEN_TERM"]
|
||||
|
||||
admin_auth_token_file = os.environ["SYNAPSE_REVITALIZATION_ADMIN_AUTH_TOKEN_FILE"]
|
||||
|
||||
with open(admin_auth_token_file, "r") as file:
|
||||
admin_auth_token = file.read().split("\n")[0]
|
||||
|
||||
return {
|
||||
"auth_token_term": auth_token_term,
|
||||
"admin_auth_token": admin_auth_token,
|
||||
"server_key_file": os.environ["SYNAPSE_REVITALIZATION_SERVER_KEY_FILE"],
|
||||
"origin_server_name": os.environ["SYNAPSE_REVITALIZATION_SERVER_NAME"],
|
||||
"origin_server": os.environ["SYNAPSE_REVITALIZATION_SERVER_ADDRESS"],
|
||||
}
|
35
pkgs/SynapseRevitalization/main.py
Normal file
35
pkgs/SynapseRevitalization/main.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from systemd import journal
|
||||
from revitalize import revitalize, parse_roomid
|
||||
import sys
|
||||
|
||||
if len(sys.argv) != 2: # 2, because running the script looks like 'python [1]main.py [2]"..."'
|
||||
print("synapse-revitalization accepts only 1 argument")
|
||||
exit()
|
||||
else:
|
||||
message = sys.argv[1]
|
||||
|
||||
if "Ignoring PDU for unknown room_id" in message:
|
||||
journal.send("[info] Got error message: %s" % message)
|
||||
roomid = message.rsplit(maxsplit=1)[1]
|
||||
x = revitalize(roomid, parse_roomid(roomid))
|
||||
if x == True:
|
||||
journal.send("[info] Successfully made all users rejoin {roomid} via {server}")
|
||||
journal.send("[info] {roomid} is available now")
|
||||
elif x == False:
|
||||
journal.send("ERROR! Couldn't make {roomid} available via {parse_roomid(roomid)}")
|
||||
|
||||
|
||||
elif "as we're not in the room" in message:
|
||||
journal.send("[info] Got error message: %s" % message)
|
||||
roomid = message.split("'")[1]
|
||||
server = message.split("from server ")[1].split(" ")[0]
|
||||
for i in [server, parse_roomid(roomid)]:
|
||||
x = revitalize(roomid, i)
|
||||
if x == True:
|
||||
journal.send(f"[info] Successfully made all users rejoin {roomid} via {server}")
|
||||
journal.send(f"[info] {roomid} is available now")
|
||||
break
|
||||
elif x == False:
|
||||
journal.send(f"[WARNING] Couldn't make users rejoin {roomid} via {server}")
|
||||
if i == parse_roomid(roomid):
|
||||
journal.send(f"ERROR! Couldn't make {roomid} available via {server} nor {parse_roomid(roomid)}")
|
198
pkgs/SynapseRevitalization/revitalize.py
Normal file
198
pkgs/SynapseRevitalization/revitalize.py
Normal file
@@ -0,0 +1,198 @@
|
||||
from signedjson.key import read_signing_keys
|
||||
from signedjson.sign import sign_json
|
||||
import json
|
||||
|
||||
import requests
|
||||
from systemd import journal
|
||||
from get_config import read_vars
|
||||
|
||||
import datetime
|
||||
|
||||
# Importing configuration from environment variables
|
||||
config = read_vars()
|
||||
|
||||
|
||||
# Getting signing key
|
||||
with open(config["server_key_file"]) as f:
|
||||
skey = read_signing_keys(f)[0]
|
||||
|
||||
|
||||
# Defining additional functions
|
||||
def current_time():
|
||||
now = datetime.datetime.now()
|
||||
return int(now.timestamp() * 1000)
|
||||
|
||||
def parse_roomid(roomid):
|
||||
return roomid.split(":")[1]
|
||||
|
||||
def serveraddr(servername):
|
||||
x = requests.get("https://%s/.well-known/matrix/server" % servername)
|
||||
if x.status_code == 200:
|
||||
j = json.loads(x.text)
|
||||
return j["m.server"]
|
||||
else:
|
||||
journal.send(f"[WARNING] Got {x.status_code} discovering server address of {servername}")
|
||||
return False
|
||||
|
||||
|
||||
# Function for getting users' access tokens
|
||||
def get_access_token(userid):
|
||||
time = current_time() + config["auth_token_term"] * 1000
|
||||
x = requests.post(
|
||||
f"https://{config['origin_server']}/_synapse/admin/v1/users/{userid}/login",
|
||||
json={"valid_until_ms": time},
|
||||
headers={
|
||||
"Authorization": "Bearer %s" % config["admin_auth_token"],
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
).text
|
||||
if "You are not a server admin" in x:
|
||||
journal.send("ERROR! The given token doesn't belogn to the server admin!")
|
||||
exit()
|
||||
y = json.loads(x)
|
||||
return y["access_token"]
|
||||
|
||||
|
||||
# Sign Matrix federation API requests
|
||||
## From Matrix protocol documentation
|
||||
def authorization_headers(
|
||||
destination_name, request_method, request_target, content=None
|
||||
):
|
||||
origin_name = config["origin_server_name"]
|
||||
request_json = {
|
||||
"method": request_method,
|
||||
"uri": request_target,
|
||||
"origin": origin_name,
|
||||
"destination": destination_name,
|
||||
}
|
||||
|
||||
if content is not None:
|
||||
request_json["content"] = content
|
||||
|
||||
signed_json = sign_json(request_json, origin_name, skey)
|
||||
|
||||
for key, sig in signed_json["signatures"][origin_name].items():
|
||||
return 'X-Matrix origin="%s",destination="%s",key="%s",sig="%s"' % (
|
||||
origin_name,
|
||||
destination_name,
|
||||
key,
|
||||
sig,
|
||||
)
|
||||
|
||||
|
||||
# Request the last event
|
||||
def request_last_event(destination, roomid):
|
||||
servers = [destination, "matrix.org", "inex.rocks", "sibnsk.net", "kde.org"]
|
||||
for i in servers:
|
||||
journal.send(f"[info] Trying access event_to_timestamp via {i}")
|
||||
try:
|
||||
server = serveraddr(i)
|
||||
except requests.exceptions.ConnectionError:
|
||||
journal.send(f"[WARNING] {i}'s well-known's are unreachable")
|
||||
continue
|
||||
except:
|
||||
journal.send(f"[WARNING] Can't request {i}'s well-known's for unknown reason. Likely {i} is unreachable or ssl certs expired")
|
||||
continue
|
||||
if server == False:
|
||||
continue
|
||||
|
||||
res = current_time()
|
||||
auth = authorization_headers(
|
||||
i,
|
||||
"GET",
|
||||
f"/_matrix/federation/v1/timestamp_to_event/{roomid}?dir=b&ts={res}",
|
||||
)
|
||||
try:
|
||||
x = requests.get(
|
||||
f"https://{server}/_matrix/federation/v1/timestamp_to_event/{roomid}",
|
||||
params={"dir": "b", "ts": res},
|
||||
headers={"Authorization": auth},
|
||||
).text
|
||||
except requests.exceptions.ConnectionError:
|
||||
journal.send(f"[WARNING] {server} is unreachable")
|
||||
continue
|
||||
except:
|
||||
journal.send(f"[WARNING] Couldn't request timestamp_to_event from {server} for unknown reason. Likely {server} is unreachable or ssl certs expired")
|
||||
continue
|
||||
|
||||
if "M_UNRECOGNIZED" in x:
|
||||
journal.send(f"[WARNING] Trying request {server} timestamp_to_event for {roomid}: got M_UNRECOGNIZED error")
|
||||
continue
|
||||
elif "M_NOT_FOUND" in x:
|
||||
journal.send(f"[WARNING] Unable to get the last event from {roomid}. {i} doesn't know room {roomid}")
|
||||
journal.send(f"{i} says: '{x}'")
|
||||
continue
|
||||
elif "event_id" in x:
|
||||
j = json.loads(x)
|
||||
return (i, server, j["event_id"])
|
||||
else:
|
||||
journal.send(f"[WARNING] Unable to get the last event from {roomid}. Unknown error from {server}: '{x}'")
|
||||
continue
|
||||
|
||||
journal.send(f"ERROR! Unable to get the last event from {roomid}. All {servers} don't know room {roomid} or support timestamp_to_event")
|
||||
return False
|
||||
|
||||
|
||||
# Request states of specified room
|
||||
def get_states(destination, server, roomid, last_event_id):
|
||||
auth = authorization_headers(
|
||||
destination, "GET", "/_matrix/federation/v1/state/%s?event_id=%s" % (roomid, last_event_id)
|
||||
)
|
||||
return requests.get(
|
||||
f"https://{server}/_matrix/federation/v1/state/{roomid}?event_id={last_event_id}",
|
||||
headers={"Authorization": auth},
|
||||
).text
|
||||
|
||||
|
||||
# Get users list from states
|
||||
def get_users(states):
|
||||
x = json.loads(states)
|
||||
# jq .pdus.[].type
|
||||
users = []
|
||||
x = x["pdus"]
|
||||
for i in x:
|
||||
if i["type"] == "m.room.member":
|
||||
users.append(i["sender"])
|
||||
return users
|
||||
|
||||
def filter_users(users):
|
||||
x = []
|
||||
for i in users:
|
||||
if f":{config["origin_server_name"]}" in i:
|
||||
x.append(i)
|
||||
return x
|
||||
|
||||
|
||||
# Make a user join a room
|
||||
def mkjoins(roomid, users, server1, server2):
|
||||
for i in users:
|
||||
token = get_access_token(i)
|
||||
x = requests.post(
|
||||
f"https://{config['origin_server']}/_matrix/client/v3/join/{roomid}",
|
||||
params={"via": server1, "via": server2},
|
||||
headers={"Authorization": "Bearer %s" % token},
|
||||
).text
|
||||
if roomid in x:
|
||||
journal.send(f"[info] Joined {i} to {roomid}")
|
||||
journal.send(x)
|
||||
return True
|
||||
else:
|
||||
journal.send(f"[info] Failed to join {i} to {roomid}")
|
||||
journal.send(x)
|
||||
return False
|
||||
|
||||
|
||||
def revitalize(roomid, server):
|
||||
journal.send(f"Got new roomid {roomid}")
|
||||
fe = request_last_event(server, roomid)
|
||||
if fe == False:
|
||||
return False
|
||||
else:
|
||||
x = get_states(fe[0], fe[1], roomid, fe[2])
|
||||
y = get_users(x)
|
||||
z = filter_users(y)
|
||||
journal.send(f"Trying to add {z} to {roomid}")
|
||||
if mkjoins(roomid, z, server, fe[0]):
|
||||
return True
|
||||
else:
|
||||
return False
|
3
pkgs/default.nix
Normal file
3
pkgs/default.nix
Normal file
@@ -0,0 +1,3 @@
|
||||
final: prev: {
|
||||
synapse-revitalization = final.callPackage ./SynapseRevitalization {};
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user