├── .envrc
├── .gitignore
├── .projectile
├── .vscode
└── tasks.json
├── LICENSE
├── README.md
├── compat
└── default.nix
├── default.nix
├── flake.lock
├── flake.nix
├── lib.nix
├── machines
├── AMD-Workstation
│ ├── default.nix
│ ├── hardware-configuration.nix
│ └── system
├── Librem5-Phone
│ ├── default.nix
│ ├── hardware-configuration.nix
│ └── system
├── RasPi-Server
│ ├── default.nix
│ ├── hardware-configuration.nix
│ └── system
├── T420-Laptop
│ ├── default.nix
│ ├── hardware-configuration.nix
│ └── system
├── T490s-Laptop
│ ├── default.nix
│ ├── hardware-configuration.nix
│ └── system
├── X2100-Laptop
│ ├── default.nix
│ ├── hardware-configuration.nix
│ └── system
├── iso-image
│ ├── default.nix
│ └── system
├── server
│ ├── default.nix
│ └── system
└── usb-persist
│ ├── default.nix
│ ├── hardware-configuration.nix
│ └── system
├── modules
├── applications.nix
├── bt-agent.nix
├── devices.nix
├── ezwg.nix
├── persist.nix
├── plasma5.nix
├── secrets-envsubst.nix
├── secrets.nix
└── themes.nix
├── overlay.nix
├── profiles
├── applications-setup.nix
├── applications
│ ├── aerc.nix
│ ├── alacritty.nix
│ ├── angelfish.nix
│ ├── cantata.nix
│ ├── emacs
│ │ ├── default.nix
│ │ ├── init.el
│ │ └── org-gcal-config.el
│ ├── firefox.nix
│ ├── geary.nix
│ ├── github.nix
│ ├── gwenview.nix
│ ├── helix.nix
│ ├── himalaya.nix
│ ├── josm.nix
│ ├── nheko.nix
│ ├── okular.nix
│ ├── packages.nix
│ ├── qmlkonsole.nix
│ ├── slack.nix
│ ├── sylpheed.nix
│ └── vscodium
│ │ ├── default.nix
│ │ ├── extensions.nix
│ │ └── theme.nix
├── bluetooth.nix
├── boot.nix
├── hardware.nix
├── network.nix
├── nix
│ ├── default.nix
│ └── expr-context.patch
├── opengl.nix
├── power.nix
├── security
│ ├── pass-secret-service.nix
│ ├── user.nix
│ ├── vlock.nix
│ └── yubikey.nix
├── servers
│ ├── gitea.nix
│ ├── home-assistant.nix
│ ├── irc.nix
│ ├── jitsi.nix
│ ├── mailserver.nix
│ ├── mastodon.nix
│ ├── matrix-synapse.nix
│ ├── minidlna.nix
│ ├── nextcloud.nix
│ ├── nginx.nix
│ ├── ntfy.nix
│ ├── remapper.nix
│ └── vsftpd.nix
├── sound.nix
├── virtualisation.nix
└── workspace
│ ├── autoRun.nix
│ ├── aws.nix
│ ├── btop
│ └── default.nix
│ ├── cage.nix
│ ├── copyq.nix
│ ├── cursor.nix
│ ├── direnv.nix
│ ├── fonts.nix
│ ├── git.nix
│ ├── gnome3
│ ├── accounts.conf
│ ├── default.nix
│ └── nextcloud.source
│ ├── gpg.nix
│ ├── gtk.nix
│ ├── i3blocks
│ ├── default.nix
│ └── scripts
│ │ ├── battery.nix
│ │ ├── bluetooth.nix
│ │ ├── brightness.nix
│ │ ├── connections.nix
│ │ ├── default.nix
│ │ ├── emacs.nix
│ │ ├── email.nix
│ │ ├── free.hs
│ │ ├── free.nix
│ │ ├── hydra-status.nix
│ │ ├── music.nix
│ │ ├── network.hs
│ │ ├── sound.nix
│ │ ├── temperature.hs
│ │ ├── temperature.nix
│ │ └── weather.nix
│ ├── kanshi.nix
│ ├── kde
│ ├── kdeconnect.nix
│ ├── plasma-mobile.nix
│ └── qt.nix
│ ├── light.nix
│ ├── locale
│ ├── compose
│ └── default.nix
│ ├── mako.nix
│ ├── misc.nix
│ ├── mopidy.nix
│ ├── openvpn.nix
│ ├── print-scan
│ └── default.nix
│ ├── rclone.nix
│ ├── shadowsocks.nix
│ ├── simple-osd-daemons.nix
│ ├── ssh.nix
│ ├── sway
│ └── default.nix
│ ├── xdg.nix
│ ├── yubikey-touch-detector.nix
│ └── zsh
│ ├── default.nix
│ └── p10k.zsh
├── roles
├── base.nix
├── default.nix
├── desktop.nix
└── server.nix
└── shell.nix
/.envrc:
--------------------------------------------------------------------------------
1 | use flake
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | \#*\#
3 | auto-save-list
4 | tramp
5 | .\#*
6 | result
7 | *\.qcow2
8 | .direnv
--------------------------------------------------------------------------------
/.projectile:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balsoft/nixos-config/d3a2e32bbf74d779629803965e945fcf29d1c1ec/.projectile
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "Build",
6 | "type": "shell",
7 | "command": "nixos-rebuild",
8 | "args": [
9 | "build",
10 | "--flake",
11 | "${workspaceFolder}"
12 | ],
13 | "problemMatcher": [],
14 | "group": {
15 | "kind": "build",
16 | "isDefault": true
17 | }
18 | },
19 | {
20 | "label": "Switch",
21 | "type": "shell",
22 | "command": "nixos-rebuild",
23 | "args": [
24 | "switch",
25 | "--flake",
26 | "${workspaceFolder}",
27 | "--use-remote-sudo"
28 | ],
29 | "problemMatcher": []
30 | }
31 | ]
32 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This is free and unencumbered software released into the public domain.
2 |
3 | Anyone is free to copy, modify, publish, use, compile, sell, or
4 | distribute this software, either in source code form or as a compiled
5 | binary, for any purpose, commercial or non-commercial, and by any
6 | means.
7 |
8 | In jurisdictions that recognize copyright laws, the author or authors
9 | of this software dedicate any and all copyright interest in the
10 | software to the public domain. We make this dedication for the benefit
11 | of the public at large and to the detriment of our heirs and
12 | successors. We intend this dedication to be an overt act of
13 | relinquishment in perpetuity of all present and future rights to this
14 | software under copyright law.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | For more information, please refer to
25 |
26 | This software was originally created by Alexander Bantyev aka balsoft,
27 | but you may omit any notices of original author in your dealings with
28 | software.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # balsoft’s nixos configuration
2 |
3 | ## License
4 |
5 | Most of this config is in public domain (see [LICENSE](./LICENSE)).
6 |
7 | ## Stuff that may be useful
8 |
9 | ### Secrets
10 |
11 | Secrets are kept in a separate (private) git repository, encrypted with
12 | gpg and decrypted at runtime using [secrets.nix](./modules/secrets.nix)
13 | and [secrets-envsubst.nix](./modules/secrets-envsubst.nix). The repo is
14 | `pass(1)`-compatible, so passwords are also stored there.
15 |
16 | _pls no pwn_
17 |
18 | ### Themes
19 |
20 | Themes for everything are generated from a custom base16 theme. The theme
21 | is defined in [themes.nix](./modules/themes.nix), and the generation is spread all around
22 | [modules](./modules).
23 |
24 | ### Tmpfs root
25 |
26 | To prevent extraneous state from clinging on the drive, I am using tmpfs
27 | root on my two main devices. It is implemented in [persist.nix](./modules/persist.nix).
28 |
29 | ### Easy Wireguard setup module
30 |
31 | Copied from notgne2 with permission to redistribute as public domain software.
32 | Can be found in [ezwg.nix](./modules/ezwg.nix)
33 |
34 | ## Installing it on your machine
35 |
36 | 1. Add a config for your device to `machines` (it has to set `deviceSpecific.devInfo`, import your `hardware-configuration.nix` and one of the profiles, and contain a `system` file);
37 | 2. `sudo nixos-rebuild test --flake .`
38 |
--------------------------------------------------------------------------------
/compat/default.nix:
--------------------------------------------------------------------------------
1 | { ... }: (builtins.getFlake (toString ../.)).legacyPackages.${builtins.currentSystem}
2 |
--------------------------------------------------------------------------------
/default.nix:
--------------------------------------------------------------------------------
1 | { ... }:
2 | let
3 | self = (import (let lock = builtins.fromJSON (builtins.readFile ./flake.lock);
4 | in fetchTarball {
5 | url =
6 | "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
7 | sha256 = lock.nodes.flake-compat.locked.narHash;
8 | }) { src = ./.; }).defaultNix;
9 | in self // self.legacyPackages.${builtins.currentSystem}
10 |
--------------------------------------------------------------------------------
/flake.nix:
--------------------------------------------------------------------------------
1 | {
2 | description =
3 | "A collection of crap, hacks and copy-paste to make my localhosts boot";
4 |
5 | nixConfig.substituters = [ "https://cache.nixos.org" ];
6 |
7 | inputs = {
8 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
9 | # For NUR
10 | nixpkgs-old = {
11 | url = "github:nixos/nixpkgs/nixos-19.09";
12 | flake = false;
13 | };
14 | # For aerc
15 | nixpkgs-24-05.url = "github:nixos/nixpkgs/nixos-24.05";
16 |
17 | lambda-launcher.url = "github:balsoft/lambda-launcher";
18 | deploy-rs.url = "github:serokell/deploy-rs";
19 | flake-compat = {
20 | url = "github:edolstra/flake-compat";
21 | flake = false;
22 | };
23 | NUR = {
24 | url = "github:nix-community/NUR";
25 | flake = false;
26 | };
27 | base16-black-metal-scheme = {
28 | url = "github:metalelf0/base16-black-metal-scheme";
29 | flake = false;
30 | };
31 | home-manager.url = "github:rycee/home-manager";
32 | materia-theme = {
33 | url = "github:nana-4/materia-theme";
34 | flake = false;
35 | };
36 | simple-nixos-mailserver = {
37 | url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
38 | flake = false;
39 | };
40 | nixpkgs-wayland = {
41 | url = "github:colemickens/nixpkgs-wayland";
42 | flake = false;
43 | };
44 | nixos-fhs-compat.url = "github:balsoft/nixos-fhs-compat";
45 | simple-osd-daemons.url = "github:balsoft/simple-osd-daemons";
46 | impermanence.url = "github:nix-community/impermanence";
47 |
48 | rycee = {
49 | url = "gitlab:rycee/nur-expressions";
50 | flake = false;
51 | };
52 |
53 | nix-direnv = { url = "github:nix-community/nix-direnv"; };
54 |
55 | flake-registry = {
56 | url = "github:nixos/flake-registry";
57 | flake = false;
58 | };
59 |
60 | remapper.url = "github:balsoft/remapper";
61 |
62 | helix.url = "github:helix-editor/helix";
63 |
64 | nixos-hardware.url = "github:nixos/nixos-hardware";
65 | };
66 |
67 | outputs = { nixpkgs, self, nix, deploy-rs, ... }@inputs:
68 | let
69 | findModules = dir:
70 | builtins.concatLists (builtins.attrValues (builtins.mapAttrs
71 | (name: type:
72 | if type == "regular" then [{
73 | name = builtins.elemAt (builtins.match "(.*)\\.nix" name) 0;
74 | value = dir + "/${name}";
75 | }] else if (builtins.readDir (dir + "/${name}"))
76 | ? "default.nix" then [{
77 | inherit name;
78 | value = dir + "/${name}";
79 | }] else
80 | findModules (dir + "/${name}")) (builtins.readDir dir)));
81 | pkgsFor = system:
82 | import inputs.nixpkgs {
83 | overlays = [ self.overlay ];
84 | localSystem = { inherit system; };
85 | config = {
86 | android_sdk.accept_license = true;
87 | permittedInsecurePackages = [ "openssl-1.1.1v" "olm-3.2.16" ];
88 | allowUnfreePredicate = (pkg: pkg.pname or null == "firmware-imx");
89 | allowlistedLicenses = with inputs.nixpkgs.lib.licenses; [ epson ];
90 | };
91 | };
92 | in {
93 | nixosModules = builtins.listToAttrs (findModules ./modules);
94 |
95 | nixosProfiles = builtins.listToAttrs (findModules ./profiles);
96 |
97 | nixosRoles = import ./roles;
98 |
99 | nixosConfigurations = with nixpkgs.lib;
100 | let
101 | hosts = builtins.attrNames (builtins.readDir ./machines);
102 |
103 | mkHost = name:
104 | let
105 | system = builtins.readFile (./machines + "/${name}/system");
106 | pkgs = pkgsFor system;
107 | in nixosSystem {
108 | inherit system;
109 | modules = __attrValues self.nixosModules ++ [
110 | inputs.home-manager.nixosModules.home-manager
111 |
112 | {
113 | disabledModules =
114 | [ "services/x11/desktop-managers/plasma5.nix" ];
115 | }
116 |
117 | (import (./machines + "/${name}"))
118 | { nixpkgs.pkgs = pkgs; }
119 | { device = name; }
120 | ];
121 | specialArgs = { inherit inputs; };
122 | };
123 | in genAttrs hosts mkHost;
124 |
125 | legacyPackages.x86_64-linux = pkgsFor "x86_64-linux";
126 |
127 | defaultApp = deploy-rs.defaultApp;
128 |
129 | overlay = import ./overlay.nix inputs;
130 |
131 | lib = import ./lib.nix nixpkgs.lib;
132 |
133 | devShell.x86_64-linux = with nixpkgs.legacyPackages.x86_64-linux;
134 | mkShell {
135 | buildInputs = [
136 | nix.packages.x86_64-linux.default
137 | deploy-rs.defaultPackage.x86_64-linux
138 | nixfmt-rfc-style
139 | nil
140 | ];
141 | shellHook = ''
142 | linkFile() {
143 | source="$(nix build --print-out-paths "$1.source" || nix eval --raw "$1.source")"
144 | target="$(nix eval --raw "$1.target")"
145 | ln -fs "$source" "$HOME/$target"
146 | }
147 | linkHomeManagerFile() {
148 | linkFile ".#nixosConfigurations.$(hostname).config.home-manager.users.$(whoami).$1"
149 | }
150 | linkConfigFile() {
151 | linkHomeManagerFile "xdg.configFile.\"$1\""
152 | }
153 | linkDataFile() {
154 | linkHomeManagerFile "xdg.dataFile.\"$1\""
155 | }
156 | linkHomeFile() {
157 | linkHomeManagerFile "home.file.\"$1\""
158 | }
159 | '';
160 | };
161 |
162 | deploy = {
163 | user = "root";
164 | nodes = (builtins.mapAttrs (name: machine:
165 | let activateable = name == "T420-Laptop" || name == "RasPi-Server";
166 | in {
167 | hostname = machine.config.networking.hostName;
168 | profiles.system = {
169 | user = if activateable then "root" else "balsoft";
170 | path = with deploy-rs.lib.${machine.pkgs.system}.activate;
171 | if activateable then
172 | nixos machine
173 | else
174 | noop machine.config.system.build.toplevel;
175 | };
176 | }) self.nixosConfigurations);
177 | };
178 | };
179 | }
180 |
--------------------------------------------------------------------------------
/lib.nix:
--------------------------------------------------------------------------------
1 | lib: rec {
2 | mkKeyValue = key: value:
3 | let
4 | mvalue = if builtins.isBool value then
5 | (if value then "true" else "false")
6 | else if builtins.isString value then
7 | value
8 | else
9 | builtins.toString value;
10 | in "${key}=${mvalue}";
11 | attrsToList = with builtins;
12 | x:
13 | (map (key: {
14 | name = key;
15 | value = getAttr key x;
16 | }) (attrNames x));
17 |
18 | genIni = lib.generators.toINI { inherit mkKeyValue; };
19 | genIniOrdered = lst:
20 | (builtins.concatStringsSep "\n" (map ({ name ? "widget", ... }@attrs:
21 | builtins.concatStringsSep "\n" ([ "[${name}]" ]
22 | ++ (map ({ name, value }: mkKeyValue name value)
23 | (attrsToList (builtins.removeAttrs attrs [ "name" ]))))) lst)) + "\n";
24 | splitHex = hexStr:
25 | map (x: builtins.elemAt x 0)
26 | (builtins.filter (a: a != "" && a != [ ]) (builtins.split "(.{2})" hexStr));
27 | hex2decDigits = rec {
28 | "0" = 0;
29 | "1" = 1;
30 | "2" = 2;
31 | "3" = 3;
32 | "4" = 4;
33 | "5" = 5;
34 | "6" = 6;
35 | "7" = 7;
36 | "8" = 8;
37 | "9" = 9;
38 | "a" = 10;
39 | "b" = 11;
40 | "c" = 12;
41 | "d" = 13;
42 | "e" = 14;
43 | "f" = 15;
44 | A = a;
45 | B = b;
46 | C = c;
47 | D = d;
48 | E = e;
49 | F = f;
50 | };
51 |
52 | dec2hexDigits = lib.mapAttrs' (lib.flip lib.nameValuePair)
53 | (builtins.mapAttrs (_: toString) hex2decDigits);
54 |
55 | doubleDigitHexToDec = hex:
56 | 16 * hex2decDigits."${builtins.substring 0 1 hex}"
57 | + hex2decDigits."${builtins.substring 1 2 hex}";
58 |
59 | decToHex = n: dec2hexDigits.${toString (builtins.div n 16)} + dec2hexDigits.${toString (builtins.mod n 16)};
60 |
61 | thmDec = builtins.mapAttrs (name: color: colorHex2Dec color);
62 | thmHash = builtins.mapAttrs (name: color: "#${color}");
63 |
64 | triplet2RGB = lst: {
65 | r = builtins.elemAt lst 0;
66 | g = builtins.elemAt lst 1;
67 | b = builtins.elemAt lst 2;
68 | };
69 |
70 | hex2RGB = color: triplet2RGB (map doubleDigitHexToDec (splitHex color));
71 | dec2RGB = color: triplet2RGB (map (builtins.fromJSON) (lib.splitString "," color));
72 |
73 | RGB2hex = { r, g, b }: decToHex r + decToHex g + decToHex b;
74 | RGB2dec = { r, g, b }: lib.concatMapStringsSep "," toString [ r g b ];
75 |
76 | mulRGB = factor: builtins.mapAttrs (_: x: builtins.floor (x * factor));
77 |
78 | mulHex = factor: color: RGB2hex (mulRGB factor (hex2RGB color));
79 |
80 | mulDec = factor: color: RGB2dec (mulRGB factor (dec2RGB color));
81 |
82 | colorHex2Dec = color:
83 | builtins.concatStringsSep ","
84 | (map (x: toString (doubleDigitHexToDec x)) (splitHex color));
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/machines/AMD-Workstation/default.nix:
--------------------------------------------------------------------------------
1 | { config, inputs, pkgs, ... }: {
2 | imports = [
3 | ./hardware-configuration.nix
4 | inputs.self.nixosRoles.desktop
5 | inputs.self.nixosProfiles.print-scan
6 | inputs.self.nixosProfiles.aws
7 | ];
8 | deviceSpecific.devInfo = {
9 | cpu = {
10 | vendor = "amd";
11 | clock = 4200;
12 | cores = 8;
13 | };
14 | drive = {
15 | type = "ssd";
16 | speed = 6000;
17 | size = 250;
18 | };
19 | bigScreen = true;
20 | ram = 32;
21 | };
22 | deviceSpecific.isHost = true;
23 | boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
24 |
25 | # services.apcupsd = {
26 | # enable = true;
27 | # configText = ''
28 | # UPSTYPE usb
29 | # NISIP 127.0.0.1
30 | # BATTERYLEVEL 10
31 | # MINUTES 1
32 | # '';
33 | # };
34 |
35 | secrets.wireguard-wg0 = { };
36 |
37 | environment.sessionVariables.WINEPREFIX =
38 | "/home/balsoft/.local/share/wineprefixes/default";
39 |
40 | services.bt-agent = {
41 | enable = true;
42 | capability = "NoInputNoOutput";
43 | };
44 |
45 | secrets.restic-backup-password = { };
46 | secrets.restic-backup-environment = { };
47 |
48 | services.restic.backups.b2 = {
49 | inhibitsSleep = true;
50 | passwordFile = config.secrets.restic-backup-password.decrypted;
51 | environmentFile = config.secrets.restic-backup-environment.decrypted;
52 | paths = [
53 | "/home/balsoft/Documents" # Documents, typically not in git
54 | "/etc/NetworkManager/system-connections" # NetworkManager's wifi networks and stuff
55 | ];
56 | # Find all projects with uncommited changes
57 | dynamicFilesFrom = ''
58 | ${pkgs.git}/bin/git config set --global safe.directory '*' # Git dirs owned by another users, should be fine
59 | for gitdir in $(${pkgs.findutils}/bin/find /home/balsoft/projects -name .git -type d -prune); do
60 | dir="$(dirname "$gitdir")";
61 | if \
62 | [[ -n "$(${pkgs.git}/bin/git -C "$dir" status --untracked-files=no --porcelain)" ]] \
63 | || [[ -n "$(${pkgs.git}/bin/git -C "$dir" log --format=short --branches --not --remotes)" ]];
64 | then printf "%s\n" "$dir";
65 | fi;
66 | done;
67 | ${pkgs.git}/bin/git config unset --global safe.directory
68 | '';
69 | repository = "s3:s3.eu-central-003.backblazeb2.com/balsoft-backups";
70 | pruneOpts = [ "--keep-daily 7" "--keep-weekly 3" "--keep-monthly 3" ];
71 | # Typically I'm done writing stuff by then, save the day's work
72 | timerConfig = {
73 | OnCalendar = "22:00";
74 | Persistent = true;
75 | };
76 | };
77 |
78 | systemd.services.restic-backups-b2.wants = [
79 | "restic-backup-password-secrets.service"
80 | "restic-backup-environment-secrets.service"
81 | ];
82 | systemd.services.restic-backups-b2.requires = [
83 | "restic-backup-password-secrets.service"
84 | "restic-backup-environment-secrets.service"
85 | ];
86 |
87 | hardware.bluetooth.input.General.UserspaceHID = true;
88 |
89 | persist = {
90 | enable = true;
91 | cache.clean.enable = false; # Scary...
92 |
93 | state.directories = [ "/home/balsoft/.local/share/Steam" ];
94 |
95 | derivative.directories =
96 | [ "/home/balsoft/.local/share/wineprefixes/default" ];
97 | };
98 | }
99 |
--------------------------------------------------------------------------------
/machines/AMD-Workstation/hardware-configuration.nix:
--------------------------------------------------------------------------------
1 | # Do not modify this file! It was generated by ‘nixos-generate-config’
2 | # and may be overwritten by future invocations. Please make changes
3 | # to /etc/nixos/configuration.nix instead.
4 | { config, lib, pkgs, inputs, ... }:
5 |
6 | {
7 | imports =
8 | [ "${inputs.nixpkgs}/nixos/modules/installer/scan/not-detected.nix" ];
9 |
10 | boot.initrd.availableKernelModules =
11 | [ "nvme" "xhci_pci" "ahci" "usb_storage" "sd_mod" ];
12 | boot.kernelModules = [ "kvm-amd" ];
13 | boot.extraModulePackages = [ ];
14 | powerManagement.cpuFreqGovernor = lib.mkDefault "performance";
15 |
16 | fileSystems."/persist" = {
17 | device = "/dev/nvme0n1p2";
18 | fsType = "ext4";
19 | neededForBoot = true;
20 | };
21 |
22 | fileSystems."/persist/home" = {
23 | device = "/dev/disk/by-label/Home";
24 | fsType = "ext4";
25 | neededForBoot = true;
26 | };
27 |
28 | fileSystems."/boot" = {
29 | device = "/dev/nvme0n1p1";
30 | fsType = "vfat";
31 | };
32 |
33 | swapDevices = [ ];
34 |
35 | nix.settings.max-jobs = lib.mkDefault 32;
36 | }
37 |
--------------------------------------------------------------------------------
/machines/AMD-Workstation/system:
--------------------------------------------------------------------------------
1 | x86_64-linux
--------------------------------------------------------------------------------
/machines/Librem5-Phone/default.nix:
--------------------------------------------------------------------------------
1 | { inputs, pkgs, lib, ... }: {
2 | imports = with inputs.self;
3 | with nixosProfiles; [
4 | ./hardware-configuration.nix
5 |
6 | nixosRoles.base
7 |
8 | inputs.nixos-hardware.nixosModules.purism-librem-5r4
9 |
10 | # applications-setup
11 | bluetooth
12 | power
13 | hardware
14 | sound
15 |
16 | # plasma-mobile
17 | # phosh
18 |
19 | # nheko
20 | # okular
21 | # gwenview
22 | # aerc
23 | # helix
24 | # angelfish
25 | nix
26 | # qmlkonsole
27 |
28 | # kdeconnect
29 | # cursor
30 | # fonts
31 | # gtk
32 | # qt
33 | # shadowsocks
34 |
35 | pass-secret-service
36 | ];
37 |
38 | hardware.librem5.audio = false;
39 |
40 | programs.ssh.askPassword =
41 | "${pkgs.plasma5Packages.ksshaskpass.out}/bin/ksshaskpass";
42 |
43 | users.users.balsoft.password = lib.mkForce "0";
44 |
45 | system.stateVersion = "23.05";
46 | home-manager.users.balsoft.home.stateVersion = "22.11";
47 |
48 | themes.fonts = {
49 | main.size = 10;
50 | serif.size = 10;
51 | mono.size = 11;
52 | };
53 |
54 | environment.systemPackages = [ pkgs.pure-maps (pkgs.organicmaps.overrideAttrs (_: {meta = {};})) pkgs.plasma5Packages.elisa ];
55 |
56 | environment.etc."gnss-share.conf".text = ''
57 | # Socket to sent NMEA location to
58 | socket="/var/run/gnss-share.sock"
59 | # Group to set as owner for the socket
60 | group="geoclue"
61 |
62 | # GPS device driver to use
63 | # Supported values: stm, stm_serial
64 | device_driver="stm"
65 |
66 | # Path to GPS device to use
67 | device_path="/dev/gnss0"
68 |
69 | # Baud rate for GPS serial device
70 | device_baud_rate=9600
71 |
72 | # Directory to load/store almanac and ephemeris data
73 | agps_directory="/var/cache/gnss-share"
74 | '';
75 |
76 | systemd.services.gnss-share = {
77 | script = "gnss-share";
78 | description = "GNSS location manager";
79 | path = [ pkgs.gnss-share ];
80 | wantedBy = [ "multi-user.target" ];
81 | before = [ "geoclue.service" ];
82 | };
83 |
84 | environment.etc."geoclue/geoclue.conf".text = lib.mkForce
85 | (lib.generators.toINI { } {
86 | network-nmea = {
87 | enable = true;
88 | nmea-socket = "/var/run/gnss-share.sock";
89 | };
90 | modem-gps.enable = true;
91 | cdma.enable = true;
92 | "3g".enable = true;
93 | agent.whitelist = "geoclue-demo-agent";
94 | wifi = {
95 | enable = true;
96 | url = "https://location.services.mozilla.com/v1/geolocate?key=geoclue";
97 | };
98 | });
99 |
100 | home-manager.users.balsoft.programs.git.signing.signByDefault =
101 | lib.mkForce false;
102 | }
103 |
--------------------------------------------------------------------------------
/machines/Librem5-Phone/hardware-configuration.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, modulesPath, ... }:
2 |
3 | {
4 | imports =
5 | [ (modulesPath + "/installer/scan/not-detected.nix")
6 | ];
7 |
8 |
9 | fileSystems."/" = {
10 | device = "/dev/mmcblk0p2";
11 | fsType = "ext4";
12 | };
13 |
14 | fileSystems."/boot" = {
15 | device = "/dev/mmcblk0p1";
16 | fsType = "ext2";
17 | };
18 |
19 | swapDevices = [ ];
20 |
21 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
22 | # (the default) this is the recommended approach. When using systemd-networkd it's
23 | # still possible to use this option, but it's recommended to use it in conjunction
24 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`.
25 | networking.useDHCP = lib.mkDefault true;
26 | # networking.interfaces.wlan0.useDHCP = lib.mkDefault true;
27 |
28 | nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
29 | powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
30 |
31 | nix.settings.max-jobs = 4;
32 | }
33 |
--------------------------------------------------------------------------------
/machines/Librem5-Phone/system:
--------------------------------------------------------------------------------
1 | aarch64-linux
--------------------------------------------------------------------------------
/machines/RasPi-Server/default.nix:
--------------------------------------------------------------------------------
1 | { inputs, pkgs, lib, ... }: {
2 | imports = with inputs.self.nixosModules; with inputs.self.nixosProfiles; [
3 | ./hardware-configuration.nix
4 | inputs.self.nixosRoles.server
5 | themes
6 | fonts
7 | cage
8 | gtk
9 | alacritty
10 | ];
11 |
12 | boot.loader.raspberryPi = {
13 | enable = true;
14 | version = 3;
15 | };
16 |
17 | nix.package = lib.mkForce pkgs.nixUnstable;
18 |
19 | deviceSpecific.devInfo = {
20 | cpu = {
21 | vendor = "broadcom";
22 | clock = 4200;
23 | cores = 8;
24 | };
25 | drive = {
26 | type = "ssd";
27 | speed = 6000;
28 | size = 250;
29 | };
30 | bigScreen = true;
31 | ram = 32;
32 | };
33 | }
34 |
--------------------------------------------------------------------------------
/machines/RasPi-Server/hardware-configuration.nix:
--------------------------------------------------------------------------------
1 | # Do not modify this file! It was generated by ‘nixos-generate-config’
2 | # and may be overwritten by future invocations. Please make changes
3 | # to /etc/nixos/configuration.nix instead.
4 | { config, lib, pkgs, modulesPath, ... }:
5 |
6 | {
7 | imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
8 |
9 | boot.initrd.availableKernelModules = [ ];
10 | boot.initrd.kernelModules = [ ];
11 | boot.kernelModules = [ ];
12 | boot.extraModulePackages = [ ];
13 |
14 | fileSystems."/" = {
15 | device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888";
16 | fsType = "ext4";
17 | };
18 |
19 | swapDevices = [ ];
20 |
21 | powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
22 | # high-resolution display
23 | hardware.video.hidpi.enable = lib.mkDefault true;
24 | }
25 |
--------------------------------------------------------------------------------
/machines/RasPi-Server/system:
--------------------------------------------------------------------------------
1 | aarch64-linux
--------------------------------------------------------------------------------
/machines/T420-Laptop/default.nix:
--------------------------------------------------------------------------------
1 | { inputs, lib, ... }: {
2 | imports = with inputs.self.nixosModules; with inputs.self.nixosProfiles; [
3 | ./hardware-configuration.nix
4 | inputs.self.nixosRoles.server
5 | gitea
6 | # jitsi
7 | mailserver
8 | matrix-synapse
9 | # minidlna
10 | nextcloud
11 | nginx
12 | vsftpd
13 | # home-assistant
14 | # mastodon
15 | irc
16 | remapper
17 | ntfy
18 | ];
19 |
20 | services.logind.lidSwitch = "ignore";
21 |
22 | system.stateVersion = "21.11";
23 |
24 | boot.loader = {
25 | systemd-boot.enable = lib.mkForce false;
26 | grub = {
27 | enable = lib.mkForce true;
28 | device = "/dev/disk/by-path/pci-0000:06:00.0-scsi-0:0:0:0";
29 | };
30 | };
31 |
32 | deviceSpecific.devInfo = {
33 | legacy = true;
34 | cpu = {
35 | vendor = "intel";
36 | clock = 2500;
37 | cores = 2;
38 | };
39 | drive = {
40 | type = "ssd";
41 | speed = 1000;
42 | size = 120;
43 | };
44 | ram = 8;
45 | };
46 | }
47 |
--------------------------------------------------------------------------------
/machines/T420-Laptop/hardware-configuration.nix:
--------------------------------------------------------------------------------
1 | # Do not modify this file! It was generated by ‘nixos-generate-config’
2 | # and may be overwritten by future invocations. Please make changes
3 | # to /etc/nixos/configuration.nix instead.
4 | { config, lib, pkgs, modulesPath, ... }:
5 |
6 | {
7 | imports =
8 | [ (modulesPath + "/profiles/qemu-guest.nix")
9 | ];
10 |
11 | boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sd_mod" "sr_mod" ];
12 | boot.initrd.kernelModules = [ ];
13 | boot.kernelModules = [ ];
14 | boot.extraModulePackages = [ ];
15 |
16 | fileSystems."/" =
17 | { device = "/dev/disk/by-uuid/1364826d-5333-4ec9-93cf-aba2925e41d0";
18 | fsType = "ext4";
19 | };
20 |
21 | fileSystems."/var/lib" =
22 | { device = "/dev/disk/by-uuid/e4122adb-3f73-44b5-8763-7fb91e9a52e7";
23 | fsType = "ext4";
24 | };
25 |
26 | swapDevices = [ ];
27 |
28 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
29 | # (the default) this is the recommended approach. When using systemd-networkd it's
30 | # still possible to use this option, but it's recommended to use it in conjunction
31 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`.
32 | networking.useDHCP = lib.mkDefault true;
33 | # networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
34 |
35 | # nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
36 | nix.settings.max-jobs = 4;
37 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
38 | }
39 |
--------------------------------------------------------------------------------
/machines/T420-Laptop/system:
--------------------------------------------------------------------------------
1 | x86_64-linux
--------------------------------------------------------------------------------
/machines/T490s-Laptop/default.nix:
--------------------------------------------------------------------------------
1 | { inputs, ... }: {
2 | imports = [ ./hardware-configuration.nix inputs.self.nixosRoles.desktop inputs.self.nixosProfiles.print-scan ];
3 | deviceSpecific.devInfo = {
4 | cpu = {
5 | vendor = "intel";
6 | clock = 4600;
7 | cores = 4;
8 | };
9 | drive = {
10 | type = "ssd";
11 | speed = 2000;
12 | size = 250;
13 | };
14 | ram = 16;
15 | };
16 |
17 | persist = {
18 | enable = true;
19 | cache.clean.enable = true;
20 | };
21 |
22 | home-manager.users.balsoft.wayland.windowManager.sway.config.input."*".natural_scroll = "enable";
23 |
24 | services.throttled = {
25 | enable = true;
26 | extraConfig = ''
27 | [GENERAL]
28 | # Enable or disable the script execution
29 | Enabled: True
30 | # SYSFS path for checking if the system is running on AC power
31 | Sysfs_Power_Path: /sys/class/power_supply/AC*/online
32 |
33 | ## Settings to apply while connected to Battery power
34 | [BATTERY]
35 | # Update the registers every this many seconds
36 | Update_Rate_s: 30
37 | # Max package power for time window #1
38 | PL1_Tdp_W: 29
39 | # Time window #1 duration
40 | PL1_Duration_s: 28
41 | # Max package power for time window #2
42 | PL2_Tdp_W: 44
43 | # Time window #2 duration
44 | PL2_Duration_S: 0.002
45 | # Max allowed temperature before throttling
46 | Trip_Temp_C: 85
47 | # Set cTDP to normal=0, down=1 or up=2 (EXPERIMENTAL)
48 | cTDP: 1
49 |
50 | ## Settings to apply while connected to AC power
51 | [AC]
52 | # Update the registers every this many seconds
53 | Update_Rate_s: 5
54 | # Max package power for time window #1
55 | PL1_Tdp_W: 44
56 | # Time window #1 duration
57 | PL1_Duration_s: 28
58 | # Max package power for time window #2
59 | PL2_Tdp_W: 44
60 | # Time window #2 duration
61 | PL2_Duration_S: 0.002
62 | # Max allowed temperature before throttling
63 | Trip_Temp_C: 95
64 | # Set HWP energy performance hints to 'performance' on high load (EXPERIMENTAL)
65 | HWP_Mode: True
66 | # Set cTDP to normal=0, down=1 or up=2 (EXPERIMENTAL)
67 | cTDP: 2
68 |
69 | [UNDERVOLT]
70 | # CPU core voltage offset (mV)
71 | CORE: -200
72 | # Integrated GPU voltage offset (mV)
73 | GPU: -60
74 | # CPU cache voltage offset (mV)
75 | CACHE: -50
76 | # System Agent voltage offset (mV)
77 | UNCORE: 0
78 | # Analog I/O voltage offset (mV)
79 | ANALOGIO: 0
80 | '';
81 | };
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/machines/T490s-Laptop/hardware-configuration.nix:
--------------------------------------------------------------------------------
1 | # Do not modify this file! It was generated by ‘nixos-generate-config’
2 | # and may be overwritten by future invocations. Please make changes
3 | # to /etc/nixos/configuration.nix instead.
4 | { config, lib, pkgs, inputs, ... }:
5 |
6 | {
7 | imports =
8 | [ "${inputs.nixpkgs}/nixos/modules/installer/scan/not-detected.nix" ];
9 |
10 | boot.initrd.availableKernelModules =
11 | [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
12 | boot.initrd.kernelModules = [ ];
13 | boot.kernelModules = [ "kvm-intel" ];
14 | boot.extraModulePackages = [ ];
15 |
16 | fileSystems."/persist" = {
17 | device = "/dev/disk/by-uuid/7c16955c-8414-4971-bf37-6492e8c0cb61";
18 | fsType = "ext4";
19 | neededForBoot = true;
20 | };
21 |
22 | boot.initrd.luks.devices."root".device =
23 | "/dev/disk/by-uuid/234de44d-b2d4-44d0-a4e3-b3ef6b159424";
24 |
25 | fileSystems."/boot" = {
26 | device = "/dev/disk/by-uuid/66D2-DC8B";
27 | fsType = "vfat";
28 | };
29 |
30 | swapDevices = [ ];
31 |
32 | nix.settings.max-jobs = lib.mkDefault 8;
33 | powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
34 | }
35 |
--------------------------------------------------------------------------------
/machines/T490s-Laptop/system:
--------------------------------------------------------------------------------
1 | x86_64-linux
--------------------------------------------------------------------------------
/machines/X2100-Laptop/default.nix:
--------------------------------------------------------------------------------
1 | {
2 | inputs,
3 | lib,
4 | config,
5 | pkgs,
6 | ...
7 | }:
8 | {
9 | imports = [
10 | ./hardware-configuration.nix
11 | inputs.self.nixosRoles.desktop
12 | ];
13 | deviceSpecific.devInfo = {
14 | cpu = {
15 | vendor = "intel";
16 | clock = 4800;
17 | cores = 4;
18 | };
19 | drive = {
20 | type = "ssd";
21 | speed = 6000;
22 | size = 256;
23 | };
24 | ram = 16;
25 | };
26 |
27 | fileSystems."/persist" = {
28 | device = "/dev/disk/by-uuid/e50bd1d6-3613-465e-895a-9dde6ffaad46";
29 | fsType = "ext4";
30 | neededForBoot = true;
31 | };
32 | fileSystems."/boot" = {
33 | device = "/dev/disk/by-uuid/621A-6414";
34 | fsType = "vfat";
35 | };
36 |
37 | boot.resumeDevice = config.fileSystems."/persist".device;
38 | boot.kernelParams = [ "resume_offset=4294656" ]; # from sudo filefrag -v /persist/swapfile
39 | services.logind.lidSwitch = "hibernate";
40 | services.logind.powerKey = "hibernate";
41 |
42 | # boot.initrd.systemd.enable = true;
43 |
44 | swapDevices = [
45 | {
46 | device = "/persist/swapfile";
47 | size = 16 * 1024; # 16 GB
48 | }
49 | ];
50 |
51 | persist = {
52 | enable = true;
53 | cache.clean.enable = true;
54 | };
55 |
56 | nix.settings.max-jobs = lib.mkDefault 8;
57 |
58 | home-manager.users.balsoft.xdg.configFile."simple-osd/brightness".text = pkgs.my-lib.genIni {
59 | default = {
60 | "backlight backend" = "/sys/class/backlight/acpi_video0";
61 | "refresh interval" = 1000;
62 | };
63 | };
64 | }
65 |
--------------------------------------------------------------------------------
/machines/X2100-Laptop/hardware-configuration.nix:
--------------------------------------------------------------------------------
1 | # Do not modify this file! It was generated by ‘nixos-generate-config’
2 | # and may be overwritten by future invocations. Please make changes
3 | # to /etc/nixos/configuration.nix instead.
4 | { config, lib, pkgs, modulesPath, ... }:
5 |
6 | {
7 | imports =
8 | [ (modulesPath + "/installer/scan/not-detected.nix")
9 | ];
10 |
11 | boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" ];
12 | boot.initrd.kernelModules = [ ];
13 | boot.kernelModules = [ "kvm-intel" ];
14 | boot.extraModulePackages = [ ];
15 |
16 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
17 | # (the default) this is the recommended approach. When using systemd-networkd it's
18 | # still possible to use this option, but it's recommended to use it in conjunction
19 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`.
20 | networking.useDHCP = lib.mkDefault true;
21 | # networking.interfaces.eth0.useDHCP = lib.mkDefault true;
22 | # networking.interfaces.wlan0.useDHCP = lib.mkDefault true;
23 |
24 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
25 | hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
26 | }
27 |
--------------------------------------------------------------------------------
/machines/X2100-Laptop/system:
--------------------------------------------------------------------------------
1 | x86_64-linux
--------------------------------------------------------------------------------
/machines/iso-image/default.nix:
--------------------------------------------------------------------------------
1 | { modulesPath, lib, inputs, pkgs, ... }: {
2 | imports = with inputs.self.nixosModules; with inputs.self.nixosProfiles; [
3 | "${modulesPath}/installer/cd-dvd/iso-image.nix"
4 | inputs.self.nixosRoles.base
5 | themes
6 | fonts
7 | cage
8 | gtk
9 | alacritty
10 | ];
11 | nix.settings.max-jobs = 4;
12 | isoImage.makeEfiBootable = true;
13 | isoImage.makeUsbBootable = true;
14 | }
15 |
--------------------------------------------------------------------------------
/machines/iso-image/system:
--------------------------------------------------------------------------------
1 | x86_64-linux
--------------------------------------------------------------------------------
/machines/server/default.nix:
--------------------------------------------------------------------------------
1 | { inputs, lib, ... }: {
2 | imports = with inputs.self.nixosModules; with inputs.self.nixosProfiles; [
3 | inputs.self.nixosRoles.base
4 | ];
5 |
6 | nix.nrBuildUsers = lib.mkForce 16;
7 |
8 | deviceSpecific.devInfo = {
9 | legacy = true;
10 | cpu = {
11 | vendor = "intel";
12 | clock = 2500;
13 | cores = 2;
14 | };
15 | drive = {
16 | type = "ssd";
17 | speed = 1000;
18 | size = 120;
19 | };
20 | ram = 8;
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/machines/server/system:
--------------------------------------------------------------------------------
1 | x86_64-linux
--------------------------------------------------------------------------------
/machines/usb-persist/default.nix:
--------------------------------------------------------------------------------
1 | { lib, inputs, pkgs, config, ... }: {
2 | imports = with inputs.self.nixosModules; with inputs.self.nixosProfiles; [
3 | ./hardware-configuration.nix
4 |
5 | inputs.self.nixosRoles.base
6 |
7 | themes
8 | fonts
9 | gtk
10 |
11 | sway
12 | i3blocks
13 | himalaya
14 | bluetooth
15 | power
16 |
17 | simple-osd-daemons
18 | alacritty
19 | firefox
20 | emacs
21 | ];
22 |
23 | deviceSpecific.devInfo = {
24 | cpu = {
25 | vendor = "intel";
26 | clock = 2000;
27 | cores = 2;
28 | };
29 | drive = {
30 | type = "ssd";
31 | speed = 6000;
32 | size = 16;
33 | };
34 | bigScreen = false;
35 | ram = 2;
36 | };
37 |
38 | networking.wireless.enable = lib.mkForce false;
39 | services.openssh.permitRootLogin = lib.mkForce "no";
40 | services.getty.autologinUser = lib.mkForce "balsoft";
41 | boot.kernelPackages = lib.mkForce pkgs.linuxPackages_latest;
42 | boot.supportedFilesystems = lib.mkForce [ "ext4" "vfat" ];
43 | boot.loader.systemd-boot.enable = lib.mkForce false;
44 | boot.loader.grub = {
45 | enable = lib.mkForce true;
46 | devices = [ "/dev/sdc" ];
47 | };
48 | security.sudo.wheelNeedsPassword = false;
49 | persist = {
50 | enable = true;
51 | };
52 |
53 | defaultApplications = {
54 | monitor.cmd = "${pkgs.alacritty}/bin/alacritty -e top";
55 | };
56 |
57 | startupApplications = [ config.defaultApplications.browser.cmd ];
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/machines/usb-persist/hardware-configuration.nix:
--------------------------------------------------------------------------------
1 | # Do not modify this file! It was generated by ‘nixos-generate-config’
2 | # and may be overwritten by future invocations. Please make changes
3 | # to /etc/nixos/configuration.nix instead.
4 | { config, lib, pkgs, modulesPath, ... }:
5 |
6 | {
7 | imports =
8 | [ (modulesPath + "/installer/scan/not-detected.nix")
9 | ];
10 |
11 | boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
12 | boot.initrd.kernelModules = [ ];
13 | boot.kernelModules = [ "kvm-amd" ];
14 | boot.extraModulePackages = [ ];
15 |
16 | fileSystems."/persist" =
17 | { device = "/dev/disk/by-uuid/315c1e94-7395-4a7e-ada8-40e3409f1a2b";
18 | fsType = "ext4";
19 | neededForBoot = true;
20 | };
21 |
22 | fileSystems."/boot" =
23 | { device = "/dev/disk/by-uuid/08B0-2766";
24 | fsType = "vfat";
25 | };
26 |
27 | swapDevices = [ ];
28 |
29 | # high-resolution display
30 | hardware.video.hidpi.enable = lib.mkDefault false;
31 | }
32 |
--------------------------------------------------------------------------------
/machines/usb-persist/system:
--------------------------------------------------------------------------------
1 | x86_64-linux
--------------------------------------------------------------------------------
/modules/applications.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, ... }: {
2 | options = with lib;
3 | with types; {
4 | defaultApplications = mkOption {
5 | type = attrsOf (submodule ({ name, ... }: {
6 | options = {
7 | cmd = mkOption { type = path; };
8 | desktop = mkOption { type = str; };
9 | };
10 | }));
11 | description = "Preferred applications";
12 | };
13 |
14 | startupApplications = mkOption {
15 | type = listOf path;
16 | description = "Applications to run on startup";
17 | };
18 | };
19 | config = rec {
20 | defaultApplications = {
21 | text_processor = {
22 | cmd = "${pkgs.abiword}/bin/abiword";
23 | desktop = "abiword";
24 | };
25 | spreadsheet = {
26 | cmd = "${pkgs.gnumeric}/bin/gnumeric";
27 | desktop = "gnumeric";
28 | };
29 | };
30 | };
31 | }
32 |
--------------------------------------------------------------------------------
/modules/bt-agent.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | options.services.bt-agent = with lib; {
3 | enable = mkEnableOption "Bluetooth authentication agent";
4 | package = mkOption {
5 | default = pkgs.bluez-tools;
6 | type = types.package;
7 | };
8 | capability = mkOption {
9 | default = "DisplayYesNo";
10 | description = "Agent capability";
11 | type = types.enum [
12 | "DisplayOnly"
13 | "DisplayYesNo"
14 | "KeyboardOnly"
15 | "NoInputNoOutput"
16 | ];
17 | };
18 | pinFile = mkOption {
19 | default = null;
20 | type = types.nullOr types.path;
21 | description = "Path to the PIN's file";
22 | };
23 | };
24 | config = let
25 | cfg = config.services.bt-agent;
26 | args = [ "--capability=${cfg.capability}" ]
27 | ++ lib.optional (!isNull cfg.pinFile) "--pin=${cfg.pinFile}";
28 | in lib.mkIf cfg.enable {
29 | systemd.services.bt-agent = {
30 | path = [ cfg.package ];
31 | serviceConfig.Type = "forking";
32 | serviceConfig.KillSignal = "SIGKILL";
33 | script = "bt-agent -d ${lib.escapeShellArgs args}";
34 | wantedBy = [ "bluetooth.target" ];
35 | after = [ "bluetooth.service" ];
36 | };
37 | };
38 | }
39 |
--------------------------------------------------------------------------------
/modules/devices.nix:
--------------------------------------------------------------------------------
1 | { pkgs, lib, config, ... }:
2 | with lib;
3 | with types; {
4 | options = {
5 | device = mkOption { type = str; };
6 | deviceSpecific = {
7 | isLaptop = mkOption {
8 | type = bool;
9 | default =
10 | !isNull (builtins.match ".*Laptop" config.networking.hostName);
11 | };
12 | isPhone = mkOption {
13 | type = bool;
14 | default = !isNull (builtins.match ".*Phone" config.networking.hostName);
15 | };
16 | devInfo = {
17 | cpu = {
18 | arch = mkOption { type = enum [ "x86_64" "aarch64" ]; };
19 | vendor = mkOption { type = enum [ "amd" "intel" "broadcom" ]; };
20 | clock = mkOption { type = int; };
21 | cores = mkOption { type = int; };
22 | };
23 | drive = {
24 | type = mkOption { type = enum [ "hdd" "ssd" ]; };
25 | speed = mkOption { type = int; };
26 | size = mkOption { type = int; };
27 | };
28 | ram = mkOption { type = int; };
29 | legacy = mkOption { type = bool; default = false; };
30 | bigScreen = mkOption {
31 | type = bool;
32 | default = true;
33 | };
34 | };
35 | # Whether machine is powerful enough for heavy stuff
36 | goodMachine = with config.deviceSpecific;
37 | mkOption {
38 | type = bool;
39 | default = devInfo.cpu.clock * devInfo.cpu.cores >= 4000
40 | && devInfo.drive.size >= 100 && devInfo.ram >= 8;
41 | };
42 | isHost = mkOption {
43 | type = bool;
44 | default = false;
45 | };
46 | bigScreen = mkOption {
47 | type = bool;
48 | default = config.deviceSpecific.devInfo ? bigScreen;
49 | };
50 | };
51 | };
52 | }
53 |
--------------------------------------------------------------------------------
/modules/ezwg.nix:
--------------------------------------------------------------------------------
1 | # Kudos to https://github.com/notgne2
2 |
3 | { config, lib, pkgs, ... }:
4 | with lib;
5 | let cfg = config.services.ezwg;
6 | in {
7 | options.services.ezwg = {
8 | enable = mkEnableOption "Enable simple Wireguard connection";
9 | proxy = mkOption {
10 | type = types.bool;
11 | default = true;
12 | description = "Route all your traffic through this connection";
13 | };
14 | lanSize = mkOption {
15 | type = types.int;
16 | default = 24;
17 | description = "Size of your VLAN (only relevant if proxy is false)";
18 | };
19 | serverIP = mkOption {
20 | type = types.str;
21 | description = "The IP of the wg server";
22 | };
23 | serverPort = mkOption {
24 | type = types.int;
25 | default = 51820;
26 | description = "The port of the wg server";
27 | };
28 | serverKey = mkOption {
29 | type = types.str;
30 | description = "The public key of the wg server";
31 | };
32 | privateKeyFile = mkOption {
33 | type = types.str;
34 | description = "Private wg key";
35 | };
36 | vlanIP = mkOption {
37 | type = types.str;
38 | description = "The IP to use on the wg VLAN";
39 | };
40 | };
41 | config = mkIf cfg.enable {
42 | networking.firewall.checkReversePath = false;
43 | systemd.services.wireguard-wg0.wantedBy = lib.mkForce [ ];
44 | systemd.paths.wireguard-wg0.wantedBy = lib.mkForce [ ];
45 | systemd.services."wireguard-wg0-peer-${
46 | lib.replaceChars [ "/" "-" " " "+" "=" ] [
47 | "-"
48 | "\\x2d"
49 | "\\x20"
50 | "\\x2b"
51 | "\\x3d"
52 | ] cfg.serverKey
53 | }".wantedBy = lib.mkForce [ ];
54 |
55 | networking.wireguard.interfaces.wg0 = let
56 | generateRangesScript =
57 | builtins.toFile "exclusionary-wildcard-ranges-generator.py" ''
58 | import ipaddress
59 | n1 = ipaddress.ip_network('0.0.0.0/0')
60 | n2 = ipaddress.ip_network('${cfg.serverIP}/32')
61 | print(':'.join(list(map(lambda x: str(x), list(n1.address_exclude(n2))))), end="")
62 | '';
63 | rangesOutput = pkgs.runCommandNoCC "exclusionary-wildcard-ranges" { } ''
64 | ${pkgs.python3}/bin/python3 ${generateRangesScript} > $out
65 | '';
66 | generateSubnetScript =
67 | builtins.toFile "subnet-without-host-bits-generator.py" ''
68 | import ipaddress
69 | n1 = ipaddress.ip_network('${cfg.vlanIP}/${
70 | toString cfg.lanSize
71 | }', False)
72 | print(n1, end="")
73 | '';
74 | subnetOutput = pkgs.runCommandNoCC "subnet-without-host-bits" { } ''
75 | ${pkgs.python3}/bin/python3 ${generateSubnetScript} > $out
76 | '';
77 | ranges = lib.splitString ":" (builtins.readFile "${rangesOutput}");
78 | subnet = builtins.readFile "${subnetOutput}";
79 | in {
80 | ips = [ "${cfg.vlanIP}/${toString cfg.lanSize}" ];
81 | privateKeyFile = cfg.privateKeyFile;
82 | peers = [{
83 | publicKey = cfg.serverKey;
84 | allowedIPs = if cfg.proxy then ranges else [ subnet ];
85 | endpoint = "${cfg.serverIP}:${toString cfg.serverPort}";
86 | persistentKeepalive = 25;
87 | }];
88 | };
89 | };
90 | }
91 |
--------------------------------------------------------------------------------
/modules/persist.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, inputs, ... }:
2 | let
3 | cfg = config.persist;
4 |
5 | takeAll = what: concatMap (x: x.${what});
6 |
7 | persists = with cfg; [ state derivative cache ];
8 |
9 | absoluteHomeFiles = map (x: "${cfg.homeDir}/${x}");
10 |
11 | allHomeFiles = takeAll "homeFiles" persists;
12 |
13 | absoluteEtcFiles = map (x: "/etc/${x}");
14 |
15 | allEtcFiles = absoluteEtcFiles (takeAll "etcFiles" persists);
16 |
17 | allDirectories = takeAll "directories" persists;
18 |
19 | inherit (builtins) concatMap;
20 | inherit (lib) mkIf;
21 |
22 | in {
23 | options = let
24 | inherit (lib) mkOption mkEnableOption;
25 | inherit (lib.types) listOf path str;
26 | common = {
27 | directories = mkOption {
28 | type = listOf path;
29 | default = [ ];
30 | };
31 | etcFiles = mkOption {
32 | type = listOf str;
33 | default = [ ];
34 | };
35 | homeFiles = mkOption {
36 | type = listOf str;
37 | default = [ ];
38 | };
39 | };
40 | in {
41 | persist = {
42 |
43 | enable = mkEnableOption "a tmpfs root with explicit opt-in state";
44 |
45 | persistRoot = mkOption {
46 | type = path;
47 | default = "/persist";
48 | };
49 |
50 | homeDir = mkOption {
51 | type = path;
52 | default = "/home/balsoft";
53 | };
54 |
55 | # Stuff that matters
56 | # TODO backups of this stuff
57 | state = {
58 | # backup = {...};
59 | } // common;
60 |
61 | # Stuff that can be computed from declarative+state, but is never invalidated (so shouldn't be cleaned up)
62 | derivative = common;
63 |
64 | # Stuff that's just there to speed up the system
65 | # It's cleaned up regularly, to solve the cache invalidation problem once and for all
66 | cache = {
67 | clean = {
68 | enable = mkEnableOption "cleaning the cache files and directories";
69 | dates = mkOption {
70 | type = str;
71 | default = "weekly";
72 | description =
73 | "A systemd.time calendar description of when to clean the cache files";
74 | };
75 | };
76 | } // common;
77 |
78 | };
79 | };
80 |
81 | imports = [
82 | inputs.impermanence.nixosModules.impermanence
83 | # Eugh
84 | (let
85 | module = (import "${inputs.impermanence}/home-manager.nix" {
86 | inherit pkgs lib;
87 | config = lib.recursiveUpdate config.home-manager.users.balsoft {
88 | home.persistence."${cfg.persistRoot}${cfg.homeDir}" = {
89 | enable = true;
90 | directories = [ ];
91 | files = allHomeFiles;
92 | allowOther = false;
93 | removePrefixDirectory = false;
94 | };
95 | };
96 | });
97 | in {
98 | config.home-manager.users.balsoft = lib.mkIf cfg.enable module.config;
99 | })
100 | ];
101 |
102 | config = mkIf cfg.enable {
103 | environment.persistence.${cfg.persistRoot} = {
104 | directories = allDirectories;
105 | files = allEtcFiles;
106 | };
107 |
108 | fileSystems."/" = {
109 | device = "none";
110 | options = [ "defaults" "size=4G" "mode=755" ];
111 | fsType = "tmpfs";
112 | };
113 |
114 | boot.initrd.postMountCommands = assert config.fileSystems
115 | ? ${cfg.persistRoot}
116 | && config.fileSystems.${cfg.persistRoot}.neededForBoot; ''
117 | mkdir -p /mnt-root/nix
118 | mount --bind /mnt-root${cfg.persistRoot}/nix /mnt-root/nix
119 | chmod 755 /mnt-root
120 | '';
121 |
122 | # Euuuugh
123 | systemd.services.persist-cache-cleanup = lib.mkIf cfg.cache.clean.enable {
124 | description = "Cleaning up cache files and directories";
125 | script = ''
126 | ${builtins.concatStringsSep "\n" (map (x: "rm ${lib.escapeShellArg x}")
127 | (absoluteEtcFiles cfg.cache.etcFiles
128 | ++ absoluteHomeFiles cfg.cache.homeFiles))}
129 |
130 | ${builtins.concatStringsSep "\n"
131 | (map (x: "rm -rf ${lib.escapeShellArg x}") cfg.cache.directories)}
132 | '';
133 | startAt = cfg.cache.clean.dates;
134 | };
135 |
136 | system.activationScripts = {
137 | homedir.text = builtins.concatStringsSep "\n" (map (dir: ''
138 | mkdir -p ${cfg.persistRoot}${dir}
139 | chown balsoft:users ${cfg.persistRoot}${dir}
140 | '') (builtins.filter (lib.hasPrefix "/home/balsoft") allDirectories));
141 | };
142 | };
143 | }
144 |
--------------------------------------------------------------------------------
/modules/secrets-envsubst.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, inputs, ... }:
2 | with lib;
3 | with types;
4 | let
5 | envsubstSecrets = { name, ... }: {
6 | options = {
7 | directory = mkOption {
8 | type = nullOr str;
9 | default = name;
10 | };
11 | secrets = mkOption { type = listOf str; };
12 | template = mkOption { type = str; };
13 | prefix = mkOption {
14 | type = nullOr str;
15 | default = null;
16 | };
17 | substituted = mkOption {
18 | type = path;
19 | default = "/var/secrets/${name}-envsubst";
20 | };
21 | envsubst = mkOption {
22 | type = str;
23 | default = "${pkgs.envsubst}/bin/envsubst -no-unset -no-empty";
24 | };
25 | owner = mkOption {
26 | type = str;
27 | default = "root:root";
28 | };
29 | permissions = mkOption {
30 | type = lib.types.addCheck lib.types.str
31 | (perm: !isNull (builtins.match "[0-7]{3}" perm));
32 | default = "400";
33 | };
34 | services = mkOption {
35 | type = listOf str;
36 | default = [ "${name}.service" ];
37 | };
38 | __toString = mkOption {
39 | readOnly = true;
40 | default = s: s.substituted;
41 | };
42 | };
43 | };
44 |
45 | exportSecrets = name: cfg:
46 | let prefix = lib.optionalString (!isNull cfg.prefix) "${cfg.prefix}_";
47 | in map (secret:
48 | ''
49 | export ${prefix}${secret}="$(cat ${
50 | config.secrets."${name}-envsubst-${secret}".decrypted
51 | })"'') cfg.secrets;
52 |
53 | envsubst = name: cfg:
54 | with cfg; {
55 | "${name}-envsubst" = rec {
56 |
57 | requires = [ "user@1000.service" ]
58 | ++ map (secret: "${name}-envsubst-${secret}-secrets.service")
59 | cfg.secrets;
60 | after = requires;
61 | bindsTo = requires;
62 |
63 | preStart = "mkdir -p '${builtins.dirOf substituted}'";
64 |
65 | script = ''
66 | ${builtins.concatStringsSep "\n" (exportSecrets name cfg)}
67 |
68 | if cat '${
69 | builtins.toFile "template" template
70 | }' | ${cfg.envsubst} > '${substituted}.tmp'; then
71 | mv -f '${substituted}.tmp' '${substituted}'
72 | chown '${owner}' '${substituted}'
73 | chmod '${permissions}' '${substituted}'
74 | else
75 | echo "Failed to run the substition"
76 | rm '${substituted}.tmp'
77 | exit 1
78 | fi
79 | '';
80 |
81 | serviceConfig = {
82 | Type = "oneshot";
83 | RemainAfterExit = "yes";
84 | };
85 | };
86 | };
87 |
88 | addDependencies = name: cfg:
89 | with cfg;
90 | genAttrs services (service: rec {
91 | requires = [ "${name}-envsubst.service" ];
92 | after = requires;
93 | bindsTo = requires;
94 | });
95 | mkServices = name: cfg: [ (envsubst name cfg) (addDependencies name cfg) ];
96 |
97 | mkIndividualSecrets = name: cfg:
98 | map (x: {
99 | "${name}-envsubst-${x}" = {
100 | encrypted = "${config.environment.sessionVariables.PASSWORD_STORE_DIR}/${
101 | lib.optionalString (!isNull cfg.directory) "${cfg.directory}/"
102 | }${x}.gpg";
103 | services = [ ];
104 | };
105 | }) cfg.secrets;
106 | in {
107 | options.secrets-envsubst = lib.mkOption {
108 | type = attrsOf (submodule envsubstSecrets);
109 | default = { };
110 | };
111 | config.systemd.services =
112 | mkMerge (concatLists (mapAttrsToList mkServices config.secrets-envsubst));
113 | config.secrets = mkMerge
114 | (concatLists (mapAttrsToList mkIndividualSecrets config.secrets-envsubst));
115 | }
116 |
--------------------------------------------------------------------------------
/modules/secrets.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, inputs, ... }:
2 | with lib;
3 | with types;
4 | let
5 | password-store = config.secretsConfig.password-store;
6 | secret = { name, ... }: {
7 | options = {
8 | encrypted = mkOption {
9 | type = path;
10 | default = "${password-store}/${name}.gpg";
11 | };
12 | decrypted = mkOption {
13 | type = path;
14 | default = "${config.secretsConfig.decryptedDir}/${name}";
15 | };
16 | decrypt = mkOption {
17 | default = pkgs.writeShellScript "gpg-decrypt" ''
18 | set -euo pipefail
19 | export GPG_TTY="$(tty)"
20 | ${pkgs.gnupg}/bin/gpg-connect-agent updatestartuptty /bye 1>&2
21 | ${pkgs.gnupg}/bin/gpg --batch --no-tty --decrypt
22 | '';
23 | };
24 | user = mkOption {
25 | type = str;
26 | default = "balsoft";
27 | };
28 | owner = mkOption {
29 | type = str;
30 | default = "root:root";
31 | };
32 | permissions = mkOption {
33 | type = lib.types.addCheck lib.types.str
34 | (perm: !isNull (builtins.match "[0-7]{3}" perm));
35 | default = "400";
36 | };
37 | services = mkOption {
38 | type = listOf str;
39 | default = [ "${name}" ];
40 | };
41 | __toString = mkOption {
42 | readOnly = true;
43 | default = s: s.decrypted;
44 | };
45 | };
46 | };
47 |
48 | restartAll = "${pkgs.systemd}/bin/systemctl restart ${allServices}";
49 |
50 | activate-secrets = pkgs.writeShellApplication {
51 | name = "activate-secrets";
52 | text = ''
53 | set -euo pipefail
54 | # wait for network
55 | while ! ping -c1 github.com; do sleep 1; done
56 | # Make sure card is available and unlocked
57 | echo fetch | gpg --card-edit --no-tty --command-fd=0
58 | gpg --card-status
59 | SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
60 | export SSH_AUTH_SOCK
61 | if [ -d "${password-store}/.git" ]; then
62 | cd "${password-store}"; git pull
63 | else
64 | git clone ${
65 | lib.escapeShellArg config.secretsConfig.repo
66 | } "${password-store}"
67 | fi
68 | gpg --decrypt < ${password-store}/unlock.gpg > /dev/null
69 | /run/wrappers/bin/sudo ${restartAll}
70 | '';
71 | runtimeInputs = [ pkgs.gnupg pkgs.git pkgs.systemd pkgs.openssh pkgs.iputils pkgs.coreutils ];
72 |
73 | };
74 | decrypt = name: cfg:
75 | with cfg; {
76 | "${name}-secrets" = rec {
77 |
78 | wantedBy = [ "multi-user.target" ];
79 |
80 | requires = [ "user@1000.service" ];
81 | after = requires;
82 |
83 | preStart = ''
84 | stat '${encrypted}'
85 | mkdir -p '${builtins.dirOf decrypted}'
86 | '';
87 |
88 | script = ''
89 | if cat '${encrypted}' | /run/wrappers/bin/sudo -u ${user} ${cfg.decrypt} > '${decrypted}.tmp'; then
90 | mv -f '${decrypted}.tmp' '${decrypted}'
91 | chown '${owner}' '${decrypted}'
92 | chmod '${permissions}' '${decrypted}'
93 | else
94 | echo "Failed to decrypt the secret"
95 | rm '${decrypted}.tmp'
96 | if [[ -f '${decrypted}' ]]; then
97 | echo "The decrypted file exists anyways, not failing"
98 | exit 0
99 | else
100 | exit 1
101 | fi
102 | fi
103 | '';
104 |
105 | serviceConfig = {
106 | Type = "oneshot";
107 | RemainAfterExit = "yes";
108 | };
109 | };
110 | };
111 |
112 | addDependencies = name: cfg:
113 | with cfg;
114 | genAttrs services (service: rec {
115 | requires = [ "${name}-secrets.service" ];
116 | after = requires;
117 | bindsTo = requires;
118 | });
119 |
120 | mkServices = name: cfg: [ (decrypt name cfg) (addDependencies name cfg) ];
121 |
122 | allServices = toString (map (name: "${name}-envsubst.service")
123 | (builtins.attrNames config.secrets-envsubst)
124 | ++ map (name: "${name}-secrets.service")
125 | (builtins.attrNames config.secrets));
126 | in {
127 | options = {
128 | secrets = lib.mkOption {
129 | type = attrsOf (submodule secret);
130 | default = { };
131 | };
132 |
133 | secretsConfig = {
134 | password-store = lib.mkOption {
135 | type = lib.types.path;
136 | default = "/home/balsoft/.local/share/password-store";
137 | };
138 | repo = lib.mkOption {
139 | type = str;
140 | default = "ssh://git@github.com/balsoft/pass";
141 | };
142 | decryptedDir = lib.mkOption {
143 | type = lib.types.path;
144 | default = "/var/secrets";
145 | };
146 | };
147 | };
148 |
149 | config = {
150 |
151 | systemd.services =
152 | mkMerge (concatLists (mapAttrsToList mkServices config.secrets));
153 |
154 | security.sudo.extraRules = [{
155 | users = [ "balsoft" ];
156 | commands = [{
157 | command = restartAll;
158 | options = [ "NOPASSWD" ];
159 | }];
160 | }];
161 |
162 | persist.derivative.directories = [ config.secretsConfig.decryptedDir password-store ];
163 |
164 | home-manager.users.balsoft = {
165 | systemd.user.services.activate-secrets = {
166 | Service = {
167 | ExecStart = "${activate-secrets}/bin/activate-secrets";
168 | Type = "oneshot";
169 | };
170 | Unit = { PartOf = [ "graphical-session-pre.target" ]; };
171 | Install.WantedBy = [ "graphical-session-pre.target" ];
172 | };
173 | systemd.user.services.pass-store-sync = {
174 | Service = {
175 | Environment = [
176 | "PASSWORD_STORE_DIR=${password-store}"
177 | "PATH=${
178 | lib.makeBinPath [ pkgs.pass pkgs.inotify-tools pkgs.gnupg ]
179 | }"
180 | ];
181 | ExecStart = toString (pkgs.writeShellScript "pass-store-sync" ''
182 | export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
183 | while inotifywait "$PASSWORD_STORE_DIR" -r -e move -e close_write -e create -e delete --exclude .git; do
184 | sleep 0.1
185 | {
186 | pass git add --all
187 | pass git commit -m "Change"
188 | pass git pull --rebase
189 | pass git push
190 | } &
191 | done
192 | '');
193 | };
194 | Unit = rec {
195 | After = [ "activate-secrets.service" ];
196 | Wants = After;
197 | };
198 | Install.WantedBy = [ "graphical-session-pre.target" ];
199 | };
200 | programs.password-store = {
201 | enable = true;
202 | package = pkgs.pass-wayland;
203 | settings.PASSWORD_STORE_DIR = password-store;
204 | };
205 | };
206 | };
207 | }
208 |
--------------------------------------------------------------------------------
/modules/themes.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, inputs, ... }:
2 | with lib;
3 | let
4 | colorType =
5 | types.addCheck types.str (x: !isNull (builtins.match "[0-9a-fA-F]{6}" x));
6 | color = mkOption { type = colorType; };
7 |
8 | font = {
9 | family = mkOption { type = types.str; };
10 | size = mkOption { type = types.int; };
11 | };
12 |
13 | fromYAML = yaml:
14 | builtins.fromJSON (builtins.readFile (pkgs.stdenv.mkDerivation {
15 | name = "fromYAML";
16 | phases = [ "buildPhase" ];
17 | buildPhase = "echo '${yaml}' | ${pkgs.yaml2json}/bin/yaml2json > $out";
18 | }));
19 | in {
20 | options = {
21 | themes = {
22 | colors = builtins.listToAttrs (map (name: {
23 | inherit name;
24 | value = color;
25 | }) [
26 | "base00"
27 | "base01"
28 | "base02"
29 | "base03"
30 | "base04"
31 | "base05"
32 | "base06"
33 | "base07"
34 | "base08"
35 | "base09"
36 | "base0A"
37 | "base0B"
38 | "base0C"
39 | "base0D"
40 | "base0E"
41 | "base0F"
42 | ]);
43 | fonts = {
44 | main = font;
45 | serif = font;
46 | mono = font;
47 | };
48 | };
49 | };
50 | config = {
51 | themes.colors = {
52 | # H = 0, S = 0%
53 | base00 = "000000"; # L = 0%
54 | base01 = "1a1a1a"; # L = 10%
55 | base02 = "333333"; # L = 20%
56 | base03 = "808080"; # L = 50%
57 | base04 = "cccccc"; # L = 80%
58 | base05 = "ffffff"; # L = 100%
59 | base06 = "e6e6e6"; # L = 90%
60 | base07 = "e6e6e6"; # L = 90%
61 | # L = 50%, S = 50%
62 | base08 = "bf4040"; # H = 0 RED
63 | base09 = "bf8040"; # H = 30 ORANGE
64 | base0A = "bfbf40"; # H = 60 YELLOW-ish
65 | base0B = "80bf40"; # H = 90 GREEN
66 | # Whoa, a lot of hues are green!
67 | base0C = "40bfbf"; # H = 180 TEAL
68 | base0D = "407fbf"; # H = 210 BLUE
69 | base0E = "7f40bf"; # H = 270 PURPLE
70 | base0F = "bf40bf"; # H = 300 MAGENTA
71 | };
72 | };
73 | }
74 |
--------------------------------------------------------------------------------
/profiles/applications-setup.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }: {
2 | startupApplications = with config.defaultApplications; [
3 | browser.cmd
4 | ];
5 |
6 | environment.sessionVariables = {
7 | EDITOR = config.defaultApplications.editor.cmd;
8 | VISUAL = config.defaultApplications.editor.cmd;
9 | };
10 |
11 | home-manager.users.balsoft = {
12 | home.activation."mimeapps-remove" = {
13 | before = [ "checkLinkTargets" ];
14 | after = [ ];
15 | data = "rm -f /home/balsoft/.config/mimeapps.list";
16 | };
17 |
18 | xdg.mimeApps = {
19 | enable = true;
20 | defaultApplications = with config.defaultApplications;
21 | builtins.mapAttrs (name: value:
22 | if value ? desktop then [ "${value.desktop}.desktop" ] else value) {
23 | "inode/directory" = fm;
24 | "text/html" = browser;
25 | "image/*" = { desktop = "org.kde.gwenview"; };
26 | "application/zip" = archive;
27 | "application/rar" = archive;
28 | "application/7z" = archive;
29 | "application/*tar" = archive;
30 | "x-scheme-handler/http" = browser;
31 | "x-scheme-handler/https" = browser;
32 | "x-scheme-handler/about" = browser;
33 | "x-scheme-handler/mailto" = mail;
34 | "x-scheme-handler/matrix" = matrix;
35 | "application/pdf" = { desktop = "org.kde.okular"; };
36 | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" =
37 | text_processor;
38 | "application/msword" = text_processor;
39 | "application/vnd.oasis.opendocument.text" = text_processor;
40 | "text/csv" = spreadsheet;
41 | "application/vnd.oasis.opendocument.spreadsheet" = spreadsheet;
42 | "text/plain" = editor;
43 | "text/*" = editor;
44 | };
45 | };
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/profiles/applications/aerc.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }: {
2 | defaultApplications.mail = {
3 | cmd = "${pkgs.aerc}/bin/aerc";
4 | desktop = "aerc";
5 | };
6 | startupApplications = [ "${config.defaultApplications.term.cmd} -T aerc -e ${pkgs.aerc}/bin/aerc" ];
7 | home-manager.users.balsoft = {
8 | programs.aerc = {
9 | enable = true;
10 | extraBinds = {
11 | global = {
12 | "" = ":prev-tab";
13 | "" = ":next-tab";
14 | "?" = ":help keys";
15 | };
16 |
17 | messages = {
18 | "h" = ":prev-tab";
19 | "l" = ":next-tab";
20 |
21 | "j" = ":next";
22 | "" = ":next";
23 | "" = ":next 50%";
24 | "" = ":next 100%";
25 | "" = ":next 100%";
26 |
27 | "k" = ":prev";
28 | "" = ":prev";
29 | "" = ":prev 50%";
30 | "" = ":prev 100%";
31 | "" = ":prev 100%";
32 | "g" = ":select 0";
33 | "G" = ":select -1";
34 |
35 | "J" = ":next-folder";
36 | "K" = ":prev-folder";
37 | "H" = ":collapse-folder";
38 | "L" = ":expand-folder";
39 |
40 | "v" = ":mark -t";
41 | "x" = ":mark -t:next";
42 | "V" = ":mark -v";
43 |
44 | "T" = ":toggle-threads";
45 |
46 | "" = ":view";
47 | "d" = ":prompt 'Really delete this message?' 'delete-message'";
48 | "D" = ":delete";
49 | "A" = ":archive flat";
50 |
51 | "C" = ":compose";
52 |
53 | "rr" = ":reply -a";
54 | "rq" = ":reply -aq";
55 | "Rr" = ":reply";
56 | "Rq" = ":reply -q";
57 |
58 | "c" = ":cf";
59 | "$" = ":term";
60 | "!" = ":term";
61 | "|" = ":pipe";
62 |
63 | "/" = ":search";
64 | "\\" = ":filter";
65 | "n" = ":next-result";
66 | "N" = ":prev-result";
67 | "" = ":clear";
68 | };
69 |
70 | "messages:folder=Drafts" = { "" = ":recall"; };
71 |
72 | view = {
73 |
74 | "/" = ":toggle-key-passthrough/";
75 | "q" = ":close";
76 | "O" = ":open";
77 | "S" = ":save";
78 | "|" = ":pipe";
79 | "D" = ":delete";
80 | "A" = ":archive flat";
81 |
82 | "" = ":open-link ";
83 |
84 | "f" = ":forward";
85 | "rr" = ":reply -a";
86 | "rq" = ":reply -aq";
87 | "Rr" = ":reply";
88 | "Rq" = ":reply -q";
89 |
90 | "H" = ":toggle-headers";
91 | "" = ":prev-part";
92 | "" = ":next-part";
93 | "J" = ":next";
94 | "K" = ":prev";
95 | };
96 |
97 | "view::passthrough" = {
98 | "$noinherit" = true;
99 | "$ex" = "";
100 | "" = ":toggle-key-passthrough";
101 | };
102 |
103 | compose = {
104 | "$noinherit" = "true";
105 | "$ex" = "";
106 | "" = ":prev-field";
107 | "" = ":next-field";
108 | "" = ":switch-account -p";
109 | "" = ":switch-account -n";
110 | "" = ":next-field";
111 | "" = ":prev-tab";
112 | "" = ":next-tab";
113 | };
114 |
115 | "compose::editor" = {
116 | "$noinherit" = "true";
117 | "$ex" = "";
118 | "" = ":prev-field";
119 | "" = ":next-field";
120 | "" = ":prev-tab";
121 | "" = ":next-tab";
122 | };
123 |
124 | "compose::review" = {
125 | "y" = ":send";
126 | "n" = ":abort";
127 | "p" = ":postpone";
128 | "q" = ":choose -o d discard abort -o p postpone postpone";
129 | "e" = ":edit";
130 | "a" = ":attach";
131 | "d" = ":detach";
132 | };
133 |
134 | terminal = {
135 | "$noinherit" = "true";
136 | "$ex" = "";
137 |
138 | "" = ":prev-tab";
139 | "" = ":next-tab";
140 | };
141 | };
142 | extraConfig = {
143 | general.unsafe-accounts-conf = true;
144 | ui = {
145 | reverse-thread-order = true;
146 | threading-enabled = true;
147 | show-thread-context = true;
148 | this-day-time-format = ''" 15:04"'';
149 | this-year-time-format = "Mon Jan 02 15:04";
150 | timestamp-format = "2006-01-02 15:04";
151 |
152 | spinner = "[ ⡿ ],[ ⣟ ],[ ⣯ ],[ ⣷ ],[ ⣾ ],[ ⣽ ],[ ⣻ ],[ ⢿ ]";
153 | border-char-vertical = "┃";
154 | border-char-horizontal = "━";
155 | };
156 | viewer = { always-show-mime = true; };
157 | compose = { no-attachment-warning = "^[^>]*attach(ed|ment)"; };
158 | triggers = {
159 | email-received = ''exec notify-send --icon=mail-message "Mail from %n" "%s"'';
160 | };
161 | filters = {
162 | "text/plain" = "colorize";
163 | "text/html" = "html";
164 | "text/calendar" = "calendar";
165 | "message/delivery-status" = "colorize";
166 | "message/rfc822" = "colorize";
167 | "image/*" = "${pkgs.catimg}/bin/catimg -";
168 | };
169 | };
170 | stylesets = {
171 | default = {
172 | "border.bg" = 0;
173 | "border.fg" = 7;
174 | "border.reverse" = "false";
175 | "msglist_default.bg" = 0;
176 | "msglist_unread.fg" = 3;
177 | "msglist_unread.bold" = "true";
178 | "msglist_marked.bg" = 4;
179 | "dirlist_default.bg" = 0;
180 | "dirlist_unread.fg" = 3;
181 | };
182 | };
183 | };
184 | accounts.email.accounts = {
185 | Personal = {
186 | primary = true;
187 | aerc.enable = true;
188 | realName = "Alexander Bantyev";
189 | address = "balsoft@balsoft.ru";
190 | imap.host = "balsoft.ru";
191 | smtp.host = "balsoft.ru";
192 |
193 | userName = "balsoft@balsoft.ru";
194 | passwordCommand = "pass email/balsoft@balsoft.ru";
195 |
196 | folders.inbox = "virtual.all";
197 | };
198 | Work = {
199 | aerc.enable = true;
200 | address = "alexander.bantyev@moduscreate.com";
201 | realName = "Alexander Bantyev";
202 | imap.host = "imap.gmail.com";
203 | smtp.host = "smtp.gmail.com";
204 |
205 | userName = "alexander.bantyev@moduscreate.com";
206 | passwordCommand = "pass aerc/alexander.bantyev@moduscreate.com";
207 |
208 | folders.inbox = "[Gmail]/All Mail";
209 | };
210 | };
211 | };
212 | }
213 |
--------------------------------------------------------------------------------
/profiles/applications/alacritty.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }: {
2 | defaultApplications.term = {
3 | cmd = "${pkgs.alacritty}/bin/alacritty";
4 | desktop = "alacritty";
5 | };
6 | home-manager.users.balsoft.programs.alacritty = {
7 | enable = true;
8 | settings = {
9 | keyboard.bindings = [{
10 | key = "Return";
11 | mods = "Control";
12 | action = "SpawnNewInstance";
13 | }];
14 |
15 | font = {
16 | normal.family = config.themes.fonts.mono.family;
17 | size = config.themes.fonts.mono.size;
18 | bold = { style = "Bold"; };
19 | };
20 |
21 | window.padding = {
22 | x = 2;
23 | y = 2;
24 | };
25 |
26 | terminal.shell.program = "${pkgs.zsh}/bin/zsh";
27 |
28 | cursor.style = "Beam";
29 |
30 | colors = with pkgs.my-lib.thmHash config.themes.colors; {
31 | primary = {
32 | background = base00;
33 | foreground = base05;
34 | dim_foreground = base04;
35 | };
36 | cursor = {
37 | text = base02;
38 | cursor = base05;
39 | };
40 | normal = {
41 | black = base00;
42 | red = base08;
43 | green = base0B;
44 | yellow = base0A;
45 | blue = base0D;
46 | magenta = base0E;
47 | white = base07;
48 | };
49 | };
50 | };
51 | };
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/profiles/applications/angelfish.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }: {
2 | environment.systemPackages = [ pkgs.plasma5Packages.angelfish ];
3 | defaultApplications.browser = {
4 | cmd = "${pkgs.plasma5Packages.angelfish}/bin/angelfish";
5 | desktop = "org.kde.angelfish";
6 | };
7 | home-manager.users.balsoft = {
8 | xdg.configFile.angelfishrc.text = pkgs.lib.generators.toGitINI {
9 | NavigationBar = {
10 | navBarReload = true;
11 | };
12 | };
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/profiles/applications/cantata.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, ... }: {
2 | home-manager.users.balsoft = {
3 | home.packages = [ pkgs.cantata ];
4 | wayland.windowManager.sway = {
5 | config = {
6 | assigns."ﱘ" = [{ app_id = "cantata"; }];
7 | };
8 | };
9 | xdg.configFile."cantata/cantata.conf".text = pkgs.my-lib.genIni {
10 | General = {
11 | lyricProviders = "azlyrics.com, chartlyrics.com, lyrics.wikia.com";
12 | wikipediaLangs = "en:en";
13 | mpris = "true";
14 | currentConnection = "Default";
15 |
16 | version = pkgs.cantata.version;
17 |
18 | hiddenPages = "PlayQueuePage, LibraryPage, PlaylistsPage, OnlineServicesPage, DevicesPage";
19 | };
20 |
21 | AlbumView.fullWidthCover = false;
22 |
23 | Connection-Default = {
24 | host = "localhost";
25 | passwd = "";
26 | port = "6600";
27 | };
28 |
29 | VolumeControl.control = "mpd";
30 | };
31 | };
32 |
33 | startupApplications = [ "${pkgs.cantata}/bin/cantata" ];
34 | }
35 |
--------------------------------------------------------------------------------
/profiles/applications/emacs/default.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, inputs, ... }:
2 | let
3 | emacs = pkgs.emacsPgtk;
4 | in {
5 | # secrets-envsubst.emacs = {
6 | # owner = "balsoft:users";
7 | # directory = "emacs";
8 | # };
9 |
10 | persist.state.homeFiles =
11 | [ ".config/emacs/custom" ".config/emacs/eshell/history" ];
12 |
13 | defaultApplications.editor = {
14 | cmd = toString (pkgs.writeShellScript "emacsclient-newwindow" ''
15 | ${config.home-manager.users.balsoft.programs.emacs.finalPackage}/bin/emacsclient -c "$@"
16 | '');
17 | desktop = "emacsclient";
18 | };
19 |
20 | home-manager.users.balsoft = {
21 | programs.emacs = {
22 | enable = true;
23 | package = emacs;
24 | extraPackages = epkgs:
25 | with epkgs; [
26 | use-package
27 | nix-mode
28 | haskell-mode
29 | exec-path-from-shell
30 | counsel
31 | projectile
32 | which-key
33 | markdown-mode
34 | frames-only-mode
35 | company
36 | rainbow-delimiters
37 | diff-hl
38 | mode-line-bell
39 | flycheck
40 | flycheck-pkg-config
41 | auto-indent-mode
42 | company-ghci
43 | expand-region
44 | ivy
45 | smex
46 | quickrun
47 | counsel-tramp
48 | ix
49 | magit
50 | elixir-mode
51 | company-box
52 | ws-butler
53 | yaml-mode
54 | gitlab-ci-mode
55 | gitlab-ci-mode-flycheck
56 | gitlab
57 | undo-tree
58 | rust-mode
59 | edit-indirect
60 | idris-mode
61 | lsp-mode
62 | envrc
63 | lsp-haskell
64 | treemacs
65 | lsp-treemacs
66 | treemacs-projectile
67 | dap-mode
68 | # forge
69 | crdt
70 | base16-theme
71 | org-caldav
72 | evil
73 | tuareg
74 | fira-code-mode
75 | terraform-mode
76 | dhall-mode
77 | ];
78 | };
79 |
80 | home.packages = [ pkgs.clang ];
81 |
82 | services.emacs.enable = true;
83 |
84 | systemd.user.services.emacs = {
85 | Service = {
86 | Environment =
87 | "PATH=/run/current-system/sw/bin:/etc/profiles/per-user/balsoft/bin";
88 | };
89 | Unit.After = [ "sway-session.target" ];
90 | Install = {
91 | WantedBy = lib.mkForce [ "sway-session.target" ];
92 | };
93 | };
94 |
95 | xdg.configFile."emacs/init.el".source = pkgs.substituteAll ({
96 | src = ./init.el;
97 | font = with config.themes.fonts; "${mono.family} ${toString mono.size}";
98 | } // pkgs.my-lib.thmHash config.themes.colors);
99 | };
100 | }
101 |
--------------------------------------------------------------------------------
/profiles/applications/emacs/init.el:
--------------------------------------------------------------------------------
1 | ;;; init.el --- balsoft's config
2 |
3 | ;;; Commentary:
4 |
5 | ;;; None
6 |
7 | ;; -*- lexical-binding: t -*-
8 |
9 | ;;; Code:
10 |
11 | (require 'package)
12 |
13 | (package-initialize)
14 |
15 | (eval-when-compile
16 | (require 'use-package))
17 | (setq use-package-always-ensure nil)
18 |
19 | (setq-default tab-width 2)
20 |
21 | (mode-line-bell-mode)
22 |
23 | (line-number-mode)
24 | (column-number-mode)
25 |
26 | (setq-default indent-tabs-mode nil)
27 |
28 | (setq-default tab-always-indent 't)
29 |
30 | (setq-default compilation-scroll-output 'first-error)
31 |
32 | (use-package ws-butler
33 | :config
34 | (ws-butler-global-mode)
35 | )
36 |
37 | (global-auto-revert-mode)
38 |
39 | (setq auto-save-interval 5)
40 |
41 | (auto-save-visited-mode)
42 |
43 | (setq make-backup-files nil)
44 |
45 | ;; (use-package xah-fly-keys
46 | ;; :config
47 | ;; (xah-fly-keys-set-layout "qwerty")
48 | ;; (xah-fly-keys 1)
49 | ;; (define-key xah-fly-insert-map (kbd "M-SPC") 'xah-fly-command-mode-activate)
50 | ;; )
51 |
52 | (use-package evil
53 | :config
54 | (evil-mode 1))
55 |
56 | (global-set-key (kbd "C-b") 'switch-to-buffer)
57 |
58 | (global-display-line-numbers-mode)
59 |
60 | (electric-pair-mode)
61 |
62 | (electric-indent-mode)
63 |
64 | (use-package flycheck
65 | :config
66 | (global-flycheck-mode))
67 |
68 | (menu-bar-mode -1)
69 | (scroll-bar-mode -1)
70 | (tool-bar-mode -1)
71 | (cua-selection-mode 1)
72 |
73 |
74 | (setq auto-revert-check-vc-info t)
75 |
76 | (vc-mode-line t)
77 |
78 | (when (not window-system)
79 | (xterm-mouse-mode 1))
80 |
81 | (use-package fira-code-mode
82 | :custom (fira-code-mode-disabled-ligatures '("[]" "#{" "#(" "#_" "#_(" "x")) ;; List of ligatures to turn off
83 | :config (global-fira-code-mode))
84 |
85 | (use-package company-ghci
86 | :config
87 | (push 'company-ghci company-backends))
88 |
89 | (global-set-key [home] 'smart-beginning-of-line)
90 |
91 | (global-unset-key [menu-bar options cua-mode])
92 | (global-unset-key (kbd "C-x C-f"))
93 | (global-set-key (kbd "C-x C-f") 'find-file-other-frame)
94 | (global-unset-key (kbd "C-x b")) ;; Old habits die hard
95 |
96 | (fringe-mode '(0 . 0))
97 |
98 | ;; scroll one line at a time (less "jumpy" than defaults)
99 |
100 | (setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) ;; one line at a time
101 |
102 | (setq mouse-wheel-progressive-speed nil) ;; don't accelerate scrolling
103 |
104 | (setq mouse-wheel-follow-mouse 't) ;; scroll window under mouse
105 |
106 | (setq scroll-step 1) ;; keyboard scroll one line at a time
107 |
108 | (use-package frames-only-mode)
109 | ;; Make new frames instead of new windows
110 | (setq pop-up-frames 'graphic-only)
111 | (setq gdb-use-separate-io-buffer nil)
112 | (setq gdb-many-windows nil)
113 |
114 | ;; -------------------
115 | ;; Projectile
116 | ;; -------------------
117 | ;; No deferred loading as bind-keymap
118 | ;; doesn't handle wakib C-d keymaps
119 | (use-package projectile
120 | :config
121 | (define-key projectile-mode-map (kbd "C-c p") nil)
122 | (define-key projectile-mode-map (kbd "C-x p") 'projectile-command-map)
123 | (projectile-mode 1)
124 | (global-unset-key [menu-bar tools Projectile])
125 | (projectile-register-project-type 'flake '("flake.nix")
126 | :compile "nix build"
127 | :run "nix run")
128 | (setq projectile-project-search-path '("~/projects/"))
129 |
130 | (global-set-key (kbd "") 'projectile-compile-project)
131 | (global-set-key (kbd "") 'projectile-run-project))
132 |
133 | (use-package nix-mode
134 | :hook
135 | ((nix-mode . (lambda () (local-set-key (kbd "") 'nix-format-buffer))))
136 | ((nix-mode . (lambda () (setq indent-line-function 'nix-indent-line)))))
137 |
138 | (use-package company
139 | :config
140 | (global-company-mode 1)
141 | ;; Number the candidates (use M-1, M-2 etc to select completions).
142 | (setq company-show-numbers t)
143 | (setq company-idle-delay 0)
144 | )
145 |
146 | (use-package company-box
147 | :hook (company-mode . company-box-mode))
148 |
149 |
150 | ;; -------------------
151 | ;; Ivy
152 | ;; -------------------
153 | (use-package ivy
154 | :config
155 | (ivy-mode 1)
156 | (setq ivy-use-virtual-buffers t)
157 | (define-key ivy-minibuffer-map [remap keyboard-quit] 'minibuffer-keyboard-quit)
158 | (setq ivy-count-format "")
159 | (setq ivy-initial-inputs-alist nil))
160 |
161 | (use-package counsel
162 | :config
163 | counsel-mode)
164 |
165 | (use-package smex)
166 |
167 | (show-paren-mode 1)
168 | ;; TODO - MOVE Electric Pair Mode to user local
169 |
170 |
171 | ;; MAJOR MODES
172 |
173 | (use-package markdown-mode
174 | :mode "\\.\\(m\\(ark\\)?down\\|md\\)$")
175 |
176 |
177 | ;; Setup Splash Screen
178 | ;; (setq inhibit-startup-screen t)
179 | ;; (setq-default major-mode 'fundamental-mode)
180 | ;; (setq-default initial-scratch-message "")
181 |
182 | (setq custom-file (expand-file-name "custom" user-emacs-directory))
183 | (load custom-file t t)
184 |
185 | (auto-fill-mode)
186 |
187 |
188 | (add-to-list 'default-frame-alist '(font . "@font@"))
189 | (set-face-attribute 'default nil :font "@font@")
190 |
191 | (setq inhibit-startup-screen t)
192 |
193 | (use-package lsp-mode
194 | :config
195 | )
196 |
197 |
198 | (use-package envrc
199 | :config
200 | (envrc-global-mode)
201 | (advice-add 'lsp :before (lambda (&optional n) (envrc--update))))
202 |
203 | (setq treemacs-position 'right)
204 |
205 | (use-package treemacs)
206 |
207 | (use-package lsp-treemacs)
208 |
209 | (use-package treemacs-projectile)
210 |
211 | (setq initial-major-mode 'text-mode)
212 |
213 | (defun compile-on-save-start ()
214 | (let ((buffer (compilation-find-buffer)))
215 | (unless (get-buffer-process buffer)
216 | (recompile))))
217 |
218 | (define-minor-mode compile-on-save-mode
219 | "Minor mode to automatically call `recompile' whenever the
220 | current buffer is saved. When there is ongoing compilation,
221 | nothing happens."
222 | :lighter " CoS"
223 | (if compile-on-save-mode
224 | (progn (make-local-variable 'after-save-hook)
225 | (add-hook 'after-save-hook 'compile-on-save-start nil t))
226 | (kill-local-variable 'after-save-hook)))
227 |
228 | (defun maybe-delete-frame-buffer (frame)
229 | "When a dedicated FRAME is deleted, also kill its buffer.
230 | A dedicated frame contains a single window whose buffer is not
231 | displayed anywhere else."
232 | (let ((windows (window-list frame)))
233 | (when (eq 1 (length windows))
234 | (let ((buffer (window-buffer (car windows))))
235 | (when (eq 1 (length (get-buffer-window-list buffer nil t)))
236 | (kill-buffer buffer))))))
237 |
238 | (add-to-list 'delete-frame-functions #'maybe-delete-frame-buffer)
239 |
240 | (require 'base16-theme)
241 |
242 | (defvar base16-generated-colors
243 | '(:base00 "@base00@"
244 | :base01 "@base01@"
245 | :base02 "@base02@"
246 | :base03 "@base03@"
247 | :base04 "@base04@"
248 | :base05 "@base05@"
249 | :base06 "@base06@"
250 | :base07 "@base07@"
251 | :base08 "@base08@"
252 | :base09 "@base09@"
253 | :base0A "@base0A@"
254 | :base0B "@base0B@"
255 | :base0C "@base0C@"
256 | :base0D "@base0D@"
257 | :base0E "@base0E@"
258 | :base0F "@base0F@")
259 | "All colors for Base16 are defined here.")
260 |
261 | ;; Define the theme
262 | (deftheme base16-generated)
263 |
264 | ;; Add all the faces to the theme
265 | (base16-theme-define 'base16-generated base16-generated-colors)
266 |
267 | ;; Mark the theme as provided
268 | (provide-theme 'base16-generated)
269 |
270 | (enable-theme 'base16-generated)
271 | ;;; init.el ends here
272 |
--------------------------------------------------------------------------------
/profiles/applications/emacs/org-gcal-config.el:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balsoft/nixos-config/d3a2e32bbf74d779629803965e945fcf29d1c1ec/profiles/applications/emacs/org-gcal-config.el
--------------------------------------------------------------------------------
/profiles/applications/firefox.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, inputs, ... }:
2 | let
3 | thm = pkgs.my-lib.thmHash config.themes.colors;
4 | fonts = config.themes.fonts;
5 | in {
6 | services.dbus.packages = [ pkgs.librewolf ];
7 |
8 | environment.sessionVariables = {
9 | MOZ_USE_XINPUT2 = "1";
10 | MOZ_DBUS_REMOTE = "1";
11 | };
12 | programs.browserpass.enable = true;
13 |
14 | persist.state.directories = [ "/home/balsoft/.librewolf/default" ];
15 |
16 | defaultApplications.browser = {
17 | cmd = "${pkgs.librewolf}/bin/librewolf";
18 | desktop = "librewolf";
19 | };
20 |
21 | home-manager.users.balsoft = {
22 | programs.browserpass = {
23 | enable = true;
24 | browsers = [ "librewolf" ];
25 | };
26 | wayland.windowManager.sway.config = {
27 | window.commands = [
28 | {
29 | criteria = { title = "Firefox — Sharing Indicator"; };
30 | command = "floating enable";
31 | }
32 | {
33 | criteria = { title = "Firefox — Sharing Indicator"; };
34 | command = "no_focus";
35 | }
36 | {
37 | criteria = { title = "Firefox — Sharing Indicator"; };
38 | command = "resize set 0 0";
39 | }
40 | {
41 | criteria = { title = "Firefox — Sharing Indicator"; };
42 | command = "move absolute position 10 10";
43 | }
44 | ];
45 | };
46 |
47 | # home.file.".mozilla/native-messaging-hosts/tridactyl.json".text = let
48 | # tridactyl = with pkgs.nimPackages;
49 | # buildNimPackage {
50 | # pname = "tridactyl_native";
51 | # version = "dev";
52 | # nimBinOnly = true;
53 | # src = inputs.tridactyl-native-messenger;
54 | # buildInputs = [ tempfile regex unicodedb ];
55 | # };
56 | # in builtins.toJSON {
57 | # name = "tridactyl";
58 | # description = "Tridactyl native command handler";
59 | # path = "${tridactyl}/bin/native_main";
60 | # type = "stdio";
61 |
62 | # allowed_extensions = [
63 | # "tridactyl.vim@cmcaine.co.uk"
64 | # "tridactyl.vim.betas@cmcaine.co.uk"
65 | # "tridactyl.vim.betas.nonewtab@cmcaine.co.uk"
66 | # ];
67 | # };
68 |
69 | programs.librewolf = {
70 | enable = true;
71 | package = pkgs.librewolf;
72 | profiles.default = {
73 | extensions.packages = with pkgs.nur.rycee.firefox-addons; [
74 | adsum-notabs
75 | ublock-origin
76 | sponsorblock
77 | browserpass
78 | darkreader
79 | ];
80 | id = 0;
81 | userChrome = ''
82 | #TabsToolbar {
83 | visibility: collapse;
84 | }
85 | // toolbar#nav-bar, nav-bar-customization-target {
86 | // background: ${thm.base00} !important;
87 | // }
88 | // @-moz-document url("about:newtab") {
89 | // * { background-color: ${thm.base00} !important; }
90 | // }
91 | '';
92 | settings = {
93 | "toolkit.legacyUserProfileCustomizations.stylesheets" = true;
94 |
95 | "extensions.autoDisableScopes" = 0;
96 |
97 | "browser.search.defaultenginename" = "Google";
98 | "browser.search.selectedEngine" = "Google";
99 | "browser.urlbar.placeholderName" = "Google";
100 | "browser.search.region" = "US";
101 |
102 | "browser.uidensity" = 1;
103 | "browser.search.openintab" = true;
104 | "xpinstall.signatures.required" = false;
105 | "extensions.update.enabled" = false;
106 |
107 | "font.name.monospace.x-western" = "${fonts.mono.family}";
108 | "font.name.sans-serif.x-western" = "${fonts.main.family}";
109 | "font.name.serif.x-western" = "${fonts.serif.family}";
110 |
111 | "browser.anchor_color" = thm.base0D;
112 | "browser.visited_color" = thm.base0C;
113 | "browser.display.use_document_fonts" = true;
114 | "pdfjs.disabled" = true;
115 | "media.videocontrols.picture-in-picture.enabled" = true;
116 |
117 | "widget.non-native-theme.enabled" = false;
118 |
119 | "browser.newtabpage.enabled" = false;
120 | "browser.startup.homepage" = "about:blank";
121 |
122 | "browser.newtabpage.activity-stream.feeds.telemetry" = false;
123 | "browser.newtabpage.activity-stream.telemetry" = false;
124 | "browser.ping-centre.telemetry" = false;
125 | "toolkit.telemetry.archive.enabled" = false;
126 | "toolkit.telemetry.bhrPing.enabled" = false;
127 | "toolkit.telemetry.enabled" = false;
128 | "toolkit.telemetry.firstShutdownPing.enabled" = false;
129 | "toolkit.telemetry.hybridContent.enabled" = false;
130 | "toolkit.telemetry.newProfilePing.enabled" = false;
131 | "toolkit.telemetry.reportingpolicy.firstRun" = false;
132 | "toolkit.telemetry.shutdownPingSender.enabled" = false;
133 | "toolkit.telemetry.unified" = false;
134 | "toolkit.telemetry.updatePing.enabled" = false;
135 |
136 | "experiments.activeExperiment" = false;
137 | "experiments.enabled" = false;
138 | "experiments.supported" = false;
139 | "network.allow-experiments" = false;
140 |
141 | "privacy.clearOnShutdown_v2.cookiesAndStorage" = false;
142 | };
143 | };
144 | };
145 | };
146 | }
147 |
--------------------------------------------------------------------------------
/profiles/applications/geary.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }:
2 | let
3 | gearyConfig = {
4 | Account = {
5 | label = "";
6 | ordinal = 6;
7 | prefetch_days = -1;
8 | save_drafts = true;
9 | save_sent = true;
10 | sender_mailboxes = "Alexander Bantyev ;";
11 | service_provider = "other";
12 | signature = builtins.replaceStrings [ "\n" ] [ "\\n" ] ''
13 | --
14 | Александр Бантьев /Alexander Bantyev/ aka balsoft
15 |
16 | Nix DevOPS/SRE at tweag.io
17 |
18 |
19 |
20 |
21 | matrix://@balsoft:balsoft.ru
22 | (https://matrix.to/#/@balsoft:balsoft.ru)
23 | https://t.me/balsoft
24 | https://github.com/balsoft
25 | '';
26 | use_signature = true;
27 | };
28 | Folders = {
29 | archive_folder = "Archive;";
30 | drafts_folder = "";
31 | junk_folder = "";
32 | sent_folder = "";
33 | trash_folder = "";
34 | };
35 | Incoming = {
36 | credentials = "custom";
37 | host = "balsoft.ru";
38 | login = "balsoft@balsoft.ru";
39 | port = 993;
40 | remember_password = true;
41 | transport_security = "transport";
42 | };
43 | Metadata = {
44 | status = "enabled";
45 | version = 1;
46 | };
47 | Outgoing = {
48 | credentials = "use-incoming";
49 | host = "balsoft.ru";
50 | port = 587;
51 | remember_password = true;
52 | transport_security = "start-tls";
53 | };
54 | };
55 | in {
56 | programs.geary.enable = true;
57 |
58 | persist.cache.directories = [ "/home/balsoft/.local/share/geary" ];
59 |
60 | defaultApplications.mail = {
61 | cmd = "${pkgs.gnome.geary}/bin/geary";
62 | desktop = "org.gnome.Geary";
63 | };
64 |
65 | home-manager.users.balsoft = let
66 | fonts = config.themes.fonts;
67 | thm = pkgs.my-lib.thmHash config.themes.colors;
68 | in {
69 | xdg.configFile."geary/user-style.css".text = ''
70 | *, html, body, body.plain div, body.plain a, body.plain p, body.plain span {
71 | background: ${thm.base00} !important;
72 | color: ${thm.base05} !important;
73 | font-family: '${fonts.mono.family}', monospace !important;
74 | }
75 | *, html, body {
76 | font-size: ${toString fonts.mono.size}pt;
77 | }
78 | '';
79 | home.activation.geary = ''
80 | mkdir -p "$XDG_CONFIG_HOME/geary/account_03"
81 | $DRY_RUN_CMD ln -sf $VERBOSE_ARG ${
82 | builtins.toFile "geary.ini" (pkgs.my-lib.genIni gearyConfig)
83 | } "$XDG_CONFIG_HOME/geary/account_03/geary.ini"
84 | '';
85 | };
86 | }
87 |
--------------------------------------------------------------------------------
/profiles/applications/github.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, ... }: {
2 | secrets.github_token = {
3 | owner = "balsoft";
4 | services = [ ];
5 | };
6 |
7 | home-manager.users.balsoft = {
8 | home.packages = let
9 | stateless-github-cli = pkgs.writeShellScriptBin "gh" ''
10 | export GITHUB_TOKEN="''${GITHUB_TOKEN-$(cat ${config.secrets.github_token.decrypted})}"
11 | exec ${pkgs.github-cli}/bin/gh "$@"
12 | '';
13 | in [ stateless-github-cli ];
14 |
15 | xdg.configFile."gh/config.yaml".text = builtins.toJSON {
16 | git_protocol = "ssh";
17 | editor = "";
18 | aliases = {
19 | pv = "pr view --comments";
20 | };
21 | };
22 | };
23 | }
24 |
--------------------------------------------------------------------------------
/profiles/applications/gwenview.nix:
--------------------------------------------------------------------------------
1 | { pkgs, lib, config, ... }:
2 | {
3 | home-manager.users.balsoft = {
4 | home.packages = [ pkgs.kdePackages.gwenview ];
5 | xdg.configFile."gwenviewrc".text = pkgs.my-lib.genIni {
6 | General = {
7 | HistoryEnabled = false;
8 | UrlNavigatorIsEditable = true;
9 | };
10 | ImageView.EnlargeSmallerImages = true;
11 | ThumbnailView.Sorting = "Sorting::Rating";
12 | };
13 | };
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/profiles/applications/helix.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }: {
2 | defaultApplications.editor = {
3 | cmd = "${pkgs.helix}/bin/hx";
4 | desktop = "helix";
5 | };
6 | home-manager.users.balsoft = {
7 | home.packages = [
8 | (pkgs.makeDesktopItem {
9 | name = "helix";
10 | desktopName = "Helix editor";
11 | terminal = true;
12 | categories = [ "Utility" "TextEditor" "Development" "IDE" ];
13 | mimeTypes = [
14 | "inode/directory"
15 | "text/english"
16 | "text/plain"
17 | "text/x-makefile"
18 | "text/x-c++hdr"
19 | "text/x-c++src"
20 | "text/x-chdr"
21 | "text/x-csrc"
22 | "text/x-java"
23 | "text/x-moc"
24 | "text/x-pascal"
25 | "text/x-tcl"
26 | "text/x-tex"
27 | "application/x-shellscript"
28 | "application/json"
29 | "application/xml"
30 | "text/xml"
31 | "text/x-c"
32 | "text/x-c++"
33 | ];
34 | exec = "${pkgs.helix}/bin/hx %F";
35 | icon = "helix";
36 | })
37 | ];
38 | xdg.configFile."helix/languages.toml".text = ''
39 | [language-server.nil]
40 | command = "nil"
41 | args = ["--stdio"]
42 | config = { nix = { maxMemoryMB = 5000, flake = { autoArchive = false, autoEvalInputs = true } } }
43 | [[language]]
44 | name = "nix"
45 | formatter = { command = "nixfmt", args = [] }
46 | '';
47 | programs.helix = {
48 | enable = true;
49 | settings = {
50 | theme = "base16";
51 | editor = {
52 | indent-guides.render = true;
53 | lsp.display-messages = true;
54 | cursor-shape = {
55 | insert = "bar";
56 | normal = "block";
57 | select = "underline";
58 | };
59 | color-modes = true;
60 | };
61 | keys = {
62 | insert = {
63 | up = "no_op";
64 | down = "no_op";
65 | left = "no_op";
66 | right = "no_op";
67 | pageup = "no_op";
68 | pagedown = "no_op";
69 | home = "no_op";
70 | end = "no_op";
71 | };
72 | normal = {
73 | "A-q" = [
74 | "goto_prev_paragraph"
75 | "goto_next_paragraph"
76 | "trim_selections"
77 | ":reflow 80"
78 | "collapse_selection"
79 | ];
80 | "A-h" = "select_prev_sibling";
81 | "A-j" = "shrink_selection";
82 | "A-k" = "expand_selection";
83 | "A-l" = "select_next_sibling";
84 | "V" = [ "select_mode" "extend_to_line_bounds" ];
85 | };
86 | };
87 | };
88 | themes.base16 =
89 | with (builtins.mapAttrs (_: v: "#${v}") config.themes.colors); rec {
90 | "ui.menu" = { bg = base01; };
91 | "ui.menu.selected" = {
92 | bg = base00;
93 | modifiers = [ "reversed" ];
94 | };
95 | "ui.linenr" = {
96 | fg = base02;
97 | bg = base00;
98 | };
99 | "ui.popup" = { modifiers = [ "reversed" ]; };
100 | "ui.linenr.selected" = {
101 | fg = base05;
102 | bg = base00;
103 | modifiers = [ "bold" ];
104 | };
105 | "ui.selection" = {
106 | fg = base00;
107 | bg = base0D;
108 | };
109 | "ui.selection.primary" = { modifiers = [ "reversed" ]; };
110 | "comment" = { fg = base03; };
111 | "ui.statusline" = {
112 | fg = base05;
113 | bg = base02;
114 | };
115 | "ui.statusline.inactive" = {
116 | fg = base03;
117 | bg = base01;
118 | };
119 | "ui.help" = {
120 | fg = base01;
121 | bg = base05;
122 | };
123 | "ui.cursor" = { modifiers = [ "reversed" ]; };
124 | "ui.cursor.insert" = {
125 | bg = base01;
126 | modifiers = [ "reversed" ];
127 | };
128 | "variable" = base05;
129 | "variable.builtin" = {
130 | fg = base06;
131 | modifiers = [ "bold" ];
132 | };
133 | "constant.numeric" = base0C;
134 | "constant" = base0A;
135 | "constant.builtin" = base0A;
136 | "constant.character" = {
137 | fg = base0C;
138 | modifiers = [ "bold" ];
139 | };
140 | "attributes" = base0A;
141 | "type" = {
142 | fg = base05;
143 | modifiers = [ "bold" ];
144 | };
145 | "ui.cursor.match" = { bg = base01; };
146 | "string" = base0B;
147 | # "variable.other.member" = base0B;
148 | "constant.character.escape" = base0E;
149 | "function" = base05;
150 | "constructor" = base0A;
151 | "special" = base0F;
152 | "keyword" = {
153 | fg = base0D;
154 | modifiers = [ "bold" ];
155 | };
156 | "markup.heading" = {
157 | fg = base0A;
158 | modifiers = [ "bold" ];
159 | };
160 | "markup.bold" = { modifiers = [ "bold" ]; };
161 | "markup.italic" = { modifiers = [ "italic" ]; };
162 | "markup.link" = {
163 | underline.style = "line";
164 | fg = base0D;
165 | };
166 | "markup.quote" = {
167 | bg = base01;
168 | modifiers = [ "italic" ];
169 | };
170 | "markup.raw" = { bg = base01; };
171 | "label" = base0B;
172 | "namespace" = base0F;
173 | "diff.plus" = base0B;
174 | "diff.delta" = base0A;
175 | "diff.minus" = base08;
176 | "diagnostic" = { underline = { style = "line"; }; };
177 | "diagnostic.error" = { fg = base08; } // diagnostic;
178 | "diagnostic.warning" = { fg = base09; } // diagnostic;
179 | "ui.gutter" = { bg = base00; };
180 | "info" = base0D;
181 | "hint" = base02;
182 | "debug" = base02;
183 | "warning" = base09;
184 | "error" = base08;
185 | "ui.virtual.indent-guide" = base01;
186 | "highlight" = base09;
187 | };
188 | };
189 | };
190 | }
191 |
--------------------------------------------------------------------------------
/profiles/applications/himalaya.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, inputs, lib, ... }: {
2 | environment.systemPackages = [ pkgs.himalaya ];
3 | }
4 |
--------------------------------------------------------------------------------
/profiles/applications/josm.nix:
--------------------------------------------------------------------------------
1 | { pkgs, ... }: {
2 | home-manager.users.balsoft.home.packages = [ pkgs.josm ];
3 | persist.state.directories =
4 | [ "/home/balsoft/.local/share/JOSM" "/home/balsoft/.config/JOSM" ];
5 | }
6 |
--------------------------------------------------------------------------------
/profiles/applications/nheko.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | home-manager.users.balsoft.home.packages = [ pkgs.nheko ];
3 | defaultApplications.matrix = {
4 | cmd = "${pkgs.nheko}/bin/nheko";
5 | desktop = "nheko";
6 | };
7 | startupApplications = [
8 | "${pkgs.nheko}/bin/nheko"
9 | ];
10 | persist.state.directories =
11 | [ "/home/balsoft/.local/share/nheko" "/home/balsoft/.config/nheko" ];
12 | }
13 |
--------------------------------------------------------------------------------
/profiles/applications/okular.nix:
--------------------------------------------------------------------------------
1 | { pkgs, lib, config, ... }:
2 | with (pkgs.my-lib.thmDec config.themes.colors); {
3 | home-manager.users.balsoft = {
4 | home.packages = [
5 | (if config.deviceSpecific.isPhone then
6 | pkgs.okularMobile
7 | else
8 | pkgs.kdePackages.okular)
9 | ];
10 | xdg.configFile."okularpartrc".text = pkgs.my-lib.genIni {
11 | "Dlg Accessibility" = {
12 | RecolorBackground = base00;
13 | RecolorForeground = base05;
14 | };
15 | "Document" = {
16 | ChangeColors = true;
17 | PaperColor = base00;
18 | RenderMode = "Recolor";
19 | };
20 | "Main View" = { ShowLeftPanel = false; };
21 | PageView = {
22 | BackgroundColor = base00;
23 | UseCustomBackgroundColor = true;
24 | };
25 | };
26 | };
27 | }
28 |
--------------------------------------------------------------------------------
/profiles/applications/packages.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, inputs, ... }: {
2 | home-manager.users.balsoft.home.packages = with pkgs;
3 | [
4 | # Internet
5 | wget
6 | curl
7 |
8 | eza
9 | jq
10 |
11 | file
12 | ] ++ lib.optionals config.deviceSpecific.goodMachine [
13 | # steamcmd
14 | # steam
15 | haskellPackages.hoogle
16 | nixfmt-rfc-style
17 | # nil
18 | nixpkgs-fmt
19 | stdman
20 | libqalculate
21 | # Messaging
22 | libnotify
23 | # Audio/Video
24 | mpv
25 | vlc
26 | pavucontrol
27 | # Tools
28 | zip
29 | kdePackages.plasma-systemmonitor
30 | wl-clipboard
31 | grim
32 | slurp
33 | abiword
34 | gnumeric
35 | gcalcli
36 | xdg-utils
37 | lambda-launcher
38 | nix-patch
39 | gopass
40 | # papirus-icon-theme
41 | kdePackages.breeze-icons
42 | shellcheck
43 | proselint
44 | ripgrep
45 | bat
46 | jless
47 |
48 | pandoc
49 | sioyek
50 |
51 | nil
52 | ];
53 | }
54 |
--------------------------------------------------------------------------------
/profiles/applications/qmlkonsole.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | environment.systemPackages = [ pkgs.plasma5Packages.qmlkonsole ];
3 | defaultApplications.term = {
4 | cmd = "${pkgs.plasma5Packages.qmlkonsole}/bin/qmlkonsole";
5 | desktop = "org.kde.qmlkonsole";
6 | };
7 | environment.variables.COLORSCHEMES_DIRS = pkgs.writeTextFile {
8 | name = "qmlkonsole-generated-theme";
9 | destination = "/Generated.colorscheme";
10 | text = with pkgs.my-lib;
11 | with (thmDec config.themes.colors);
12 | let dim = mulDec 0.66;
13 | in lib.generators.toGitINI {
14 | General.Description = "Generated Color Scheme";
15 | Background = {
16 | Bold = false;
17 | Color = base00;
18 | };
19 | BackgroundIntense = {
20 | Bold = false;
21 | Color = base03;
22 | };
23 | Color0 = {
24 | Bold = false;
25 | Color = base00;
26 | };
27 | Color1 = {
28 | Bold = false;
29 | Color = base08;
30 | };
31 | Color2 = {
32 | Bold = false;
33 | Color = base0B;
34 | };
35 | Color3 = {
36 | Bold = false;
37 | Color = base0A;
38 | };
39 | Color4 = {
40 | Bold = false;
41 | Color = base0D;
42 | };
43 | Color5 = {
44 | Bold = false;
45 | Color = base0E;
46 | };
47 | Color6 = {
48 | Bold = false;
49 | Color = base0C;
50 | };
51 | Color7 = {
52 | Bold = false;
53 | Color = base07;
54 | };
55 | Foreground = {
56 | Bold = false;
57 | Color = base05;
58 | };
59 | Color0Faint = {
60 | Bold = false;
61 | Color = dim base00;
62 | };
63 | Color1Faint = {
64 | Bold = false;
65 | Color = dim base08;
66 | };
67 | Color2Faint = {
68 | Bold = false;
69 | Color = dim base0B;
70 | };
71 | Color3Faint = {
72 | Bold = false;
73 | Color = dim base0A;
74 | };
75 | Color4Faint = {
76 | Bold = false;
77 | Color = dim base0D;
78 | };
79 | Color5Faint = {
80 | Bold = false;
81 | Color = dim base0E;
82 | };
83 | Color6Faint = {
84 | Bold = false;
85 | Color = dim base0C;
86 | };
87 | Color7Faint = {
88 | Bold = false;
89 | Color = dim base07;
90 | };
91 | ForegroundFaint = {
92 | Bold = false;
93 | Color = dim base05;
94 | };
95 | Color0Intense = {
96 | Bold = false;
97 | Color = base00;
98 | };
99 | Color1Intense = {
100 | Bold = false;
101 | Color = base08;
102 | };
103 | Color2Intense = {
104 | Bold = false;
105 | Color = base0B;
106 | };
107 | Color3Intense = {
108 | Bold = false;
109 | Color = base0A;
110 | };
111 | Color4Intense = {
112 | Bold = false;
113 | Color = base0D;
114 | };
115 | Color5Intense = {
116 | Bold = false;
117 | Color = base0E;
118 | };
119 | Color6Intense = {
120 | Bold = false;
121 | Color = base0C;
122 | };
123 | Color7Intense = {
124 | Bold = false;
125 | Color = base07;
126 | };
127 | ForegroundIntense = {
128 | Bold = false;
129 | Color = base05;
130 | };
131 | };
132 | };
133 | home-manager.users.balsoft = {
134 | xdg.configFile.qmlkonsolerc.text = lib.generators.toGitINI {
135 | General = {
136 | colorScheme = "Generated";
137 | fontFamily = config.themes.fonts.mono.family;
138 | fontSize = config.themes.fonts.mono.size;
139 | };
140 | };
141 | };
142 | }
143 |
--------------------------------------------------------------------------------
/profiles/applications/slack.nix:
--------------------------------------------------------------------------------
1 | { pkgs, ... }: {
2 | home-manager.users.balsoft.wayland.windowManager.sway.config.startup = [{
3 | command = toString (pkgs.writeShellScript "slack" ''
4 | librewolf https://tweag.slack.com &
5 | sleep 5
6 | swaymsg '[title=Slack.*] move to workspace '
7 | swaymsg '[title=Slack.*] fullscreen disable'
8 | librewolf https://calendar.google.com
9 | '');
10 | }];
11 | }
12 |
--------------------------------------------------------------------------------
/profiles/applications/sylpheed.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, ... }: {
2 | home-manager.users.balsoft = {
3 | home.packages = [ pkgs.sylpheed ];
4 | wayland.windowManager.sway.config.startup = [
5 | {
6 | command = "${pkgs.sylpheed}/bin/sylpheed";
7 | }
8 | ];
9 | home.activation."accountrc" = {
10 | data = ''
11 | $DRY_RUN_CMD rm -f ~/.sylpheed-2.0/accountrc
12 | $DRY_RUN_CMD cp ~/.sylpheed-2.0/accountrc.home ~/.sylpheed-2.0/accountrc
13 | $DRY_RUN_CMD chmod 700 ~/.sylpheed-2.0/accountrc
14 | '';
15 | before = [ ];
16 | after = [ "linkGeneration" ];
17 | };
18 | home.file.".sylpheed-2.0/accountrc.home".text = ''
19 | [Account: 1]
20 | account_name=balsoft@balsoft.ru
21 | is_default=1
22 | name=Alexander Bantyev
23 | address=balsoft@balsoft.ru
24 | organization=
25 | protocol=3
26 | receive_server=balsoft.ru
27 | smtp_server=balsoft.ru
28 | nntp_server=
29 | use_nntp_auth=0
30 | user_id=balsoft@balsoft.ru
31 | password=${config.secrets.mail.password or ""}
32 | inbox=inbox
33 | use_apop_auth=0
34 | remove_mail=1
35 | message_leave_time=7
36 | get_all_mail=0
37 | enable_size_limit=0
38 | size_limit=1024
39 | filter_on_receive=1
40 | imap_check_inbox_only=0
41 | imap_filter_inbox_on_receive=0
42 | imap_auth_method=0
43 | max_nntp_articles=300
44 | receive_at_get_all=1
45 | add_date=1
46 | generate_msgid=1
47 | add_custom_header=0
48 | use_smtp_auth=1
49 | smtp_auth_method=0
50 | smtp_user_id=
51 | smtp_password=
52 | pop_before_smtp=0
53 | signature_type=2
54 | signature_path=/home/balsoft/.signature
55 | signature_name=Default
56 | signature_name2=Russian
57 | signature_name3=Short
58 | signature_name4=
59 | signature_name5=
60 | signature_name6=
61 | signature_name7=
62 | signature_name8=
63 | signature_name9=
64 | signature_name10=
65 | signature_text=Александр Бантьев /Alexander Bantyev/ aka balsoft\n\nNix DevOPS/SRE at serokell.io\n\n\n\n\nmatrix://@balsoft:balsoft.ru \n(https://matrix.to/#/@balsoft:balsoft.ru)\nhttps://t.me/balsoft\nhttps://github.com/balsoft\n
66 | signature_text2=Александр Бантьев (balsoft)\n\nNix DevOPS/SRE в serokell.io\n\n\n\n\nmatrix://@balsoft:balsoft.ru \n(https://matrix.to/#/@balsoft:balsoft.ru)\nhttps://t.me/balsoft\nhttps://github.com/balsoft\n
67 | signature_text3=Alexander Bantyev aka balsoft
68 | signature_text4=
69 | signature_text5=
70 | signature_text6=
71 | signature_text7=
72 | signature_text8=
73 | signature_text9=
74 | signature_text10=
75 | signature_before_quote=0
76 | set_autocc=0
77 | auto_cc=
78 | set_autobcc=0
79 | auto_bcc=
80 | set_autoreplyto=0
81 | auto_replyto=
82 | default_sign=1
83 | default_encrypt=0
84 | encrypt_reply=1
85 | encrypt_to_self=1
86 | ascii_armored=0
87 | clearsign=0
88 | sign_key=0
89 | sign_key_id=
90 | ssl_pop=0
91 | ssl_imap=2
92 | ssl_nntp=0
93 | ssl_smtp=2
94 | use_nonblocking_ssl=1
95 | use_socks=0
96 | use_socks_for_recv=1
97 | use_socks_for_send=1
98 | socks_type=1
99 | proxy_host=
100 | proxy_port=1080
101 | use_proxy_auth=0
102 | proxy_name=
103 | proxy_pass=
104 | set_smtpport=0
105 | smtp_port=25
106 | set_popport=0
107 | pop_port=110
108 | set_imapport=0
109 | imap_port=143
110 | set_nntpport=0
111 | nntp_port=119
112 | set_domain=0
113 | domain=
114 | imap_directory=
115 | imap_clear_cache_on_exit=0
116 | set_sent_folder=0
117 | sent_folder=
118 | set_draft_folder=0
119 | draft_folder=
120 | set_queue_folder=0
121 | queue_folder=
122 | set_trash_folder=0
123 | trash_folder=
124 | '';
125 | };
126 | }
127 |
--------------------------------------------------------------------------------
/profiles/applications/vscodium/default.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, inputs, ... }:
2 | let
3 | EDITOR = pkgs.writeShellScript "codium-editor" ''
4 | source "/etc/profiles/per-user/balsoft/etc/profile.d/hm-session-vars.sh"
5 | NIX_OZONE_WL=1 \
6 | exec \
7 | ${config.home-manager.users.balsoft.programs.vscode.package}/bin/codium \
8 | --enable-features=UseOzonePlatform \
9 | --ozone-platform=wayland \
10 | -w -n \
11 | "$@"
12 | '';
13 | codium-wayland = pkgs.buildEnv {
14 | name = "codium-wayland";
15 | paths = [
16 | (pkgs.writeShellScriptBin "codium-wayland" ''
17 | NIX_OZONE_WL=1 \
18 | exec \
19 | ${config.home-manager.users.balsoft.programs.vscode.package}/bin/codium \
20 | --enable-features=UseOzonePlatform \
21 | --ozone-platform=wayland \
22 | "$@"
23 | '')
24 | (pkgs.makeDesktopItem {
25 | name = "codium-wayland";
26 | desktopName = "VSCodium (Wayland)";
27 | exec = "codium-wayland";
28 | icon = "code";
29 | categories = [ "Utility" "TextEditor" "Development" "IDE" ];
30 | mimeTypes = [ "text/plain" "inode/directory" ];
31 | extraConfig = {
32 | StartupNotify = "true";
33 | StartupWMClass = "vscodium";
34 | };
35 | })
36 | ];
37 | };
38 |
39 | custom-extensions = import ./extensions.nix {
40 | inherit (pkgs.vscode-utils) buildVscodeMarketplaceExtension;
41 | };
42 | in {
43 | environment.systemPackages = [ codium-wayland ];
44 |
45 | defaultApplications.editor = {
46 | cmd = "${EDITOR}";
47 | desktop = "codium-wayland";
48 | };
49 | home-manager.users.balsoft = {
50 | programs.vscode = {
51 | enable = true;
52 | package = pkgs.vscodium;
53 |
54 | mutableExtensionsDir = true;
55 | extensions =
56 | with inputs.nix-vscode-marketplace.packages.${pkgs.system}.vscode;
57 | with inputs.nix-vscode-marketplace.packages.${pkgs.system}.open-vsx;
58 | with pkgs.vscode-extensions;
59 | [
60 | kahole.magit
61 |
62 | cab404.vscode-direnv
63 |
64 | (pkgs.callPackage ./theme.nix { } config.themes.colors)
65 |
66 | vscodevim.vim
67 |
68 | matklad.rust-analyzer
69 | redhat.vscode-yaml
70 | jnoortheen.nix-ide
71 | dhall.dhall-lang
72 | hashicorp.terraform
73 | timonwong.shellcheck
74 | bungcip.better-toml
75 | haskell.haskell
76 | justusadam.language-haskell
77 | ms-python.python
78 | github.vscode-pull-request-github
79 | eamodio.gitlens
80 | llvm-vs-code-extensions.vscode-clangd
81 | stkb.rewrap
82 | shardulm94.trailing-spaces
83 | meraymond.idris-vscode
84 | ocamllabs.ocaml-platform
85 | bierner.markdown-mermaid
86 | ] ++ pkgs.lib.concatMap builtins.attrValues
87 | (builtins.attrValues custom-extensions);
88 |
89 | userSettings = {
90 | "update.mode" = "none";
91 | "[nix]"."editor.tabSize" = 2;
92 | "workbench.colorTheme" = "Balsoft's generated theme";
93 | "terminal.integrated.profiles.linux".bash.path =
94 | "/run/current-system/sw/bin/bash";
95 | "terminal.integrated.defaultProfile.linux" = "bash";
96 | "editor.fontFamily" = "IBM Plex Mono";
97 | "nix.formatterPath" = "nixfmt";
98 | "git.autofetch" = true;
99 | "redhat.telemetry.enabled" = false;
100 | "security.workspace.trust.untrustedFiles" = "open";
101 | "window.menuBarVisibility" = "toggle";
102 | "vim.useSystemClipboard" = true;
103 | "haskell.manageHLS" = "PATH";
104 | "extensions.autoCheckUpdates" = false;
105 | "extensions.autoUpdate" = false;
106 | };
107 | keybindings = [{
108 | key = "ctrl+shift+r";
109 | command = "workbench.action.tasks.runTask";
110 | when = "textInputFocus";
111 | }];
112 | };
113 | };
114 | }
115 |
--------------------------------------------------------------------------------
/profiles/applications/vscodium/extensions.nix:
--------------------------------------------------------------------------------
1 | { buildVscodeMarketplaceExtension }: {
2 | dhall.vscode-dhall-lsp-server = buildVscodeMarketplaceExtension {
3 | mktplcRef = {
4 | publisher = "dhall";
5 | name = "vscode-dhall-lsp-server";
6 | version = "0.0.4";
7 | sha256 = "sha256-WopWzMCtiiLrx3pHNiDMZYFdjS359vu3T+6uI5A+Nv4=";
8 | };
9 | };
10 | gpoore.codebraid-preview = buildVscodeMarketplaceExtension {
11 | mktplcRef = {
12 | publisher = "gpoore";
13 | name = "codebraid-preview";
14 | version = "0.8.0";
15 | sha256 = "sha256-bw/uzdbLDREwhd0PHOD+Ref3UdaYlkhegsUhkTX1WlI=";
16 | };
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/profiles/bluetooth.nix:
--------------------------------------------------------------------------------
1 | {
2 | pkgs,
3 | lib,
4 | config,
5 | ...
6 | }:
7 | {
8 | hardware.bluetooth = {
9 | enable = true;
10 | package = pkgs.bluez;
11 | };
12 |
13 | systemd.services.bluetooth.serviceConfig.ExecStart = lib.mkForce [
14 | ""
15 | "${pkgs.bluez}/libexec/bluetooth/bluetoothd -f /etc/bluetooth/main.conf -E"
16 | ];
17 |
18 | persist.state.directories = [ "/var/lib/bluetooth" ];
19 | home-manager.users.balsoft =
20 | let
21 | headphones = "80:99:E7:8B:AE:D5";
22 | in
23 | {
24 | services.mpris-proxy.enable = true;
25 | programs.zsh.shellAliases = {
26 | "hpc" = "bluetoothctl connect ${headphones}";
27 | "hpd" = "bluetoothctl disconnect ${headphones}";
28 | };
29 |
30 | wayland.windowManager.sway.config.keybindings =
31 | let
32 | inherit (config.home-manager.users.balsoft.wayland.windowManager.sway.config)
33 | modifier
34 | ;
35 | in
36 | {
37 | "${modifier}+F2" = "exec bluetoothctl connect ${headphones}";
38 | "${modifier}+Shift+F2" = "exec bluetoothctl disconnect ${headphones}";
39 | };
40 | };
41 | }
42 |
--------------------------------------------------------------------------------
/profiles/boot.nix:
--------------------------------------------------------------------------------
1 | { lib, pkgs, config, ... }: {
2 | boot = {
3 | loader = {
4 | timeout = lib.mkForce 4;
5 | grub.enable = false;
6 | systemd-boot.enable = pkgs.system == "x86_64-linux";
7 | };
8 | kernelParams = [ "modeset" "nofb" "preempt=full" ]
9 | ++ lib.optionals (pkgs.system == "x86_64-linux") [
10 | "pti=off"
11 | "spectre_v2=off"
12 | ];
13 |
14 | kernelPackages = pkgs.linuxPackages_latest;
15 |
16 | consoleLogLevel = 3;
17 | kernel.sysctl."vm.swappiness" = 0;
18 | kernel.sysctl."kernel/sysrq" = 1;
19 | };
20 | persist.state.etcFiles = [ "machine-id" ];
21 | }
22 |
--------------------------------------------------------------------------------
/profiles/hardware.nix:
--------------------------------------------------------------------------------
1 | {
2 | hardware.enableRedistributableFirmware = true; # For some unfree drivers
3 | # systemd.services.systemd-udev-settle.enable = false;
4 | services.fwupd.enable = true;
5 | # sound.enable = true;
6 | services.fstrim.enable = true;
7 | }
8 |
--------------------------------------------------------------------------------
/profiles/network.nix:
--------------------------------------------------------------------------------
1 | { pkgs, lib, config, ... }:
2 | let
3 | localRanges = [{
4 | from = 1714;
5 | to = 1764;
6 | } # KDE connect
7 | ];
8 | in {
9 | networking = {
10 | networkmanager.enable = true;
11 | firewall = {
12 | enable = true;
13 | allowedTCPPorts = [ 13748 13722 5000 22 80 443 51820 ];
14 | interfaces.wlan0.allowedTCPPortRanges = localRanges;
15 | interfaces.wlan0.allowedUDPPortRanges = localRanges;
16 | interfaces.eth0.allowedUDPPortRanges = localRanges;
17 | interfaces.eth0.allowedTCPPortRanges = localRanges;
18 | };
19 | resolvconf.extraConfig = ''
20 | local_nameservers=""
21 | name_server_blacklist="0.0.0.0 127.0.0.1"
22 | resolv_conf_local_only=NO
23 | '';
24 | usePredictableInterfaceNames = false;
25 | hostName = config.device;
26 | };
27 |
28 | persist.state.directories = [ "/etc/NetworkManager/system-connections" ];
29 |
30 | networking.firewall.trustedInterfaces = [ "eth0" ];
31 | systemd.services.ModemManager.wantedBy =
32 | lib.optional (config.device == "T490s-Laptop") "network.target";
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/profiles/nix/default.nix:
--------------------------------------------------------------------------------
1 | { pkgs, lib, inputs, config, ... }: {
2 | nix = {
3 | nixPath = lib.mkForce [ "self=/etc/self/compat" "nixpkgs=/etc/nixpkgs" ];
4 | registry.self.flake = inputs.self;
5 | registry.np.flake = inputs.nixpkgs;
6 |
7 | nrBuildUsers = config.nix.settings.max-jobs;
8 |
9 | optimise.automatic = true;
10 |
11 | settings = {
12 | use-xdg-base-directories = true;
13 | builders-use-substitutes = true;
14 | flake-registry = "${inputs.flake-registry}/flake-registry.json";
15 | experimental-features = [ "nix-command" "flakes" ];
16 | trusted-users = [ "root" "balsoft" "@wheel" ];
17 | trusted-public-keys = [
18 | "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
19 | "serokell-1:aIojg2Vxgv7MkzPJoftOO/I8HKX622sT+c0fjnZBLj0="
20 | ];
21 | substituters = [ "https://cache.nixos.org" ];
22 | trusted-substituters = [
23 | "s3://serokell-private-cache?endpoint=s3.eu-central-1.wasabisys.com&profile=serokell-private-cache-wasabi"
24 | ];
25 | };
26 | buildMachines = [
27 | # tweag remote builder
28 | {
29 | hostName = "build01.tweag.io";
30 | maxJobs = 24;
31 | sshUser = "nix";
32 | sshKey = "/root/.ssh/id_ed25519";
33 | system = "x86_64-linux";
34 | supportedFeatures = [ "benchmark" "big-parallel" "kvm" ];
35 | }
36 | {
37 | hostName = "build02.tweag.io";
38 | maxJobs = 24;
39 | sshUser = "nix";
40 | sshKey = "/root/.ssh/id_ed25519";
41 | systems = [ "aarch64-darwin" "x86_64-darwin" ];
42 | }
43 | ];
44 | };
45 |
46 | persist.state.directories = [ "/home/balsoft/.local/share/nix" ];
47 |
48 | environment.etc.nixpkgs.source = inputs.nixpkgs;
49 | environment.etc.self.source = inputs.self;
50 | }
51 |
--------------------------------------------------------------------------------
/profiles/opengl.nix:
--------------------------------------------------------------------------------
1 | { pkgs, ... }: {
2 | hardware.graphics.enable = true;
3 | # hardware.opengl.driSupport = true;
4 | hardware.graphics.enable32Bit = true; # For steam
5 | hardware.graphics.package = pkgs.mesa;
6 | }
7 |
--------------------------------------------------------------------------------
/profiles/power.nix:
--------------------------------------------------------------------------------
1 | {
2 | services.upower.enable = true;
3 |
4 | services.logind.lidSwitchExternalPower = "ignore";
5 |
6 | services.logind.extraConfig = "HandlePowerKey=suspend";
7 | }
8 |
--------------------------------------------------------------------------------
/profiles/security/pass-secret-service.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | home-manager.users.balsoft = {
3 | services.pass-secret-service.enable = true;
4 |
5 | systemd.user.services.pass-secret-service = {
6 | Service = {
7 | Type = "dbus";
8 | Environment = [ "GPG_TTY=/dev/tty1" "DISPLAY=:0" ];
9 | BusName = "org.freedesktop.secrets";
10 | };
11 | Unit = rec {
12 | Wants = [ "gpg-agent.service" ];
13 | After = Wants;
14 | PartOf = [ "graphical-session-pre.target" ];
15 | };
16 | };
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/profiles/security/user.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | users.mutableUsers = false;
3 | users.users.balsoft = {
4 | isNormalUser = true;
5 | extraGroups = [
6 | "sudo"
7 | "wheel"
8 | "networkmanager"
9 | "disk"
10 | "dbus"
11 | "audio"
12 | "docker"
13 | "sound"
14 | "pulse"
15 | "adbusers"
16 | "input"
17 | "libvirtd"
18 | "vboxusers"
19 | "wireshark"
20 | "lp"
21 | "scanner"
22 | "feedbackd"
23 | ];
24 | description = "Александр Бантьев";
25 | uid = 1000;
26 | password = "";
27 | };
28 |
29 | systemd.services."user@" = { serviceConfig = { Restart = "always"; }; };
30 |
31 | home-manager.users.balsoft = {
32 | systemd.user.services.polkit-agent = {
33 | Unit = {
34 | Description = "Run polkit authentication agent";
35 | X-RestartIfChanged = true;
36 | };
37 |
38 | Install.WantedBy = [ "sway-session.target" ];
39 |
40 | Service = { ExecStart = "${pkgs.mate.mate-polkit}/libexec/polkit-mate-authentication-agent-1"; };
41 | };
42 | };
43 |
44 |
45 | services.getty.autologinUser = "balsoft";
46 |
47 | home-manager.useUserPackages = true;
48 | }
49 |
--------------------------------------------------------------------------------
/profiles/security/vlock.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | environment.loginShellInit = lib.mkBefore ''
3 | [[ "$(tty)" == /dev/tty? ]] && sudo /run/current-system/sw/bin/lock this
4 | '';
5 |
6 | environment.systemPackages = [
7 | (pkgs.writeShellScriptBin "lock" ''
8 | set -euo pipefail
9 | if [[ "$1" == this ]]
10 | then args="-s"
11 | else args="-san"
12 | fi
13 | ${lib.optionalString (config.deviceSpecific.isLaptop)
14 | ''USER=balsoft ${pkgs.vlock}/bin/vlock "$args"''}
15 | '')
16 | ];
17 |
18 | security.sudo = {
19 | enable = true;
20 | extraConfig = ''
21 | balsoft ALL = (root) NOPASSWD: /run/current-system/sw/bin/lock
22 | balsoft ALL = (root) NOPASSWD: /run/current-system/sw/bin/lock this
23 | balsoft ALL = (root) NOPASSWD: ${pkgs.light}/bin/light -A 5
24 | balsoft ALL = (root) NOPASSWD: ${pkgs.light}/bin/light -U 5
25 | '';
26 | };
27 | }
28 |
--------------------------------------------------------------------------------
/profiles/security/yubikey.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }: {
2 | home-manager.users.balsoft = {
3 | home.activation.yubi = {
4 | data = ''
5 | mkdir -p .config/Yubico
6 | [ -f /home/balsoft/.config/Yubico/u2f_keys ] || (pamu2fcfg > /home/balsoft/.config/Yubico/u2f_keys)
7 | '';
8 | after = [ "linkGeneration" ];
9 | before = [ ];
10 | };
11 | };
12 |
13 | persist.state.directories = [ "/home/balsoft/.config/Yubico" ];
14 |
15 | security.pam.services = builtins.listToAttrs (builtins.map (name: {
16 | inherit name;
17 | value = { unixAuth = false; };
18 | }) [
19 | "chpasswd"
20 | "chsh"
21 | "groupadd"
22 | "groupdel"
23 | "groupmems"
24 | "groupmod"
25 | "i3lock"
26 | "i3lock-color"
27 | "login"
28 | "passwd"
29 | "polkit-1"
30 | "runuser"
31 | "runuser-l"
32 | "su"
33 | "sudo"
34 | "swaylock"
35 | "systemd-user"
36 | "useradd"
37 | "userdel"
38 | "usermod"
39 | "vlock"
40 | "xlock"
41 | "xscreensaver"
42 | ]);
43 |
44 | security.pam.u2f = {
45 | control = "sufficient";
46 | settings.cue = true;
47 | enable = true;
48 | };
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/profiles/servers/gitea.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, ... }:
2 | {
3 | services.gitea = {
4 | enable = false;
5 | appName = "code.balsoft.ru";
6 | settings.server = {
7 | HTTP_PORT = 6000;
8 | ROOT_URL = "https://code.balsoft.ru";
9 | DISABLE_REGISTRATION = true;
10 | COOKIE_SECURE = true;
11 | DOMAIN = "code.balsoft.ru";
12 | };
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/profiles/servers/home-assistant.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, inputs, ... }: {
2 | services.home-assistant = {
3 | enable = true;
4 | package = (pkgs.home-assistant.override {
5 | extraPackages = py: with py; [ aiohttp-cors zeroconf pycrypto ];
6 | }).overrideAttrs (_: {
7 | tests = [];
8 | doInstallCheck = false;
9 | });
10 | config = {
11 | homeassistant = {
12 | name = "Home";
13 | time_zone = "Europe/Moscow";
14 | latitude = 1;
15 | longitude = 1;
16 | elevation = 1;
17 | unit_system = "metric";
18 | temperature_unit = "C";
19 | };
20 | # Enable the frontend
21 | frontend = { };
22 | sonoff = {
23 | default_class = "light";
24 | };
25 | mobile_app = { };
26 | };
27 | };
28 | systemd.tmpfiles.rules = [
29 | "C /var/lib/hass/custom_components/sonoff - - - - ${inputs.sonoff-lan}/custom_components/sonoff"
30 | "Z /var/lib/hass 770 hass hass - -"
31 | ];
32 | services.nginx = {
33 | virtualHosts."hass.balsoft.ru" = {
34 | enableACME = true;
35 | forceSSL = true;
36 | extraConfig = ''
37 | proxy_buffering off;
38 | '';
39 | locations."/" = {
40 | proxyPass = "http://127.0.0.1:8123";
41 | proxyWebsockets = true;
42 | extraConfig = ''
43 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
44 | proxy_set_header Upgrade $http_upgrade;
45 | proxy_set_header Connection $connection_upgrade;
46 | '';
47 | };
48 | };
49 | };
50 | }
51 |
--------------------------------------------------------------------------------
/profiles/servers/irc.nix:
--------------------------------------------------------------------------------
1 | { ... }: {
2 | services.ergochat = {
3 | enable = true;
4 | settings = {
5 | accounts = {
6 | authentication-enabled = true;
7 | multiclient = {
8 | allowed-by-default = true;
9 | always-on = "opt-out";
10 | auto-away = "opt-out";
11 | enabled = true;
12 | };
13 | registration = {
14 | allow-before-connect = true;
15 | bcrypt-cost = 4;
16 | email-verification = { enabled = false; };
17 | enabled = true;
18 | throttling = {
19 | duration = "10m";
20 | enabled = true;
21 | max-attempts = 30;
22 | };
23 | };
24 | };
25 | channels = {
26 | default-modes = "+ntC";
27 | registration = { enabled = true; };
28 | };
29 | datastore = {
30 | autoupgrade = true;
31 | path = "/var/lib/ergo/ircd.db";
32 | };
33 | history = {
34 | autoreplay-on-join = 0;
35 | autoresize-window = "3d";
36 | channel-length = 2048;
37 | chathistory-maxmessages = 100;
38 | client-length = 256;
39 | enabled = true;
40 | restrictions = {
41 | expire-time = "1w";
42 | grace-period = "1h";
43 | query-cutoff = "none";
44 | };
45 | retention = {
46 | allow-individual-delete = false;
47 | enable-account-indexing = false;
48 | };
49 | tagmsg-storage = {
50 | default = false;
51 | whitelist = [ "+draft/react" "+react" ];
52 | };
53 | znc-maxmessages = 2048;
54 | };
55 | limits = {
56 | awaylen = 390;
57 | channellen = 64;
58 | identlen = 20;
59 | kicklen = 390;
60 | nicklen = 32;
61 | topiclen = 390;
62 | };
63 | network = { name = "balsoftnet"; };
64 | server = {
65 | casemapping = "permissive";
66 | check-ident = false;
67 | enforce-utf = true;
68 | forward-confirm-hostnames = false;
69 | ip-cloaking = { enabled = false; };
70 | ip-limits = {
71 | count = false;
72 | throttle = false;
73 | };
74 | listeners = { ":6667" = { }; };
75 | lookup-hostnames = false;
76 | max-sendq = "1M";
77 | name = "balsoft.ru";
78 | relaymsg = { enabled = false; };
79 | };
80 | };
81 | };
82 | services.thelounge = {
83 | enable = true;
84 | extraConfig = {
85 | host = "localhost";
86 | reverseProxy = true;
87 | lockNetwork = true;
88 | defaults = {
89 | host = "localhost";
90 | name = "balsoftnet";
91 | port = 6667;
92 | tls = false;
93 | nick = "user%%%";
94 | leaveMessage = "<3";
95 | join = "#klananas";
96 | };
97 | };
98 | port = 9857;
99 | public = true;
100 | };
101 | services.nginx.virtualHosts."chat.balsoft.ru" = {
102 | forceSSL = true;
103 | enableACME = true;
104 | locations."/".proxyPass = "http://localhost:9857";
105 | basicAuthFile = "/var/lib/chat.passwd";
106 | };
107 | }
108 |
--------------------------------------------------------------------------------
/profiles/servers/jitsi.nix:
--------------------------------------------------------------------------------
1 | { config, ... }: {
2 | services.jitsi-meet = {
3 | enable = true;
4 | hostName = "meet.balsoft.ru";
5 | };
6 |
7 | services.nginx.virtualHosts.${config.services.jitsi-meet.hostName} = {
8 | enableACME = true;
9 | forceSSL = true;
10 | basicAuthFile = "/var/lib/jitsi-auth";
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/profiles/servers/mailserver.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, inputs, ... }:
2 | let module = toString inputs.simple-nixos-mailserver;
3 | in {
4 | imports = [ module ];
5 | secrets.mailserver = {
6 | owner = "dovecot2:dovecot2";
7 | services = [ "dovecot2" ];
8 | };
9 | secrets.mailserver-mastodon = {
10 | owner = "dovecot2:dovecot2";
11 | services = [ "dovecot2" ];
12 | };
13 | services.postfix = {
14 | dnsBlacklists = [
15 | "all.s5h.net"
16 | "b.barracudacentral.org"
17 | "bl.spamcop.net"
18 | "blacklist.woody.ch"
19 | # "bogons.cymru.com"
20 | # "cbl.abuseat.org"
21 | # "combined.abuse.ch"
22 | # "db.wpbl.info"
23 | # "dnsbl-1.uceprotect.net"
24 | # "dnsbl-2.uceprotect.net"
25 | # "dnsbl-3.uceprotect.net"
26 | # "dnsbl.anticaptcha.net"
27 | # "dnsbl.dronebl.org"
28 | # "dnsbl.inps.de"
29 | # "dnsbl.sorbs.net"
30 | # "dnsbl.spfbl.net"
31 | # "drone.abuse.ch"
32 | # "duinv.aupads.org"
33 | # "dul.dnsbl.sorbs.net"
34 | # "dyna.spamrats.com"
35 | # "dynip.rothen.com"
36 | # "http.dnsbl.sorbs.net"
37 | # "ips.backscatterer.org"
38 | # "ix.dnsbl.manitu.net"
39 | # "korea.services.net"
40 | # "misc.dnsbl.sorbs.net"
41 | # "noptr.spamrats.com"
42 | # "orvedb.aupads.org"
43 | # "pbl.spamhaus.org"
44 | # "proxy.bl.gweep.ca"
45 | # "psbl.surriel.com"
46 | # "relays.bl.gweep.ca"
47 | # "relays.nether.net"
48 | # "sbl.spamhaus.org"
49 | # "singular.ttk.pte.hu"
50 | # "smtp.dnsbl.sorbs.net"
51 | # "socks.dnsbl.sorbs.net"
52 | # "spam.abuse.ch"
53 | # "spam.dnsbl.anonmails.de"
54 | # "spam.dnsbl.sorbs.net"
55 | # "spam.spamrats.com"
56 | # "spambot.bls.digibase.ca"
57 | # "spamrbl.imp.ch"
58 | # "spamsources.fabel.dk"
59 | # "ubl.lashback.com"
60 | # "ubl.unsubscore.com"
61 | # "virus.rbl.jp"
62 | # "web.dnsbl.sorbs.net"
63 | # "wormrbl.imp.ch"
64 | # "xbl.spamhaus.org"
65 | # "z.mailspike.net"
66 | # "zen.spamhaus.org"
67 | # "zombie.dnsbl.sorbs.net"
68 | ];
69 | dnsBlacklistOverrides = ''
70 | balsoft.ru OK
71 | 192.168.0.0/16 OK
72 | ${lib.concatMapStringsSep "\n" (machine: "${machine}.lan OK")
73 | (builtins.attrNames inputs.self.nixosConfigurations)}
74 | '';
75 | };
76 | services.dovecot2 = {
77 | mailPlugins.globally.enable = [ "virtual" ];
78 | extraConfig = ''
79 | namespace {
80 | prefix = virtual.
81 | separator = .
82 | location = virtual:~/Maildir/virtual
83 | }
84 | '';
85 | };
86 | systemd.tmpfiles.rules = [
87 | "d /var/vmail/Maildir 700 virtualMail virtualMail - -"
88 | "d /var/vmail/Maildir/virtual 700 virtualMail virtualMail - -"
89 | "d /var/vmail/Maildir/virtual/all 700 virtualMail virtualMail - -"
90 | "d /var/vmail/Maildir/virtual/INBOX 700 virtualMail virtualMail - -"
91 | "L+ /var/vmail/Maildir/virtual/all/dovecot-virtual - - - - ${
92 | pkgs.writeText "virtual.all" ''
93 | *
94 | all
95 | ''
96 | }"
97 | "L+ /var/vmail/Maildir/virtual/INBOX/dovecot-virtual - - - - ${
98 | pkgs.writeText "virtual.INBOX" ''
99 | virtual.all
100 | inthread refs x-mailbox INBOX
101 | ''
102 | }"
103 | ];
104 | mailserver = {
105 | enable = true;
106 | fqdn = "balsoft.ru";
107 | domains = [ "balsoft.ru" ];
108 | mailboxes = {
109 | Trash = {
110 | auto = "no";
111 | specialUse = "Trash";
112 | };
113 | Junk = {
114 | auto = "subscribe";
115 | specialUse = "Junk";
116 | };
117 | Drafts = {
118 | auto = "subscribe";
119 | specialUse = "Drafts";
120 | };
121 | Sent = {
122 | auto = "subscribe";
123 | specialUse = "Sent";
124 | };
125 | };
126 | loginAccounts = {
127 | "balsoft@balsoft.ru" = {
128 | aliases = [
129 | "balsoft"
130 | "admin@balsoft.ru"
131 | "patches"
132 | "patches@balsoft.ru"
133 | "issues"
134 | "issues@balsoft.ru"
135 | "admin"
136 | "root@balsoft.ru"
137 | "root"
138 | "paypal@balsoft.ru"
139 | "paypal"
140 | ];
141 | hashedPasswordFile = config.secrets.mailserver.decrypted;
142 | sieveScript = ''
143 | if header :is "X-GitHub-Sender" "serokell-bot" {
144 | discard;
145 | stop;
146 | }
147 | '';
148 | };
149 | "mastodon@balsoft.ru" = {
150 | aliases = [ "mastodon" ];
151 | hashedPasswordFile = config.secrets.mailserver-mastodon.decrypted;
152 | };
153 | };
154 | localDnsResolver = false;
155 | certificateScheme = "manual";
156 | certificateFile = "/var/lib/acme/balsoft.ru/fullchain.pem";
157 | keyFile = "/var/lib/acme/balsoft.ru/key.pem";
158 | enableImap = true;
159 | enableImapSsl = true;
160 | virusScanning = false;
161 | };
162 | }
163 |
--------------------------------------------------------------------------------
/profiles/servers/mastodon.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | secrets.email-mastodon = {
3 | owner = "mastodon:mastodon";
4 | encrypted = "/home/balsoft/.password-store/email/mastodon@balsoft.ru.gpg";
5 | services = [ "mastodon-web" ];
6 | };
7 | services.mastodon = {
8 | enable = true;
9 | configureNginx = true;
10 | localDomain = "social.balsoft.ru";
11 | smtp = {
12 | createLocally = false;
13 | fromAddress = "mastodon@balsoft.ru";
14 | user = "mastodon";
15 | host = "balsoft.ru";
16 | passwordFile = config.secrets.email-mastodon.decrypted;
17 | };
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/profiles/servers/matrix-synapse.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, ... }: {
2 | services.matrix-synapse = {
3 | enable = true;
4 | settings = {
5 | allow_guest_access = false;
6 | listeners = [{
7 | # bind_address = "0.0.0.0";
8 | port = 13748;
9 | resources = [
10 | {
11 | compress = true;
12 | names = [ "client" ];
13 | }
14 | {
15 | compress = false;
16 | names = [ "federation" ];
17 | }
18 | ];
19 | type = "http";
20 | tls = false;
21 | x_forwarded = true;
22 | }];
23 | public_baseurl = "https://balsoft.ru";
24 | server_name = "balsoft.ru";
25 | turn_uris =
26 | [ "turn:balsoft.ru?transport=udp" "turn:balsoft.ru?transport=tcp" ];
27 | # app_service_config_files =
28 | # [ config.secrets-envsubst.mautrix-telegram-registration.substituted ];
29 | allow_public_rooms_over_federation = true;
30 | };
31 | extraConfigFiles = [
32 | config.secrets-envsubst.coturn.substituted
33 | config.secrets-envsubst.matrix.substituted
34 | ];
35 | };
36 |
37 | services.postgresql.enable = true;
38 | services.postgresql.package = pkgs.postgresql_15;
39 |
40 | services.mautrix-telegram = {
41 | enable = true;
42 | environmentFile = toString config.secrets-envsubst.mautrix-telegram;
43 | settings = {
44 | appservice = {
45 | address = "http://localhost:29317";
46 | bot_avatar = "mxc://maunium.net/tJCRmUyJDsgRNgqhOgoiHWbX";
47 | id = "telegram";
48 | max_body_size = 1;
49 | port = 29317;
50 | };
51 | bridge = {
52 | alias_template = "tg_{groupname}";
53 | allow_matrix_login = true;
54 | bot_messages_as_notices = true;
55 | catch_up = true;
56 | command_prefix = "!tg";
57 | image_as_file_size = 10;
58 | max_document_size = 100;
59 | max_initial_member_sync = -1;
60 | max_telegram_delete = 10;
61 | permissions = {
62 | "*" = "relaybot";
63 | "@balsoft:balsoft.ru" = "admin";
64 | };
65 | plaintext_highlights = true;
66 | startup_sync = true;
67 | username_template = "tg_{userid}";
68 | relay_user_distinguishers = [ ];
69 | state_event_formats = {
70 | leave = "";
71 | name_change = "";
72 | };
73 | };
74 | homeserver = {
75 | address = "https://matrix.balsoft.ru";
76 | domain = "balsoft.ru";
77 | verify_ssl = true;
78 | };
79 | };
80 | };
81 |
82 | secrets-envsubst.mautrix-telegram = {
83 | secrets = [ "as_token" "hs_token" "api_id" "api_hash" "bot_token" ];
84 | template = ''
85 | MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=$as_token
86 | MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=$hs_token
87 | MAUTRIX_TELEGRAM_TELEGRAM_API_ID=$api_id
88 | MAUTRIX_TELEGRAM_TELEGRAM_API_HASH=$api_hash
89 | MAUTRIX_TELEGRAM_TELEGRAM_BOT_TOKEN=$bot_token
90 | '';
91 | };
92 |
93 | secrets-envsubst.mautrix-telegram-registration = {
94 | directory = "mautrix-telegram";
95 | secrets = [ "as_token" "hs_token" ];
96 | owner = "matrix-synapse";
97 | template = builtins.toJSON {
98 | as_token = "$as_token";
99 | hs_token = "$hs_token";
100 | id = "telegram";
101 | namespaces = {
102 | aliases = [{
103 | exclusive = true;
104 | regex = "#tg_.+:balsoft.ru";
105 | }];
106 | users = [{
107 | exclusive = true;
108 | regex = "@tg_.+:balsoft.ru";
109 | }];
110 | };
111 | rate_limited = false;
112 | sender_localpart = "telegrambot";
113 | url = "http://localhost:29317";
114 | };
115 | };
116 |
117 | systemd.services.mautrix-telegram.serviceConfig = {
118 | DynamicUser = lib.mkForce false;
119 | Restart = "always";
120 | RuntimeMaxSec = "1d";
121 | };
122 |
123 | systemd.services.mautrix-telegram.serviceConfig.User = "mautrix-telegram";
124 |
125 | users.users.mautrix-telegram = {
126 | group = "mautrix-telegram";
127 | isSystemUser = true;
128 | };
129 |
130 | users.groups.mautrix-telegram = { };
131 |
132 | users.users.matrix-synapse.name = lib.mkForce "matrix-synapse";
133 |
134 | services.coturn = {
135 | enable = true;
136 | use-auth-secret = true;
137 | static-auth-secret-file = config.secrets.coturn.decrypted;
138 | no-tls = true;
139 | realm = "balsoft.ru";
140 | extraConfig = ''
141 | external-ip=94.25.150.197
142 |
143 | denied-peer-ip=10.0.0.0-10.255.255.255
144 | denied-peer-ip=192.168.0.0-192.168.255.255
145 | denied-peer-ip=172.16.0.0-172.31.255.255
146 |
147 | denied-peer-ip=0.0.0.0-0.255.255.255
148 | denied-peer-ip=100.64.0.0-100.127.255.255
149 | denied-peer-ip=127.0.0.0-127.255.255.255
150 | denied-peer-ip=169.254.0.0-169.254.255.255
151 | denied-peer-ip=192.0.0.0-192.0.0.255
152 | denied-peer-ip=192.0.2.0-192.0.2.255
153 | denied-peer-ip=192.88.99.0-192.88.99.255
154 | denied-peer-ip=198.18.0.0-198.19.255.255
155 | denied-peer-ip=198.51.100.0-198.51.100.255
156 | denied-peer-ip=203.0.113.0-203.0.113.255
157 | denied-peer-ip=240.0.0.0-255.255.255.255
158 |
159 | allowed-peer-ip=192.168.8.236
160 | '';
161 | };
162 |
163 | secrets.coturn = {
164 | encrypted =
165 | "/home/balsoft/.local/share/password-store/coturn/shared_secret.gpg";
166 | services = [ "coturn" ];
167 | owner = "turnserver:turnserver";
168 | };
169 | secrets-envsubst.coturn = {
170 | secrets = [ "shared_secret" ];
171 | services = [ "matrix-synapse" ];
172 | owner = "matrix-synapse:matrix-synapse";
173 | template = builtins.toJSON { turn_shared_secret = "$shared_secret"; };
174 | };
175 | secrets-envsubst.matrix = {
176 | secrets = [ "registration_shared_secret" ];
177 | services = [ "matrix-synapse" ];
178 | owner = "matrix-synapse:matrix-synapse";
179 | template = builtins.toJSON {
180 | registration_shared_secret = "$registration_shared_secret";
181 | };
182 | };
183 |
184 | networking.firewall = rec {
185 | allowedTCPPorts = [ 3478 5349 ];
186 | allowedUDPPorts = allowedTCPPorts;
187 | allowedUDPPortRanges = [{
188 | from = 49152;
189 | to = 65535;
190 | }];
191 | };
192 |
193 | }
194 |
--------------------------------------------------------------------------------
/profiles/servers/minidlna.nix:
--------------------------------------------------------------------------------
1 | {
2 | services.minidlna = {
3 | enable = true;
4 | announceInterval = 10;
5 | mediaDirs = [ "A,/var/lib/music" ];
6 | };
7 | }
8 |
--------------------------------------------------------------------------------
/profiles/servers/nextcloud.nix:
--------------------------------------------------------------------------------
1 | {
2 | config,
3 | pkgs,
4 | lib,
5 | ...
6 | }:
7 | {
8 | services.nextcloud = {
9 | enable = true;
10 | hostName = "nextcloud.balsoft.ru";
11 | config.adminpassFile = config.secrets.nextcloud.decrypted;
12 | config.dbtype = "sqlite";
13 | package = pkgs.nextcloud31;
14 | https = true;
15 | phpOptions.memory_limit = lib.mkForce "1G";
16 | settings = {
17 | "memories.exiftool" = "${lib.getExe pkgs.exiftool}";
18 | "memories.vod.ffmpeg" = "${lib.getExe pkgs.ffmpeg-headless}";
19 | "memories.vod.ffprobe" = "${pkgs.ffmpeg-headless}/bin/ffprobe";
20 | };
21 | phpExtraExtensions = all: [
22 | ((all.pdlib.override { dlib = (pkgs.dlib.override { blas = pkgs.openblas; }); }).overrideAttrs
23 | (oa: {
24 | buildInputs = oa.buildInputs ++ [
25 | pkgs.openblas
26 | pkgs.liblapack
27 | ];
28 | })
29 | )
30 | ];
31 | };
32 | services.phpfpm.pools.nextcloud.phpEnv.PATH =
33 | lib.mkForce "/run/wrappers/bin:${pkgs.ffmpeg-headless}/bin:${pkgs.exiftool}/bin:${pkgs.perl}/bin:/usr/bin:/bin";
34 | secrets.nextcloud = {
35 | owner = "nextcloud:nextcloud";
36 | services = [ "nextcloud-setup" ];
37 | };
38 | services.nginx.virtualHosts."nextcloud.balsoft.ru" = {
39 | enableACME = true;
40 | forceSSL = true;
41 | locations."/".proxyWebsockets = true;
42 | };
43 | }
44 |
--------------------------------------------------------------------------------
/profiles/servers/nginx.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, ... }: {
2 | services.nginx = {
3 | enable = true;
4 | appendHttpConfig = "charset utf-8;";
5 | virtualHosts = let
6 | default = {
7 | forceSSL = true;
8 | enableACME = true;
9 | };
10 | in {
11 | "balsoft.ru" = {
12 | default = true;
13 | locations."/" = {
14 | root = "/var/lib/balsoft.ru";
15 | index = "index.txt";
16 | };
17 | locations."/.well-known" = {
18 | proxyPass = "http://localhost:13748";
19 | };
20 | locations."/_matrix" = {
21 | proxyPass = "http://localhost:13748";
22 | };
23 | enableACME = true;
24 | forceSSL = true;
25 | };
26 | "code.balsoft.ru" = {
27 | locations."/" = { proxyPass = "http://localhost:6000"; };
28 | } // default;
29 | "cache.balsoft.ru" = {
30 | locations."/" = { proxyPass = "http://localhost:5000"; };
31 | } // default;
32 | "matrix.balsoft.ru" = {
33 | locations."/" = {
34 | proxyPass = "http://localhost:13748";
35 | };
36 | } // default;
37 | "share.balsoft.ru" = {
38 | locations."/" = { root = "/var/lib/share"; };
39 | } // default;
40 | "things.balsoft.ru" = {
41 | locations."/" = { root = "/nix/var/nix/profiles/per-user/nginx/random-things/www"; };
42 | } // default;
43 | };
44 | };
45 | security.acme.defaults.email = "balsoft@balsoft.ru";
46 | security.acme.acceptTerms = true;
47 | }
48 |
--------------------------------------------------------------------------------
/profiles/servers/ntfy.nix:
--------------------------------------------------------------------------------
1 | { config, ... }:
2 | {
3 | services.ntfy-sh = {
4 | enable = true;
5 | settings = {
6 | base-url = "https://ntfy.balsoft.ru";
7 | listen-http = "localhost:8111";
8 | behind-proxy = true;
9 | enable-login = true;
10 | auth-default-access = "read-write";
11 | };
12 | };
13 |
14 | secrets.ntfy_password = { owner = "nginx:nginx"; };
15 |
16 | services.nginx.virtualHosts."ntfy.balsoft.ru" = {
17 | enableACME = true;
18 | forceSSL = true;
19 |
20 | locations."/" = {
21 | proxyPass = "http://127.0.0.1:8111";
22 | proxyWebsockets = true;
23 | # basicAuthFile = config.secrets.ntfy_password.decrypted;
24 | };
25 | };
26 | }
27 |
--------------------------------------------------------------------------------
/profiles/servers/remapper.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }: {
2 | systemd.services.remapper = {
3 | path = [ pkgs.remapper ];
4 | script = "remapper";
5 | serviceConfig = {
6 | EnvironmentFile = config.secrets.remapper-telegram-token.decrypted;
7 | PrivateTmp = true;
8 | User = "remapper";
9 | Group = "remapper";
10 | };
11 | };
12 | users.users.remapper = {
13 | isSystemUser = true;
14 | group = "remapper";
15 | };
16 | users.groups.remapper = { };
17 | secrets.remapper-telegram-token = {
18 | owner = "remapper:remapper";
19 | services = [ "remapper" ];
20 | };
21 | }
--------------------------------------------------------------------------------
/profiles/servers/vsftpd.nix:
--------------------------------------------------------------------------------
1 | {
2 | services.vsftpd = {
3 | enable = true;
4 | anonymousUser = true;
5 | allowWriteableChroot = true;
6 | anonymousMkdirEnable = true;
7 | anonymousUploadEnable = true;
8 | writeEnable = true;
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/profiles/sound.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, ... }: {
2 | services.pulseaudio.enable = lib.mkForce false;
3 |
4 | security.rtkit.enable = true;
5 |
6 | services.pipewire = {
7 | enable = true;
8 | alsa.enable = true;
9 | pulse.enable = true;
10 | wireplumber.enable = true;
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/profiles/virtualisation.nix:
--------------------------------------------------------------------------------
1 | { config, lib, ... }: {
2 | # virtualisation.docker.enable = config.deviceSpecific.isHost;
3 | # virtualisation.libvirtd = {
4 | # enable = config.deviceSpecific.isHost;
5 | # allowedBridges = lib.mkForce [];
6 | # };
7 |
8 | persist.state.directories = [
9 | "/var/lib/docker"
10 | "/var/lib/libvirt"
11 | ];
12 |
13 | # virtualisation.spiceUSBRedirection.enable = true;
14 |
15 | # networking.nat = {
16 | # enable = true;
17 | # internalInterfaces = ["ve-+"];
18 | # };
19 | }
20 |
--------------------------------------------------------------------------------
/profiles/workspace/autoRun.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | home-manager.users.balsoft = {
3 | programs.nix-index.enable = true;
4 | };
5 |
6 | persist.cache.directories = [ "/home/balsoft/.cache/nix-index" ];
7 |
8 | environment.sessionVariables = {
9 | NIX_AUTO_RUN = "1";
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/profiles/workspace/aws.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | secrets.aws_credentials = {
3 | owner = "balsoft:users";
4 | services = [ ];
5 | };
6 |
7 | systemd.tmpfiles.rules = [ "L+ /root/.aws/credentials - - - - ${config.secrets.aws_credentials.decrypted}" ];
8 |
9 | environment.sessionVariables = {
10 | AWS_SHARED_CREDENTIALS_FILE = config.secrets.aws_credentials.decrypted;
11 | AWS_CONFIG_FILE = toString (pkgs.writeText "aws_config"
12 | (pkgs.my-lib.genIni { default.region = "eu-west-2"; }));
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/profiles/workspace/btop/default.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }: {
2 | defaultApplications = {
3 | monitor = {
4 | cmd =
5 | "${config.defaultApplications.term.cmd} -T btop -e ${pkgs.btop}/bin/btop";
6 | desktop = "alacritty";
7 | };
8 | };
9 | home-manager.users.balsoft = {
10 | programs.btop = {
11 | enable = true;
12 | settings = {
13 | vim_keys = true;
14 | proc_gradient = false;
15 | color_theme = "Default";
16 | update_ms = 500;
17 | presets = "cpu:0:default,proc:0:default cpu:0:default,mem:0:default";
18 | };
19 | };
20 | };
21 | }
22 |
--------------------------------------------------------------------------------
/profiles/workspace/cage.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | services.cage = {
3 | enable = true;
4 | program = config.defaultApplications.term.cmd;
5 | user = "balsoft";
6 | };
7 | }
8 |
--------------------------------------------------------------------------------
/profiles/workspace/copyq.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }: {
2 | environment.systemPackages = [ pkgs.copyq ];
3 | home-manager.users.balsoft = {
4 | wayland.windowManager.sway.config = {
5 | window.commands = [
6 | {
7 | criteria = { title = ".*CopyQ"; };
8 | command = "floating enable";
9 | }
10 | {
11 | criteria = { title = ".*CopyQ"; };
12 | command = "move position mouse";
13 | }
14 | ];
15 | startup = [{ command = "${pkgs.copyq}/bin/copyq"; }];
16 | };
17 |
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/profiles/workspace/cursor.nix:
--------------------------------------------------------------------------------
1 | { pkgs, lib, ... }: {
2 |
3 | environment.sessionVariables = {
4 | XCURSOR_PATH = lib.mkForce "/home/balsoft/.icons";
5 | };
6 |
7 | home-manager.users.balsoft = {
8 |
9 | home.pointerCursor = {
10 | package = pkgs.kdePackages.breeze;
11 | name = "breeze_cursors";
12 | size = 16;
13 | };
14 |
15 | home.file."/home/balsoft/.icons/default".source =
16 | "${lib.getBin pkgs.kdePackages.breeze}/share/icons/breeze_cursors";
17 |
18 |
19 | home.file."/home/balsoft/.icons/Breeze".source =
20 | "${lib.getBin pkgs.kdePackages.breeze}/share/icons/breeze_cursors";
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/profiles/workspace/direnv.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, inputs, ... }: {
2 | home-manager.users.balsoft = {
3 | programs.direnv = {
4 | enable = true;
5 | nix-direnv = {
6 | enable = true;
7 | };
8 | };
9 | };
10 | persist.state.directories =
11 | [ "/home/balsoft/.local/share/direnv" ];
12 | }
13 |
--------------------------------------------------------------------------------
/profiles/workspace/fonts.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, ... }: {
2 | fonts = {
3 | packages = with pkgs; [
4 | ibm-plex
5 | nerdfonts
6 | material-design-icons
7 | material-icons
8 | fira-code
9 | fira-code-symbols
10 | ];
11 | fontconfig = let fonts = config.themes.fonts;
12 | in {
13 | enable = lib.mkForce true;
14 | defaultFonts = {
15 | monospace = [ "${fonts.mono.family} ${toString fonts.mono.size}" ];
16 | sansSerif = [ "${fonts.main.family} ${toString fonts.main.size}" ];
17 | serif = [ "${fonts.serif.family} ${toString fonts.serif.size}" ];
18 | };
19 | };
20 | enableDefaultPackages = true;
21 | };
22 | themes.fonts = {
23 | main = {
24 | family = "IBM Plex Sans";
25 | size = lib.mkDefault 13;
26 | };
27 | serif = {
28 | family = "IBM Plex Serif";
29 | size = lib.mkDefault 13;
30 | };
31 | mono = {
32 | family = "IBM Plex Mono";
33 | size = lib.mkDefault 13;
34 | };
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/profiles/workspace/git.nix:
--------------------------------------------------------------------------------
1 | {
2 | home-manager.users.balsoft.programs = {
3 | git = {
4 | enable = true;
5 | userEmail = "balsoft@balsoft.ru";
6 | userName = "Alexander Bantyev";
7 | extraConfig.pull.rebase = true;
8 | ignores = [ ".envrc" ".direnv" ".shell.nix" ".balsoft" "*~" ".#*" "#*#" ];
9 | signing = {
10 | signByDefault = true;
11 | key = "687558B21E04FE92B255BED0E081FF12ADCB4AD5";
12 | };
13 | };
14 | lazygit = {
15 | enable = true;
16 | settings = { update.method = "never"; };
17 | };
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/profiles/workspace/gnome3/accounts.conf:
--------------------------------------------------------------------------------
1 | [Account account_1609508064_4]
2 | Provider=owncloud
3 | Identity=balsoft
4 | PresentationIdentity=balsoft@nextcloud.balsoft.ru
5 | CalendarEnabled=true
6 | ContactsEnabled=true
7 | DocumentsEnabled=true
8 | FilesEnabled=true
9 | Uri=https://nextcloud.balsoft.ru/
10 | AcceptSslErrors=false
11 |
12 | # [Account account_1634567009_0]
13 | # Provider=google
14 | # Identity=balsoft75@gmail.com
15 | # PresentationIdentity=balsoft75@gmail.com
16 | # MailEnabled=false
17 | # CalendarEnabled=true
18 | # ContactsEnabled=true
19 | # DocumentsEnabled=true
20 | # PhotosEnabled=true
21 | # FilesEnabled=true
22 | # PrintersEnabled=true
23 |
24 | [Account account_1635512206_0]
25 | Provider=google
26 | Identity=alexander.bantyev@tweag.io
27 | PresentationIdentity=alexander.bantyev@tweag.io
28 | MailEnabled=true
29 | CalendarEnabled=true
30 | ContactsEnabled=true
31 | DocumentsEnabled=true
32 | PhotosEnabled=true
33 | FilesEnabled=true
34 | PrintersEnabled=true
35 |
--------------------------------------------------------------------------------
/profiles/workspace/gnome3/default.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | environment.systemPackages = [ pkgs.pass-secret-service ];
3 |
4 | environment.gnome.excludePackages = [ pkgs.gnome-console pkgs.gnome.evince pkgs.gnome.eog ];
5 |
6 | services.dbus.packages = [ pkgs.pass-secret-service ];
7 | xdg.portal.extraPortals = [ pkgs.pass-secret-service ];
8 |
9 | services.gvfs.enable = true;
10 | services.geoclue2.enable = true;
11 |
12 | fileSystems = with config.persist;
13 | lib.mkIf enable (builtins.listToAttrs (map (name: {
14 | inherit name;
15 | value.options = [ "x-gvfs-hide" ];
16 | }) (state.directories ++ cache.directories ++ derivative.directories)));
17 |
18 | defaultApplications = {
19 | fm = {
20 | cmd = "${pkgs.nautilus}/bin/nautilus";
21 | desktop = "org.gnome.Nautilus";
22 | };
23 | archive = {
24 | cmd = "${pkgs.file-roller}/bin/file-roller";
25 | desktop = "org.gnome.FileRoller";
26 | };
27 | };
28 | home-manager.users.balsoft = {
29 |
30 | home.activation.gnome = ''
31 | $DRY_RUN_CMD mkdir -p "$XDG_CONFIG_HOME/goa-1.0"
32 | $DRY_RUN_CMD ln -sf ${
33 | ./accounts.conf
34 | } "$XDG_CONFIG_HOME/goa-1.0/accounts.conf"
35 | $DRY_RUN_CMD mkdir -p "$XDG_CONFIG_HOME/evolution/sources"
36 | $DRY_RUN_CMD ln -sf ${
37 | ./nextcloud.source
38 | } "$XDG_CONFIG_HOME/evolution/sources/nextcloud.source"
39 | '';
40 |
41 | home.packages = with pkgs; [ nautilus file-roller ];
42 |
43 | dconf.settings = {
44 | "org/gnome/nautilus/icon-view" = {
45 | captions = [ "size" "date_modified" "none" ];
46 | };
47 | "org/gnome/nautilus/list-view" = {
48 | default-column-order = [
49 | "name"
50 | "size"
51 | "type"
52 | "owner"
53 | "group"
54 | "permissions"
55 | "where"
56 | "date_modified"
57 | "date_modified_with_time"
58 | "date_accessed"
59 | "recency"
60 | "starred"
61 | "detailed_type"
62 | ];
63 | default-visible-columns = [ "name" "size" "date_modified" "starred" ];
64 | };
65 | "org/gnome/nautilus/preferences" = {
66 | default-folder-viewer = "list-view";
67 | executable-text-activation = "display";
68 | search-filter-time-type = "last_modified";
69 | search-view = "list-view";
70 | show-image-thumbnails = "always";
71 | thumbnail-limit = 10;
72 | };
73 |
74 | "org/gnome/evince/default" = { inverted-colors = true; };
75 |
76 | "org/gnome/maps" = {
77 | night-mode = true;
78 | transportation-type = "car";
79 | };
80 | };
81 | };
82 | }
83 |
--------------------------------------------------------------------------------
/profiles/workspace/gnome3/nextcloud.source:
--------------------------------------------------------------------------------
1 | [Data Source]
2 | DisplayName=balsoft@nextcloud.balsoft.ru
3 | Enabled=true
4 | Parent=
5 |
6 | [Authentication]
7 | Host=
8 | Method=none
9 | Port=0
10 | ProxyUid=system-proxy
11 | RememberPassword=true
12 | User=
13 | CredentialName=
14 | IsExternal=true
15 |
16 | [Collection]
17 | BackendName=webdav
18 | CalendarEnabled=true
19 | ContactsEnabled=true
20 | Identity=balsoft
21 | MailEnabled=true
22 | AllowSourcesRename=false
23 | CalendarUrl=
24 | ContactsUrl=
25 |
26 | [GNOME Online Accounts]
27 | AccountId=account_1609508064_4
28 | CalendarUrl=https://balsoft@nextcloud.balsoft.ru/remote.php/caldav/
29 | ContactsUrl=https://balsoft@nextcloud.balsoft.ru/remote.php/carddav/
30 | Name=
31 | Address=
32 |
--------------------------------------------------------------------------------
/profiles/workspace/gpg.nix:
--------------------------------------------------------------------------------
1 | { pkgs, lib, config, ... }: {
2 | services.pcscd.enable = true;
3 | services.udev.packages = [ pkgs.yubikey-personalization ];
4 |
5 | persist.derivative.directories = [ "/home/balsoft/.local/share/gnupg" ];
6 |
7 | home-manager.users.balsoft = {
8 | services.gpg-agent = {
9 | enable = true;
10 | enableSshSupport = true;
11 | pinentry.package = pkgs.pinentry-qt;
12 | };
13 |
14 | systemd.user.services.gpg-agent = {
15 | Service = {
16 | Environment = lib.mkForce [
17 | "GPG_TTY=/dev/tty1"
18 | "DISPLAY=:0"
19 | "GNUPGHOME=${config.home-manager.users.balsoft.xdg.dataHome}/gnupg"
20 | ];
21 | };
22 | };
23 |
24 | programs.gpg = {
25 | enable = true;
26 | homedir = "${config.home-manager.users.balsoft.xdg.dataHome}/gnupg";
27 | scdaemonSettings = {
28 | disable-ccid = true;
29 | reader-port = "Yubico Yubi";
30 | };
31 | };
32 | };
33 | }
34 |
--------------------------------------------------------------------------------
/profiles/workspace/gtk.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, inputs, ... }:
2 | let
3 | thm = config.themes.colors;
4 | thm' = builtins.mapAttrs (name: value: { hex.rgb = value; }) thm;
5 | in {
6 | programs.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];
7 | nixpkgs.overlays = [
8 | (self: super: {
9 | generated-gtk-theme =
10 | pkgs.callPackage "${inputs.rycee}/pkgs/materia-theme" {
11 | configBase16 = {
12 | name = "Generated";
13 | kind = "dark";
14 | colors = thm' // {
15 | base01 = thm'.base00;
16 | base02 = thm'.base00;
17 | };
18 | };
19 | };
20 | })
21 | ];
22 | programs.dconf.enable = true;
23 | services.dbus.packages = with pkgs; [ dconf ];
24 | home-manager.users.balsoft = {
25 | gtk = {
26 | enable = true;
27 | iconTheme = {
28 | name = "breeze-dark";
29 | package = pkgs.kdePackages.breeze-icons;
30 | };
31 | theme = {
32 | name = "Generated";
33 | package = pkgs.generated-gtk-theme;
34 | };
35 | font = {
36 | name = with config.themes.fonts; "${main.family} ${toString main.size}";
37 | };
38 | gtk3 = {
39 | bookmarks = [
40 | "file:///home/balsoft/projects Projects"
41 | "davs://nextcloud.balsoft.ru/remote.php/dav/files/balsoft nextcloud.balsoft.ru"
42 | "sftp://balsoft.ru/home/balsoft balsoft.ru"
43 | ] ++ map (machine: "sftp://${machine}/home/balsoft ${machine}")
44 | (builtins.attrNames inputs.self.nixosConfigurations);
45 | };
46 |
47 | };
48 | home.sessionVariables.GTK_THEME = "Generated";
49 | };
50 | }
51 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/default.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, ... }:
2 | with lib; with pkgs.my-lib;
3 | let scripts = import ./scripts pkgs config;
4 | in {
5 | secrets.email = {
6 | owner = "balsoft:users";
7 | services = [ ];
8 | encrypted = "${config.environment.sessionVariables.PASSWORD_STORE_DIR}/email/balsoft@balsoft.ru.gpg";
9 | };
10 |
11 | home-manager.users.balsoft = {
12 | wayland.windowManager.sway.config.bars = [{
13 | id = "default";
14 | trayOutput = "none";
15 | command = "true";
16 | colors = let
17 | thm = pkgs.my-lib.thmHash config.themes.colors;
18 | default = {
19 | background = thm.base00;
20 | border = thm.base00;
21 | };
22 | in {
23 | background = thm.base00;
24 | statusline = thm.base05;
25 | separator = thm.base02;
26 | focusedWorkspace = default // { text = thm.base08; };
27 | activeWorkspace = default // { text = thm.base0B; };
28 | inactiveWorkspace = default // { text = thm.base05; };
29 | urgentWorkspace = default // { text = thm.base09; };
30 | bindingMode = default // { text = thm.base0A; };
31 | };
32 | statusCommand = "${pkgs.i3blocks}/bin/i3blocks -o json";
33 | fonts = {
34 | names = [ "${config.themes.fonts.main.family}" "Material Icons" "Roboto Mono" ];
35 | style = "Regular";
36 | size = 12.0;
37 | };
38 | mode = "hide";
39 | position = "bottom";
40 | workspaceNumbers = false;
41 | }];
42 | xdg.configFile."i3blocks/config".text = let
43 | scr = x: {
44 | name = x;
45 | command = scripts.${x};
46 | };
47 | scrint = x: interval: (scr x) // { inherit interval; };
48 | in ''
49 | interval=60
50 | markup=pango
51 | '' + pkgs.my-lib.genIniOrdered ([ (scr "email") ]
52 | ++ [ (scrint "weather" 600) (scr "nixos") ]
53 | ++ [ (scrint "music" 3) (scrint "sound" 1) ]
54 | ++ [
55 | (scrint "cpu" 5)
56 | (scrint "freq" 10)
57 | (scr "temperature")
58 | (scrint "free" 10)
59 | (scr "battery")
60 | ] ++ optionals config.deviceSpecific.isLaptop [
61 | (scrint "brightness" 5)
62 | ] ++ optional (config.deviceSpecific.devInfo ? bigScreen)
63 | (scrint "network" 1) ++ [
64 | (scrint "bluetooth" 3)
65 | (scrint "connections" 3)
66 | (scr "df")
67 | (scr "date")
68 | (scrint "time" 1)
69 | ]);
70 | systemd.user.services.swaybar = {
71 | Unit = {
72 | Description = "Start default bar";
73 | X-RestartIfChanged = true;
74 | };
75 |
76 | Install.WantedBy = [ "sway-session.target" ];
77 |
78 | Service = {
79 | ExecStart = "${pkgs.sway}/bin/swaybar -d -b default";
80 | Environment = [ "PATH=${pkgs.bash}/bin" ];
81 | };
82 | };
83 | };
84 | }
85 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/battery.nix:
--------------------------------------------------------------------------------
1 | { upower, gnugrep, coreutils-full, lib, bash, iconfont, low_threshold ? 10, ... }: ''
2 | #!${bash}/bin/bash
3 | PATH=$PATH:${lib.makeBinPath [ gnugrep upower coreutils-full ]}
4 | readarray -t DEVICES <<< "$(${upower}/bin/upower -e | grep -v "DisplayDevice$")"
5 |
6 | DELIM=""
7 | STATUS=0
8 |
9 | for dev in "''${DEVICES[@]}"; do
10 | INFO="$(${upower}/bin/upower -i "$dev")"
11 | PERCENTAGE="$(echo "$INFO" | grep 'percentage:' | grep -o '[[:digit:]]*')"
12 | if [ -n "$PERCENTAGE" ]; then
13 | TIME="$(echo "$INFO" | grep 'time to' | tr -s ' ' | cut -d' ' -f5-6)"
14 | STATE="$(echo "$INFO" | grep 'state:' | tr -s ' ' | cut -d' ' -f3)"
15 | MODEL="$(echo "$INFO" | grep 'model:' | tr -s ' ' | cut -d' ' -f3)"
16 | if [[ "x$STATE" == "xfully-charged" ]] || [[ "x$STATE" == "xcharging" ]]; then
17 | case $PERCENTAGE in
18 | [0-9]|1[0-9]) icon=;;
19 | [2-3][0-9]) icon=;;
20 | [4-5][0-9]) icon=;;
21 | [6-7][0-9]) icon=;;
22 | [8-9][0-9]) icon=;;
23 | 100) icon=;;
24 | esac
25 | else
26 | if [[ "$PERCENTAGE" -lt ${toString low_threshold} ]]; then
27 | STATUS=33
28 | fi
29 | case $PERCENTAGE in
30 | [0-9]) icon=;;
31 | 1[0-9]) icon=;;
32 | 2[0-9]) icon=;;
33 | 3[0-9]) icon=;;
34 | 4[0-9]) icon=;;
35 | 5[0-9]) icon=;;
36 | 6[0-9]) icon=;;
37 | 7[0-9]) icon=;;
38 | 8[0-9]) icon=;;
39 | 9[0-9]) icon=;;
40 | 100) icon=;;
41 | esac
42 | fi
43 | if [ -n "$DELIM" ]; then
44 | echo -n "| "
45 | else
46 | DELIM="yes"
47 | fi
48 | echo -n ""
49 | if echo "$INFO" | grep 'native-path:' | grep bluez > /dev/null; then
50 | echo -n ""
51 | fi
52 | echo -n "$icon"
53 | if [ -n "$BLOCK_BUTTON" ]; then
54 | echo -n " $MODEL "
55 | echo -n "$PERCENTAGE% "
56 | if [ -n "$TIME" ]; then echo -n "($TIME) "; fi
57 | fi
58 | fi
59 | done
60 |
61 | echo
62 | exit "$STATUS"
63 | ''
64 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/bluetooth.nix:
--------------------------------------------------------------------------------
1 | { iconfont, gnugrep, bash, bluez, pulseaudio, util-linux, python3, ... }:
2 | ''
3 | #!${bash}/bin/bash
4 | if ${util-linux}/bin/rfkill | ${gnugrep}/bin/grep bluetooth > /dev/null; then
5 | if ${util-linux}/bin/rfkill | ${gnugrep}/bin/grep bluetooth | ${gnugrep}/bin/grep blocked > /dev/null; then
6 | if ${bluez}/bin/bluetoothctl info > /dev/null; then
7 | if ${pulseaudio}/bin/pactl list sinks | ${gnugrep}/bin/grep bluez > /dev/null; then
8 | echo -n ""
9 | else
10 | echo -n ""
11 | fi
12 | else
13 | echo -n ""
14 | fi
15 | else
16 | echo -n ""
17 | fi
18 | fi
19 | ''
20 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/brightness.nix:
--------------------------------------------------------------------------------
1 | { iconfont, light, config, ... }: ''
2 | case $BLOCK_BUTTON in
3 | 4) sudo ${light}/bin/light -A 5;;
4 | 5) sudo ${light}/bin/light -U 5;;
5 | esac
6 | LIGHT=`${light}/bin/light | cut -f 1 -d '.'`
7 | if [[ $LIGHT -lt 33 ]]
8 | then
9 | icon=
10 | else
11 | if [[ $LIGHT -lt 66 ]]
12 | then
13 | icon=
14 | else
15 | icon=
16 | fi
17 | fi
18 | ${if config.device == "ASUS-Laptop" then ''
19 | if [[ `cat /sys/devices/platform/asus-nb-wmi/als_enable` -eq 1 ]]
20 | then
21 | icon=""
22 | fi
23 | '' else
24 | ""}
25 | [[ -n $BLOCK_BUTTON ]] && text=" $LIGHT"
26 | echo "$icon$text"
27 | ''
28 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/connections.nix:
--------------------------------------------------------------------------------
1 | { bash, gnugrep, coreutils-full, util-linux, networkmanager, iconfont, config, modemmanager, lib, ... }: ''
2 | #!${bash}/bin/bash
3 | PATH=$PATH:${lib.makeBinPath [ networkmanager coreutils-full gnugrep modemmanager util-linux.bin ]}
4 | export PATH
5 | CONNECTIONS=$(nmcli con show --active | tail +2 | tr -s ' ' | rev | cut -d' ' -f3 | rev)
6 | text=""
7 | for connection in $CONNECTIONS
8 | do
9 | grep wifi <<< $connection > /dev/null && {
10 | # SIGNAL=$(${networkmanager}/bin/nmcli d w | grep '^\*' | tr -s ' ' | cut -d' ' -f7)
11 | # if [[ $SIGNAL -lt 20 ]]
12 | # then
13 | # text+=冷
14 | # elif [[ $SIGNAL -lt 40 ]]
15 | # then
16 | # text+=爛
17 | # elif [[ $SIGNAL -lt 60 ]]
18 | # then
19 | # text+=嵐
20 | # elif [[ $SIGNAL -lt 80 ]]
21 | # then
22 | # text+=襤
23 | # else
24 | # text+=蠟
25 | # fi
26 | text=
27 | }
28 | grep gsm <<< $connection >/dev/null && {
29 | MODEM=$(mmcli -K -L | tail -1 | cut -d: -f2 | tr -d ' ')
30 | STATUS=$(mmcli -K -m $MODEM)
31 | TECH=$(grep "modem.generic.access-technologies.value\[1\]" <<< $STATUS | cut -d: -f2 | tr -d ' ')
32 |
33 | # SIGNAL=$(grep "modem.generic.signal-quality.value" <<< $STATUS | cut -d: -f2 | tr -d ' ')
34 | # if [[ $SIGNAL -lt 20 ]]
35 | # then
36 | # text+=""
37 | # elif [[ $SIGNAL -lt 40 ]]
38 | # then
39 | # text+=""
40 | # elif [[ $SIGNAL -lt 60 ]]
41 | # then
42 | # text+=""
43 | # elif [[ $SIGNAL -lt 80 ]]
44 | # then
45 | # text+=""
46 | # else
47 | # text+=""
48 | # fi
49 | text+=
50 | if [[ $TECH == lte ]]
51 | then
52 | text+="ﰒ"
53 | else
54 | text+="ﰑ"
55 | fi
56 | }
57 | grep ethernet <<< $connection > /dev/null && text+=""
58 | done
59 | code=0
60 | [[ $text == "" ]] && {
61 | text=
62 | code=33
63 | }
64 | echo "$text"
65 | exit $code
66 | ''
67 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/default.nix:
--------------------------------------------------------------------------------
1 | p: c:
2 | with p;
3 | let
4 | iconfont = "Material Icons";
5 | buildHaskellScript = name: script:
6 | stdenv.mkDerivation {
7 | inherit name;
8 | src = script;
9 | unpackPhase = "true";
10 | buildInputs = [ghc];
11 | buildPhase = "ghc -o $out $src";
12 | installPhase = "true";
13 | ICONFONT = iconfont;
14 | };
15 | writeScript = name: script:
16 | writeTextFile {
17 | inherit name;
18 | text = callPackage script {
19 | inherit iconfont;
20 | config = c;
21 | };
22 | executable = true;
23 | checkPhase =
24 | "${bash}/bin/bash -n $src || ${python3}/bin/python3 -m compileall $src";
25 | };
26 | in
27 | builtins.mapAttrs buildHaskellScript {
28 | free = ./free.hs;
29 | temperature = ./temperature.hs;
30 | network = ./network.hs;
31 | } // builtins.mapAttrs writeScript {
32 | battery = ./battery.nix;
33 | brightness = ./brightness.nix;
34 | email = ./email.nix;
35 | # emacs = ./emacs.nix;
36 | bluetooth = ./bluetooth.nix;
37 | connections = ./connections.nix;
38 | weather = ./weather.nix;
39 | sound = ./sound.nix;
40 | music = ./music.nix;
41 | cpu = {...}: ''${procps}/bin/top -b -n1 -p 1 | ${gnugrep}/bin/fgrep "Cpu(s)" | ${coreutils}/bin/tail -1 | ${gawk}/bin/awk -F'id,' -v prefix="$prefix" '{ split($1, vs, ","); v=vs[length(vs)]; sub("%", "", v); printf "%s%.1f%%\n", prefix, 100 - v }' '';
42 | freq = {...}: ''echo $(${pkgs.bc}/bin/bc -l <<< "scale=2; `${coreutils}/bin/cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq|${coreutils}/bin/sort|${coreutils}/bin/tail -1`/1000000") GHz'';
43 | df = {...}: ''echo '' `${coreutils}/bin/df / | ${coreutils}/bin/tail -1 | ${gnugrep}/bin/grep -o '..%'`'';
44 | date = {...}: "${pkgs.coreutils}/bin/date +' %a %y-%m-%d'";
45 | time = {...}: "${pkgs.coreutils}/bin/date +' %T'";
46 | nixos = {...}: "echo -n ''; ${coreutils}/bin/cat /run/current-system/nixos-version | ${coreutils-full}/bin/cut -d. -f3";
47 | #temperature = ./temperature.nix;
48 | #free = ./free.nix;
49 | }
50 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/emacs.nix:
--------------------------------------------------------------------------------
1 | { config, ... }:
2 | let ec = "${config.home-manager.users.balsoft.programs.emacs.finalPackage}/bin/emacsclient";
3 | in
4 | ''
5 | [[ $BLOCK_BUTTON -eq 2 ]] && ${ec} --eval "(org-clock-out)" > /dev/null
6 | ${ec} --eval "org-mode-line-string" | head -1 | cut -d\" -f 2
7 | ''
8 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/email.nix:
--------------------------------------------------------------------------------
1 | { python3, iconfont, config, ... }: ''
2 | #!${python3}/bin/python3
3 | import imaplib
4 | obj = imaplib.IMAP4_SSL('balsoft.ru', 993)
5 | password = open("${config.secrets.email.decrypted}").read()[:-1:]
6 | obj.login("balsoft@balsoft.ru", password)
7 | obj.select()
8 | l = len(obj.search(None, 'unseen')[1][0].split())
9 | if l == 0:
10 | print('')
11 | else:
12 | print(' %s' % str(l))
13 | exit(33)
14 | ''
15 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/free.hs:
--------------------------------------------------------------------------------
1 | import System.Exit
2 |
3 | main :: IO ()
4 | main = do
5 | freeMemory <- read
6 | <$> (!!1) <$> words
7 | <$> (!!2) <$> lines
8 | <$> readFile "/proc/meminfo"
9 | putStrLn $ (take 5 $ show $ freeMemory / 1000000) ++ "GB"
10 | exitWith $ if freeMemory > 500000 then ExitSuccess else ExitFailure 33
11 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/free.nix:
--------------------------------------------------------------------------------
1 | { bc, ... }: ''
2 | echo `free | tail -2 | head -1 | awk '{print "scale=3; "$7"/1000000"}' | ${
3 | bc
4 | }/bin/bc -l`GB
5 | ''
6 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/hydra-status.nix:
--------------------------------------------------------------------------------
1 | { bash, curl, libnotify, sox, iconfont, ... }:
2 | ''
3 | #!${bash}/bin/bash
4 | STATUS=$(${curl}/bin/curl -sw "%{http_code}" https://hydra.typeable.io/ping)
5 | if [ $STATUS -eq 200 ]
6 | then
7 | echo '🐍'
8 | exit 0
9 | else
10 | msg="HYDRA DOWN"
11 | echo $msg
12 | exit 33
13 | fi
14 | ''
15 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/music.nix:
--------------------------------------------------------------------------------
1 | { python3, playerctl, iconfont, ...}: ''
2 | #!${python3}/bin/python
3 | from subprocess import getoutput, call
4 | from os import environ
5 | status = getoutput("${playerctl}/bin/playerctl status")
6 | if "BLOCK_BUTTON" in environ:
7 | BLOCK_BUTTON = environ["BLOCK_BUTTON"]
8 | if BLOCK_BUTTON == "1": call(["${playerctl}/bin/playerctl", "play-pause"])
9 | if BLOCK_BUTTON == "2": call(["${playerctl}/bin/playerctl", "stop"])
10 | if BLOCK_BUTTON == "3": call(["${playerctl}/bin/playerctl", "next"])
11 | if status == "Paused" or status == "Playing":
12 | text = getoutput("${playerctl}/bin/playerctl metadata title")[:20:]
13 | icon = ""
14 | else:
15 | text = ""
16 | icon = ""
17 | print("%s %s" % (icon, text.replace('&', '&')))
18 | ''
19 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/network.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE BangPatterns, TemplateHaskell #-}
2 |
3 | import Control.Concurrent (threadDelay)
4 | import Control.Monad (mapM, join)
5 | import System.Directory (listDirectory)
6 | import Data.Bool (bool)
7 | import Language.Haskell.TH.Syntax (liftString, runIO)
8 | import System.Environment (getEnv)
9 | import Control.Monad.IO.Class (liftIO)
10 | import Text.Printf (printf)
11 |
12 | path :: String
13 | path = "/sys/class/net/"
14 |
15 | data Statistics = Statistics !Float !Float
16 |
17 | instance Semigroup Statistics where
18 | Statistics a b <> Statistics c d = Statistics (a + c) (b + d)
19 |
20 | instance Monoid Statistics where
21 | mempty = Statistics 0 0
22 |
23 | icon :: String -> String
24 | icon i = "" ++ i ++ ""
25 |
26 | readInterface :: FilePath -> IO Statistics
27 | readInterface interface = do
28 | rx <- read <$> readFile (path ++ interface ++ "/statistics/rx_bytes")
29 | tx <- read <$> readFile (path ++ interface ++ "/statistics/tx_bytes")
30 | return $ Statistics rx tx
31 |
32 | readInterfaces :: [FilePath] -> IO Statistics
33 | readInterfaces interfaces = mconcat <$> (mapM readInterface interfaces)
34 |
35 | renderSpeed :: Float -> String
36 | renderSpeed bits
37 | | bits < 1e6 = (show . round) (bits / 1e3) ++ "kbps"
38 | | otherwise = printf "%0.*f" (1 :: Int) (bits / 1e6) ++ "Mbps"
39 |
40 | main :: IO ()
41 | main = do
42 | interfaces <- listDirectory path
43 | Statistics rx tx <- readInterfaces interfaces
44 | threadDelay 1000000
45 | Statistics rx' tx' <- readInterfaces interfaces
46 | putStrLn $ (icon "\58052") ++ renderSpeed (rx' - rx)
47 | ++ (icon "\58054") ++ renderSpeed (tx' - tx)
48 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/sound.nix:
--------------------------------------------------------------------------------
1 | { pamixer, lxqt, iconfont, config, lib, ... }: ''
2 | case $BLOCK_BUTTON in
3 | 2) ${pamixer}/bin/pamixer -t;;
4 | 4) ${pamixer}/bin/pamixer -i 5;;
5 | 5) ${pamixer}/bin/pamixer -d 5;;
6 | esac
7 | code=0
8 | if [[ `${pamixer}/bin/pamixer --get-mute` = "true" ]]
9 | then
10 | volume=""
11 | end=""
12 | icon="婢"
13 | else
14 | volume=`${pamixer}/bin/pamixer --get-volume`
15 | end="%"
16 | if [[ $volume -lt 33 ]]
17 | then
18 | icon="奄"
19 | else
20 | if [[ $volume -lt 66 ]]
21 | then
22 | icon="奔"
23 | else
24 | icon="墳"
25 | code=33
26 | fi
27 | fi
28 | fi
29 | ${lib.optionalString (! config.deviceSpecific.bigScreen) "[[ -n $BLOCK_BUTTON ]] &&"} text=" $volume$end"
30 | echo "$icon$text"
31 | exit $code
32 | ''
33 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/temperature.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
2 |
3 | import Prelude hiding (readFile)
4 | import System.Directory
5 | import System.FilePath
6 | import Control.Monad (forM, join)
7 | import System.Posix.Files
8 | import Data.List (isPrefixOf, isInfixOf)
9 | import System.Exit
10 | import Language.Haskell.TH.Syntax (liftString, runIO)
11 | import System.Environment (getEnv)
12 | import Control.Monad.IO.Class (liftIO)
13 | import Data.Maybe (catMaybes)
14 | import Control.Exception
15 | import Data.Text (unpack)
16 | import Data.Text.IO (readFile)
17 |
18 | -- | Traverse from 'top' directory and return all the files by
19 | -- filtering with 'include' predicate.
20 | traverseDir :: FilePath -> (FilePath -> Bool) -> IO [FilePath]
21 | traverseDir top include = do
22 | ds <- getDirectoryContents top
23 | paths <- forM (filter include ds) $ \d -> do
24 | let path = top > d
25 | s <- getFileStatus path
26 | if isDirectory s
27 | then traverseDir path include
28 | else return [path]
29 | return $ concat paths
30 |
31 |
32 |
33 | -- | Get temperatures from hardware sensors in
34 | getTemps :: IO [Int]
35 | getTemps = do
36 | hwmons <- traverseDir "/sys/class/hwmon"
37 | (
38 | \name
39 | -> ("hwmon" `isPrefixOf` name)
40 | || ("temp" `isInfixOf` name) && ("input" `isInfixOf` name)
41 | )
42 | fmap (round . (/1000) . read . unpack) <$> traverse (handle (\e -> do pure (e :: IOException); pure "0") . readFile) hwmons
43 |
44 | -- | Get a symbol corresponding to the temperature
45 | getSymbol :: Integral n => n -> String
46 | getSymbol t
47 | | t < 50 = "\57868" --
48 | | t < 80 = "\57866" --
49 | | otherwise = "\57867" --
50 |
51 | icon :: String -> String
52 | icon s = "" ++ s ++ ""
53 |
54 | main :: IO ()
55 | main = do
56 | maxTemp <- maximum <$> getTemps
57 | putStrLn $ (getSymbol <> show) maxTemp <> "°"
58 | exitWith $ if maxTemp < 80 then ExitSuccess else ExitFailure 33
59 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/temperature.nix:
--------------------------------------------------------------------------------
1 | { ... }:
2 | ''
3 | temp=$((`cat /sys/class/thermal/thermal_zone*/temp | sort | tail -1`/1000))
4 | echo $temp °
5 | [[ $temp -gt 80 ]] && exit 33
6 | ''
7 |
--------------------------------------------------------------------------------
/profiles/workspace/i3blocks/scripts/weather.nix:
--------------------------------------------------------------------------------
1 | { bash, config, curl, iconfont, ... }: ''
2 | #!${bash}/bin/bash
3 | WTTR=$(${curl}/bin/curl wttr.in/?format=1)
4 | echo "$WTTR"
5 | ''
6 |
--------------------------------------------------------------------------------
/profiles/workspace/kanshi.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | home-manager.users.balsoft = {
3 | xsession.windowManager.i3.config.startup = [{
4 | command = "${pkgs.kanshi}/bin/kanshi";
5 | notification = false;
6 | always = true;
7 | }];
8 | xdg.configFile."kanshi/config".text = ''
9 | {
10 | output "Samsung Electric Company C27JG5x HTOM901267" position 0,1025
11 | output "Dell Inc. DELL E176FP MC0435BH2ATP" position 1400,0
12 | }
13 | {
14 | output "Samsung Electric Company C27JG5x HTOM901267" position 0,0
15 | }
16 | '';
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/profiles/workspace/kde/kdeconnect.nix:
--------------------------------------------------------------------------------
1 | { lib, ... }: {
2 | home-manager.users.balsoft = {
3 | services.kdeconnect.enable = true;
4 | systemd.user.services.kdeconnect = {
5 | Service.Environment = lib.mkForce [
6 | "PATH=/etc/profiles/per-user/balsoft/bin"
7 | ];
8 | };
9 | };
10 | persist.state.directories = [ "/home/balsoft/.config/kdeconnect" ];
11 | }
12 |
--------------------------------------------------------------------------------
/profiles/workspace/kde/plasma-mobile.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 |
3 | environment.sessionVariables = {
4 | _JAVA_AWT_WM_NONREPARENTING = "1";
5 | XDG_SESSION_TYPE = "wayland";
6 | QT_QPA_PLATFORM = "wayland";
7 | QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
8 | };
9 |
10 | nixpkgs.overlays = [
11 | (final: prev: {
12 | libsForQt5 = prev.libsForQt5 // {
13 | kwallet = null;
14 | kwallet-pam = null;
15 | kwalletmanager = null;
16 | };
17 | })
18 | ];
19 |
20 | services.xserver = {
21 | enable = true;
22 | desktopManager.plasma5 = {
23 | mobile.enable = true;
24 | runUsingSystemd = false;
25 | };
26 | displayManager = {
27 | autoLogin = {
28 | enable = true;
29 | user = "balsoft";
30 | };
31 | defaultSession = "plasma-mobile";
32 | lightdm = {
33 | enable = true;
34 | extraSeatDefaults = ''
35 | session-cleanup-script=${pkgs.procps}/bin/pkill -P1 -fx ${pkgs.lightdm}/sbin/lightdm
36 | '';
37 | };
38 | };
39 | libinput.enable = true;
40 | };
41 |
42 | programs.feedbackd.enable = true;
43 |
44 | services.upower.enable = true;
45 |
46 | services.geoclue2.enable = true;
47 |
48 | home-manager.users.balsoft = {
49 | home.activation.removeGtkRc = {
50 | data = "rm -f $HOME/.gtkrc-2.0";
51 | before = [ "checkLinkTargets" ];
52 | after = [ ];
53 | };
54 |
55 | xdg.configFile."autostart/org_kde_powerdevil.desktop".text = ''
56 | [Desktop Entry]
57 | DBusActivatable=true
58 | Exec=${pkgs.kdePackages.powerdevil}/libexec/org_kde_powerdevil
59 | Name=org_kde_powerdevil
60 | Type=Application
61 | '';
62 | xdg.configFile."plasmarc".text =
63 | lib.generators.toGitINI { Theme.name = "generated"; };
64 | xdg.configFile."plasmamobilerc".text = lib.generators.toGitINI {
65 | General = {
66 | actionDrawerTopLeftMode = "1";
67 | actionDrawerTopRightMode = "0";
68 | vibrationDuration = "100";
69 | vibrationIntensity = "0.5";
70 | vibrationsEnabled = "true";
71 | navigationPanelEnabled = "false";
72 | taskSwitcherPreviewsEnabled = "false";
73 | animationsEnabled = "false";
74 | };
75 | QuickSettings = {
76 | disabledQuickSettings = builtins.concatStringsSep "," [ ];
77 | enabledQuickSettings = builtins.concatStringsSep "," [
78 | "org.kde.plasma.quicksetting.wifi"
79 | "org.kde.plasma.quicksetting.mobiledata"
80 | "org.kde.plasma.quicksetting.bluetooth"
81 | "org.kde.plasma.quicksetting.flashlight"
82 | "org.kde.plasma.quicksetting.screenrotation"
83 | "org.kde.plasma.quicksetting.settingsapp"
84 | "org.kde.plasma.quicksetting.airplanemode"
85 | "org.kde.plasma.quicksetting.audio"
86 | "org.kde.plasma.quicksetting.battery"
87 | "org.kde.plasma.quicksetting.location"
88 | "org.kde.plasma.quicksetting.nightcolor"
89 | "org.kde.plasma.quicksetting.screenshot"
90 | "org.kde.plasma.quicksetting.powermenu"
91 | "org.kde.plasma.quicksetting.donotdisturb"
92 | "org.kde.plasma.quicksetting.caffeine"
93 | "org.kde.plasma.quicksetting.keyboardtoggle"
94 | "org.kde.plasma.quicksetting.record"
95 | ];
96 | };
97 | };
98 | xdg.configFile."plasmaparc".text =
99 | lib.generators.toGitINI { General.VolumeStep = 2; };
100 | };
101 | }
102 |
--------------------------------------------------------------------------------
/profiles/workspace/kde/qt.nix:
--------------------------------------------------------------------------------
1 | { pkgs, lib, config, ... }:
2 | with pkgs.my-lib;
3 | let
4 | colorTheme = with (thmDec config.themes.colors); {
5 | "Colors:Button" = {
6 | BackgroundAlternate = base01;
7 | BackgroundNormal = base01;
8 | DecorationFocus = base0D;
9 | DecorationHover = base0D;
10 | ForegroundActive = base0D;
11 | ForegroundInactive = base01;
12 | ForegroundLink = base0D;
13 | ForegroundNegative = base08;
14 | ForegroundNeutral = base09;
15 | ForegroundNormal = base05;
16 | ForegroundPositive = base0B;
17 | ForegroundVisited = base03;
18 | };
19 | "Colors:Complementary" = {
20 | BackgroundAlternate = base01;
21 | BackgroundNormal = base03;
22 | DecorationFocus = base0D;
23 | DecorationHover = base0D;
24 | ForegroundActive = base0D;
25 | ForegroundInactive = base01;
26 | ForegroundLink = base0D;
27 | ForegroundNegative = base08;
28 | ForegroundNeutral = base0A;
29 | ForegroundNormal = base05;
30 | ForegroundPositive = base0B;
31 | ForegroundVisited = base02;
32 | };
33 | "Colors:Selection" = {
34 | BackgroundAlternate = base0D;
35 | BackgroundNormal = base0D;
36 | DecorationFocus = base0D;
37 | DecorationHover = base0D;
38 | ForegroundActive = base05;
39 | ForegroundInactive = base05;
40 | ForegroundLink = base0D;
41 | ForegroundNegative = base08;
42 | ForegroundNeutral = base09;
43 | ForegroundNormal = base05;
44 | ForegroundPositive = base0B;
45 | ForegroundVisited = base02;
46 | };
47 | "Colors:Tooltip" = {
48 | BackgroundAlternate = base01;
49 | BackgroundNormal = base00;
50 | DecorationFocus = base0D;
51 | DecorationHover = base0D;
52 | ForegroundActive = base0D;
53 | ForegroundInactive = base01;
54 | ForegroundLink = base0D;
55 | ForegroundNegative = base08;
56 | ForegroundNeutral = base09;
57 | ForegroundNormal = base05;
58 | ForegroundPositive = base0B;
59 | ForegroundVisited = base03;
60 | };
61 | "Colors:View" = {
62 | BackgroundAlternate = base01;
63 | BackgroundNormal = base00;
64 | DecorationFocus = base0D;
65 | DecorationHover = base0D;
66 | ForegroundActive = base0D;
67 | ForegroundInactive = base01;
68 | ForegroundLink = base0D;
69 | ForegroundNegative = base08;
70 | ForegroundNeutral = base09;
71 | ForegroundNormal = base05;
72 | ForegroundPositive = base0B;
73 | ForegroundVisited = base03;
74 | };
75 | "Colors:Window" = {
76 | BackgroundAlternate = base01;
77 | BackgroundNormal = base00;
78 | DecorationFocus = base0D;
79 | DecorationHover = base0D;
80 | ForegroundActive = base0D;
81 | ForegroundInactive = base01;
82 | ForegroundLink = base0D;
83 | ForegroundNegative = base08;
84 | ForegroundNeutral = base09;
85 | ForegroundNormal = base05;
86 | ForegroundPositive = base0B;
87 | ForegroundVisited = base03;
88 | };
89 | General = {
90 | ColorScheme = "Generated";
91 | Name = "Generated";
92 | shadeSortColumn = true;
93 | };
94 | KDE.contrast = 4;
95 | WM = {
96 | activeBackground = base00;
97 | activeBlend = base06;
98 | activeForeground = base05;
99 | inactiveBackground = base01;
100 | inactiveBlend = base02;
101 | inactiveForeground = base04;
102 | };
103 | };
104 | misc = with config.themes; {
105 | Icons.Theme = "breeze-dark";
106 |
107 | KDE = {
108 | DoubleClickInterval = 400;
109 | ShowDeleteCommand = true;
110 | SingleClick = false;
111 | StartDragDist = 4;
112 | StartDragTime = 500;
113 | WheelScrollLines = 3;
114 | widgetStyle = "Breeze";
115 | };
116 | General = {
117 | TerminalApplication = config.defaultApplications.term.cmd;
118 | fixed =
119 | "${fonts.mono.family},${toString fonts.mono.size},-1,5,50,0,0,0,0,0";
120 | font =
121 | "${fonts.main.family},${toString fonts.main.size},-1,5,50,0,0,0,0,0";
122 | menuFont =
123 | "${fonts.main.family},${toString fonts.main.size},-1,5,50,0,0,0,0,0";
124 | smallestReadableFont = "${fonts.main.family},${
125 | toString fonts.main.size
126 | },-1,5,57,0,0,0,0,0,Medium";
127 | toolBarFont =
128 | "${fonts.main.family},${toString fonts.main.size},-1,5,50,0,0,0,0,0";
129 | };
130 | };
131 | effects = with (thmDec config.themes.colors); {
132 | "ColorEffects:Disabled" = {
133 | Color = base02;
134 | ColorAmount = "0";
135 | ColorEffect = "0";
136 | ContrastAmount = "0.65";
137 | ContrastEffect = "1";
138 | IntensityAmount = "0.1";
139 | IntensityEffect = "2";
140 | };
141 |
142 | "ColorEffects:Inactive" = {
143 | ChangeSelectionColor = "true";
144 | Color = base03;
145 | ColorAmount = "0.025";
146 | ColorEffect = "2";
147 | ContrastAmount = "0.1";
148 | ContrastEffect = "2";
149 | Enable = "false";
150 | IntensityAmount = "0";
151 | IntensityEffect = "0";
152 | };
153 | };
154 | desktopThemeColors = pkgs.writeText "generated-plasma-theme-colors"
155 | (lib.generators.toGitINI
156 | (builtins.foldl' lib.recursiveUpdate { } [ colorTheme effects ]));
157 | desktopThemeRc = pkgs.writeText "generated-plasma-theme-rc"
158 | (lib.generators.toGitINI {
159 | Wallpaper = {
160 | defaultWallpaperTheme = "Next";
161 | defaultFileSuffix = ".png";
162 | defaultWidth = "1920";
163 | defaultHeight = "1080";
164 | };
165 | ContrastEffect = {
166 | enabled = "true";
167 | contrast = "0.17";
168 | intensity = "1.25";
169 | saturation = "9";
170 | };
171 | AdaptiveTransparency.enabled = "true";
172 | });
173 | desktopTheme = pkgs.linkFarm "generated-plasma-theme" [
174 | {
175 | name = "share/plasma/desktoptheme/generated/plasmarc";
176 | path = desktopThemeRc;
177 | }
178 | {
179 | name = "share/plasma/desktoptheme/generated/colors";
180 | path = desktopThemeColors;
181 | }
182 | ];
183 | in {
184 | environment.systemPackages = [ desktopTheme ];
185 |
186 | xdg.portal.enable = true;
187 | xdg.portal.extraPortals = [ pkgs.kdePackages.xdg-desktop-portal-kde ];
188 | services.dbus.packages = [ pkgs.systemd pkgs.kdePackages.breeze-icons ];
189 | services.udev.packages = [ pkgs.libmtp pkgs.media-player-info ];
190 |
191 | qt.enable = false;
192 |
193 | environment.sessionVariables = {
194 | QT_XFT = "true";
195 | QT_SELECT = "5";
196 | KDE_SESSION_VERSION = "5";
197 | QT_SCALE_FACTOR = "1";
198 | QT_AUTO_SCREEN_SCALE_FACTOR = "0";
199 | QT_QPA_PLATFORMTHEME = "kde";
200 | KDEDIRS =
201 | "/run/current-system/sw:/run/current-system/sw/share/kservices5:/run/current-system/sw/share/kservicetypes5:/run/current-system/sw/share/kxmlgui5";
202 | };
203 |
204 | defaultApplications = {
205 | # fm = {
206 | # cmd = "${pkgs.kdePackages.dolphin}/bin/dolphin";
207 | # desktop = "org.kde.dolphin";
208 | # };
209 | # archive = {
210 | # cmd = "${pkgs.kdePackages.ark}/bin/ark";
211 | # desktop = "org.kde.ark";
212 | # };
213 | };
214 |
215 | home-manager.users.balsoft = {
216 | # home.packages = [ pkgs.kdePackages.ark pkgs.kdePackages.dolphin ];
217 |
218 | xdg.configFile."kdeglobals".text = pkgs.my-lib.genIni
219 | (builtins.foldl' lib.recursiveUpdate { } [ colorTheme effects misc ]);
220 | };
221 | }
222 |
--------------------------------------------------------------------------------
/profiles/workspace/light.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | programs.light.enable = config.deviceSpecific.isLaptop;
3 | services.actkbd = {
4 | enable = config.deviceSpecific.isLaptop;
5 | bindings = map (x:
6 | x // {
7 | events = [ "key" ];
8 | attributes = [ "exec" ];
9 | }) [
10 | {
11 | keys = [ 225 ];
12 | command = "${pkgs.light}/bin/light -A 10";
13 | }
14 | {
15 | keys = [ 224 ];
16 | command = "${pkgs.light}/bin/light -U 10";
17 | }
18 | {
19 | keys = [ 431 ];
20 | command = (toString (pkgs.writeTextFile {
21 | name = "dark-script";
22 | text = ''
23 | if [[ `${pkgs.light}/bin/light` -eq 0 ]]
24 | then
25 | ${pkgs.light}/bin/light -I
26 | else
27 | ${pkgs.light}/bin/light -O
28 | ${pkgs.light}/bin/light -S 0
29 | fi'';
30 | executable = true;
31 | }));
32 | }
33 | ];
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/profiles/workspace/locale/default.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, ... }: {
2 | environment.sessionVariables = {
3 | XKB_DEFAULT_LAYOUT = "us,ru";
4 | XKB_DEFAULT_OPTIONS =
5 | "grp:lctrl_toggle,grp_led:caps,ctrl:nocaps,compose:ralt";
6 | LANG = lib.mkForce "en_GB.UTF-8";
7 | XCOMPOSEFILE = "${config.home-manager.users.balsoft.xdg.configHome}/XCompose";
8 | };
9 |
10 | i18n.defaultLocale = "en_GB.UTF-8";
11 |
12 | time.timeZone = "Asia/Tbilisi";
13 | home-manager.users.balsoft = {
14 | home.file.".XCompose".source = ./compose;
15 | xdg.configFile."gtk-3.0/Compose".source = ./compose;
16 | xdg.configFile."XCompose".source = ./compose;
17 | home.language = let
18 | en = "en_GB.UTF-8";
19 | ru = "ru_RU.UTF-8";
20 | in {
21 | address = ru;
22 | monetary = ru;
23 | paper = ru;
24 | time = en;
25 | base = en;
26 | };
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/profiles/workspace/mako.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, ... }:
2 | {
3 | home-manager.users.balsoft = {
4 | systemd.user.services.mako = {
5 | Service = {
6 | ExecStart = "${pkgs.mako}/bin/mako";
7 | Environment = [
8 | "PATH=${
9 | pkgs.lib.makeBinPath [
10 | pkgs.bash
11 | pkgs.mpv
12 | ]
13 | }"
14 | ];
15 | };
16 | Install = {
17 | After = [ "sway-session.target" ];
18 | WantedBy = [ "sway-session.target" ];
19 | };
20 | };
21 | services.mako = with (pkgs.my-lib.thmHash config.themes.colors); {
22 | enable = true;
23 | settings =
24 | let
25 | play = sound: "mpv ${pkgs.sound-theme-freedesktop}/share/sounds/freedesktop/stereo/${sound}.oga";
26 | in
27 | {
28 | "urgency=high".border-color = "${base09}AA";
29 | "urgency=critical" = {
30 | border-color = "${base09}AA";
31 | on-notify = "exec ${play "message"}";
32 | };
33 | "app-name=yubikey-touch-detector".on-notify = "exec ${play "service-login"}";
34 | "app-name=command_complete summary~=\"✘.*\"".on-notify = "exec ${play "dialog-warning"}";
35 | "app-name=command_complete summary~=\"✓.*\"".on-notify = "exec ${play "bell"}";
36 | "category=osd".on-notify = "none";
37 | "mode=do-not-disturb".invisible = 1;
38 | "mode=do-not-disturb summary=\"Do not disturb: on\"".invisible = 0;
39 | "mode=concentrate".invisible = 1;
40 | "mode=concentrate urgency=critical".invisible = 0;
41 | "mode=concentrate summary=\"Concentrate mode: on\"".invisible = 0;
42 | layer = "overlay";
43 | font = with config.themes.fonts; "${main.family} ${toString main.size}";
44 | width = 500;
45 | height = 160;
46 | default-timeout = 10000;
47 | max-visible = 10;
48 | background-color = "${base00}AA";
49 | text-color = base05;
50 | border-color = "${base0D}AA";
51 | progress-color = "over ${base0B}";
52 | icon-path = "${pkgs.kdePackages.breeze-icons}/share/icons/breeze-dark";
53 | max-icon-size = 24;
54 | };
55 | };
56 | };
57 | }
58 |
--------------------------------------------------------------------------------
/profiles/workspace/misc.nix:
--------------------------------------------------------------------------------
1 | {
2 | pkgs,
3 | lib,
4 | config,
5 | inputs,
6 | ...
7 | }:
8 | {
9 |
10 | environment.sessionVariables =
11 | builtins.mapAttrs (_: toString) (
12 | lib.removeAttrs config.home-manager.users.balsoft.home.sessionVariables [ "GIO_EXTRA_MODULES" ]
13 | )
14 | // rec {
15 | LESS = "MR";
16 | LESSCHARSET = "utf-8";
17 | LESSHISTFILE = "~/.local/share/lesshist";
18 |
19 | CARGO_HOME = "${config.home-manager.users.balsoft.xdg.dataHome}/cargo";
20 |
21 | SYSTEMD_LESS = LESS;
22 | };
23 |
24 | home-manager.users.balsoft = {
25 | news.display = "silent";
26 |
27 | systemd.user.startServices = true;
28 |
29 | home.stateVersion = lib.mkDefault "20.09";
30 | home.preferXdgDirectories = true;
31 | };
32 |
33 | home-manager.useGlobalPkgs = true;
34 |
35 | persist.cache.directories = [
36 | "/home/balsoft/.cache"
37 | "/home/balsoft/.local/share/cargo"
38 | "/var/cache"
39 | ];
40 |
41 | persist.state.directories = [
42 | "/var/lib/nixos"
43 | "/var/lib/systemd"
44 | ];
45 |
46 | system.stateVersion = lib.mkDefault "18.03";
47 |
48 | systemd.services.systemd-timesyncd.wantedBy = [ "multi-user.target" ];
49 |
50 | systemd.timers.systemd-timesyncd = {
51 | timerConfig.OnCalendar = "hourly";
52 | };
53 |
54 | services.avahi.enable = true;
55 |
56 | environment.systemPackages = [ pkgs.ntfs3g ];
57 | }
58 |
--------------------------------------------------------------------------------
/profiles/workspace/mopidy.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, ... }: {
2 | secrets.mopidy_ytmusic_auth = {
3 | owner = "mopidy:mopidy";
4 | services = [ "mopidy" ];
5 | };
6 |
7 | services.mopidy = {
8 | enable = true;
9 | extensionPackages = with pkgs; [ mopidy-mpd /*mopidy-ytmusic*/ ];
10 | configuration = ''
11 | [ytmusic]
12 | enabled=true
13 | auth_json=${config.secrets.mopidy_ytmusic_auth.decrypted}
14 | [mpd]
15 | hostname = 0.0.0.0
16 | port = 6600
17 | [audio]
18 | output = autoaudiosink
19 | '';
20 | };
21 |
22 | systemd.services.mopidy = { after = [ "network-online.target" ]; environment.https_proxy = "socks5://localhost:5555"; };
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/profiles/workspace/openvpn.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: let password-store = config.secretsConfig.password-store; in {
2 | secrets.tawasal_eu1 = {
3 | encrypted = "${password-store}/openvpn/tawasal_eu1.gpg";
4 | services = [ "openvpn-tawasal-eu1.service" ];
5 | };
6 | secrets.tawasal_eu2 = {
7 | encrypted = "${password-store}/openvpn/tawasal_eu2.gpg";
8 | services = [ "openvpn-tawasal-eu2.service" ];
9 | };
10 |
11 | services.openvpn.servers = {
12 | tawasal-eu1.config = "config ${config.secrets.tawasal_eu1.decrypted}";
13 | tawasal-eu2.config = "config ${config.secrets.tawasal_eu2.decrypted}";
14 | };
15 |
16 | systemd.services.openvpn-tawasal-eu1.wantedBy = lib.mkForce [];
17 | systemd.services.openvpn-tawasal-eu2.wantedBy = lib.mkForce [];
18 | }
19 |
--------------------------------------------------------------------------------
/profiles/workspace/print-scan/default.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, inputs, ... }:
2 | let
3 | brother_printer = pkgs.linkFarm "Brother_HL-3170CDW_series" [{
4 | name = "share/cups/model/hl3170cdw.ppd";
5 | path = "${inputs.brother-hl-3170cdw-driver}/Brother_HL-3170CDW_series.ppd";
6 | }];
7 | in {
8 | # services.printing = {
9 | # enable = true;
10 | # drivers = [
11 | # brother_printer
12 | # ];
13 | # };
14 |
15 | # hardware.printers = {
16 | # ensureDefaultPrinter = "Brother_HL-3170CDW_series";
17 | # ensurePrinters = [{
18 | # name = "Brother_HL-3170CDW_series";
19 | # deviceUri = "usb://Brother/HL-3170CDW%20series?serial=E71798K6J706416";
20 | # model = "hl3170cdw.ppd";
21 | # }];
22 | # };
23 |
24 | # programs.system-config-printer.enable = true;
25 |
26 | hardware.sane.extraBackends = [ pkgs.epkowa pkgs.utsushi ];
27 | services.udev.packages = [ pkgs.epkowa pkgs.utsushi ];
28 | hardware.sane.enable = true;
29 | services.saned.enable = true;
30 |
31 | environment.systemPackages = [ pkgs.simple-scan ];
32 | }
33 |
--------------------------------------------------------------------------------
/profiles/workspace/rclone.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | secrets-envsubst.rclone = {
3 | owner = "balsoft:users";
4 | secrets = [ "nextcloud" ];
5 | services = [ "home-manager-balsoft" ];
6 | template = lib.generators.toINI {} {
7 | nextcloud = {
8 | type = "webdav";
9 | url = "https://nextcloud.balsoft.ru/remote.php/dav/files/balsoft";
10 | vendor = "nextcloud";
11 | user = "balsoft";
12 | pass = "$nextcloud";
13 | };
14 | };
15 | };
16 |
17 | home-manager.users.balsoft.home = {
18 | activation.rclone = ''
19 | mkdir -p $XDG_CONFIG_HOME/rclone
20 | ln -sf ${config.secrets-envsubst.rclone.substituted} $XDG_CONFIG_HOME/rclone/rclone.conf
21 | '';
22 | packages = [ pkgs.rclone ];
23 | };
24 | }
25 |
--------------------------------------------------------------------------------
/profiles/workspace/shadowsocks.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }: {
2 |
3 | secrets.shadowsocks_options = {
4 | owner = "shadowsocks:shadowsocks";
5 | services = [ "shadowsocks" ];
6 | };
7 |
8 | users.users.shadowsocks = {
9 | isSystemUser = true;
10 | group = "shadowsocks";
11 | };
12 |
13 | users.groups.shadowsocks = { };
14 |
15 | systemd.services.shadowsocks = {
16 | script = "ss-local -l 5555 $(cat ${config.secrets.shadowsocks_options})";
17 | path = [ pkgs.shadowsocks-libev ];
18 | serviceConfig = {
19 | User = "shadowsocks";
20 | Group = "shadowsocks";
21 | };
22 | wantedBy = [ "multi-user.target" ];
23 | };
24 | }
25 |
--------------------------------------------------------------------------------
/profiles/workspace/simple-osd-daemons.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }:
2 | let
3 | simple-osd-daemon = name: {
4 | Install.WantedBy = [ "default.target" ];
5 | Service = {
6 | ExecStart = "${pkgs.simple-osd.${name}}/bin/simple-osd-${name}";
7 | Restart = "always";
8 | After = [ "mako.service" ];
9 | Wants = [ "mako.service" ];
10 | };
11 | };
12 | inherit (pkgs.my-lib) genIni;
13 | daemons = names:
14 | builtins.listToAttrs (builtins.map (name: {
15 | name = "simple-osd-${name}";
16 | value = simple-osd-daemon name;
17 | }) names);
18 | in {
19 | home-manager.users.balsoft = {
20 | systemd.user.services = daemons [ "pulseaudio" "mpris" "bluetooth" ]
21 | // pkgs.lib.optionalAttrs (config.deviceSpecific.isLaptop)
22 | (daemons [ "battery" "brightness" ]);
23 | xdg.configFile = {
24 | "simple-osd/common".text =
25 | genIni { progressbar.length = 25; notification."default timeout" = 3; };
26 | "simple-osd/mpris".text =
27 | genIni { default."notification display time" = 3; };
28 | };
29 | };
30 | }
31 |
--------------------------------------------------------------------------------
/profiles/workspace/ssh.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, ... }: {
2 | services.openssh = {
3 | enable = true;
4 | settings = {
5 | PasswordAuthentication = false;
6 | PermitRootLogin = "no";
7 | X11Forwarding = true;
8 | };
9 | extraConfig = "StreamLocalBindUnlink yes";
10 | ports = [ 22 ];
11 | };
12 |
13 | persist.state.etcFiles = [
14 | "ssh/ssh_host_ed25519_key"
15 | "ssh/ssh_host_ed25519_key.pub"
16 | "ssh/ssh_host_rsa_key"
17 | "ssh/ssh_host_rsa_key.pub"
18 | ];
19 |
20 | persist.state.directories = [ "/home/balsoft/.ssh" ];
21 |
22 | users.users.balsoft.openssh.authorizedKeys.keys = [
23 | "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDd2OdcSHUsgezuV+cpFqk9+Svtup6PxIolv1zokVZdqvS8qxLsA/rwYmQgTnuq4/zK/GIxcUCH4OxYlW6Or4M4G7qrDKcLAUrRPWkectqEooWRflZXkfHduMJhzeOAsBdMfYZQ9024GwKr/4yriw2BGa8GbbAnQxiSeTipzvXHoXuRME+/2GsMFAfHFvxzXRG7dNOiLtLaXEjUPUTcw/fffKy55kHtWxMkEvvcdyR53/24fmO3kLVpEuoI+Mp1XFtX3DvRM9ulgfwZUn8/CLhwSLwWX4Xf9iuzVi5vJOJtMOktQj/MwGk4tY/NPe+sIk+nAUKSdVf0y9k9JrJT98S/ comment"
24 | ];
25 |
26 | # secrets.ssh_key = {
27 | # services = [ ];
28 | # decrypted = "/root/.ssh/id_ed25519";
29 | # };
30 |
31 | home-manager.users.balsoft.programs.ssh = {
32 | enable = true;
33 | matchBlocks = { "*" = { compression = false; }; };
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/profiles/workspace/xdg.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | home-manager.users.balsoft = {
3 | xdg.enable = true;
4 | xdg.userDirs.enable = true;
5 | };
6 |
7 | environment.sessionVariables = {
8 | XDG_CURRENT_DESKTOP = "X-Generic";
9 | DE = "generic";
10 | };
11 |
12 | persist.state.directories = map (x: "/home/balsoft/${x}") [
13 | "Pictures"
14 | "Documents"
15 | "Downloads"
16 | "Music"
17 | "projects"
18 | "Videos"
19 | ];
20 | }
21 |
--------------------------------------------------------------------------------
/profiles/workspace/yubikey-touch-detector.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }: {
2 | home-manager.users.balsoft.systemd.user.services.yubikey-touch-detector = {
3 | Service = {
4 | Environment = [ "PATH=${lib.makeBinPath [ pkgs.gnupg pkgs.yubikey-touch-detector ]}" ];
5 | ExecStart = toString (pkgs.writeShellScript "yubikey-touch-detector" ''
6 | export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
7 | yubikey-touch-detector -libnotify
8 | '');
9 | };
10 | Install = rec {
11 | WantedBy = [ "graphical-session.target" ];
12 | Wants = [ "gpg-agent-ssh.socket" "gpg-agent.socket" ];
13 | After = Wants;
14 | };
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/profiles/workspace/zsh/default.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, lib, ... }: {
2 |
3 | environment.pathsToLink = [ "/share/zsh" ];
4 | environment.sessionVariables.SHELL = "${pkgs.zsh}/bin/zsh";
5 |
6 | # A history file is screwed up otherwise :(
7 | persist.state.directories = [ "/home/balsoft/.local/share/zsh" ];
8 |
9 | home-manager.users.balsoft.programs.zsh = {
10 | enable = true;
11 | # enableAutosuggestions = true;
12 | enableCompletion = true;
13 | oh-my-zsh = {
14 | enable = true;
15 | plugins = [ "git" "dirhistory" ];
16 | };
17 |
18 | dotDir = ".config/zsh";
19 |
20 | history = rec {
21 | size = 10000000;
22 | save = size;
23 | path = "$HOME/.local/share/zsh/history";
24 | };
25 | plugins = [
26 | {
27 | name = "zsh-autosuggestions";
28 | src = pkgs.fetchFromGitHub {
29 | owner = "zsh-users";
30 | repo = "zsh-autosuggestions";
31 | rev = "v0.4.0";
32 | sha256 = "0z6i9wjjklb4lvr7zjhbphibsyx51psv50gm07mbb0kj9058j6kc";
33 | };
34 | }
35 | {
36 | name = "you-should-use";
37 | src = pkgs.fetchFromGitHub {
38 | owner = "MichaelAquilina";
39 | repo = "zsh-you-should-use";
40 | rev = "2be37f376c13187c445ae9534550a8a5810d4361";
41 | sha256 = "0yhwn6av4q6hz9s34h4m3vdk64ly6s28xfd8ijgdbzic8qawj5p1";
42 | };
43 | }
44 | {
45 | name = "async";
46 | file = "async.zsh";
47 | src = pkgs.fetchFromGitHub {
48 | owner = "mafredri";
49 | repo = "zsh-async";
50 | rev = "3ba6e2d1ea874bfb6badb8522ab86c1ae272923d";
51 | sha256 = "3hhZXL8/Ml7UlkkHBPpS5NfUGB5BqgO95UvtpptXf8E=";
52 | };
53 | }
54 | {
55 | name = "powerlevel10k-config";
56 | src = ./.;
57 | file = "p10k.zsh";
58 | }
59 | {
60 | name = "zsh-powerlevel10k";
61 | src = pkgs.zsh-powerlevel10k;
62 | file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
63 | }
64 | ];
65 | shellAliases = {
66 | "b" = "nix build";
67 | "p" = "nix-shell --run zsh -p";
68 | "s" = "nix shell";
69 | "e" = "$EDITOR";
70 | "dog" = "$EDITOR -";
71 | "d" = "nix develop";
72 | "r" = "nix run";
73 | "f" = "nix search";
74 | "fs" = "nix search self";
75 | "o" = "xdg-open";
76 | "post" = ''curl -F"file=@-" https://0x0.st'';
77 | "cat" = "${pkgs.bat}/bin/bat";
78 | "ls" = "${pkgs.eza}/bin/eza";
79 | "gp" = "git push && github_status_reset_bg";
80 | "gpf!" = "git push --force-with-lease && github_status_reset_bg";
81 | };
82 | initContent = ''
83 | cmdignore=(htop tmux top vim)
84 |
85 | export GITHUB_TOKEN=$(cat /var/secrets/github_token)
86 |
87 | # end and compare timer, notify-send if needed
88 | function notifyosd-precmd() {
89 | retval=$?
90 | if [ ! -z "$cmd" ]; then
91 | cmd_end=`date +%s`
92 | ((cmd_time=$cmd_end - $cmd_start))
93 | fi
94 | cleareol="\e[K"
95 | colorreset="\e[1;0m"
96 | if [ $retval -eq 0 ]; then
97 | cmdstat="✓"
98 | bgcolor="\e[1;30;42m"
99 | fgcolor="\e[1;32;40m"
100 | else
101 | cmdstat="✘"
102 | bgcolor="\e[1;41m"
103 | fgcolor="\e[1;31;40m"
104 | printf "$bgcolor $cmdstat $retval $colorreset\n"
105 | fi
106 | if [ ! -z "$cmd" ]; then
107 | if [[ $cmd_time -gt 3 ]]; then
108 | ${pkgs.libnotify}/bin/notify-send -a command_complete -i utilities-terminal -u low "$cmdstat $cmd" "in `date -u -d @$cmd_time +'%T'`"
109 | echo -e '\a'
110 | fi
111 | fi
112 | unset cmd
113 | }
114 |
115 | # make sure this plays nicely with any existing precmd
116 | precmd_functions+=( notifyosd-precmd )
117 |
118 | # get command name and start the timer
119 | function notifyosd-preexec() {
120 | cmd=$1
121 | cmd_start=`date +%s`
122 | }
123 |
124 | bindkey -v
125 | bindkey -M viins '^H' backward-kill-word
126 |
127 | # make sure this plays nicely with any existing preexec
128 | preexec_functions+=( notifyosd-preexec )
129 | XDG_DATA_DIRS=$XDG_DATA_DIRS:$GSETTINGS_SCHEMAS_PATH
130 |
131 | function repl() {
132 | source="$(nix flake prefetch --json "$1" | ${pkgs.jq}/bin/jq -r .storePath)"
133 | TEMP="$(mktemp --suffix=.nix)"
134 | echo "let self = builtins.getFlake \"$source\"; in self // self.legacyPackages.\''${builtins.currentSystem} or { } // self.packages.\''${builtins.currentSystem} or { }" > "$TEMP"
135 | nix repl "$TEMP"
136 | rm "$TEMP"
137 | }
138 |
139 |
140 | function ss() { nix shell "self#$1" }
141 | function es() { nix edit "self#$1" }
142 | function bs() { nix build "self#$1" }
143 | function is() { nix search "self#$1" }
144 | function rs() { repl self }
145 |
146 | zle_highlight=(default:bg=#333333,fg=white)
147 |
148 | PS1="$PS1
149 | $ "
150 | '';
151 | };
152 | }
153 |
--------------------------------------------------------------------------------
/roles/base.nix:
--------------------------------------------------------------------------------
1 | { inputs, ... }: {
2 | imports = with inputs.self.nixosProfiles; [
3 | # PROFILES
4 | autoRun
5 | xdg
6 |
7 | git
8 | gpg
9 | locale
10 | misc
11 | network
12 | nix
13 | user
14 | ssh
15 | zsh
16 | ];
17 | }
18 |
--------------------------------------------------------------------------------
/roles/default.nix:
--------------------------------------------------------------------------------
1 | {
2 | server = ./server.nix;
3 | desktop = ./desktop.nix;
4 | base = ./base.nix;
5 | }
6 |
--------------------------------------------------------------------------------
/roles/desktop.nix:
--------------------------------------------------------------------------------
1 | { inputs, ... }: {
2 | imports = with inputs.self.nixosProfiles; [
3 | ./base.nix
4 |
5 | boot
6 |
7 | # PROFILES
8 | applications-setup
9 | bluetooth
10 | power
11 | opengl
12 | hardware
13 | sound
14 | virtualisation
15 |
16 | yubikey
17 | vlock
18 |
19 | alacritty
20 | aerc
21 | # cantata
22 | # emacs
23 | # vscodium
24 | helix
25 | firefox
26 | # geary
27 | github
28 | gwenview
29 | himalaya
30 | nheko
31 | packages
32 | okular
33 | josm
34 |
35 | pass-secret-service
36 | rclone
37 | copyq
38 | cursor
39 | direnv
40 | fonts
41 | gnome3
42 | gtk
43 | i3blocks
44 | qt
45 | slack
46 | kdeconnect
47 | light
48 | mako
49 | # mopidy
50 | simple-osd-daemons
51 | sway
52 | yubikey-touch-detector
53 | btop
54 | ];
55 | }
56 |
--------------------------------------------------------------------------------
/roles/server.nix:
--------------------------------------------------------------------------------
1 | { inputs, ... }: {
2 | imports = [
3 | ./base.nix
4 |
5 | inputs.self.nixosProfiles.boot
6 | ];
7 |
8 | security.sudo.wheelNeedsPassword = false;
9 | }
10 |
--------------------------------------------------------------------------------
/shell.nix:
--------------------------------------------------------------------------------
1 | (import
2 | (
3 | let
4 | lock = builtins.fromJSON (builtins.readFile ./flake.lock);
5 | in
6 | fetchTarball {
7 | url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
8 | sha256 = lock.nodes.flake-compat.locked.narHash;
9 | }
10 | )
11 | {
12 | src = ./.;
13 | }).shellNix
14 |
--------------------------------------------------------------------------------