Reorganize imports
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
16
hosts/common/configs/system/bluetooth/default.nix
Normal file
16
hosts/common/configs/system/bluetooth/default.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{ config, ... }:
|
||||
{
|
||||
hardware.bluetooth = {
|
||||
enable = true;
|
||||
powerOnBoot = true;
|
||||
settings = {
|
||||
General.Experimental = true;
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence."/persist"."/var/lib/bluetooth" = { };
|
||||
|
||||
systemd.services.bluetooth.after = [
|
||||
config.environment.persistence."/persist"."/var/lib/bluetooth".mount
|
||||
];
|
||||
}
|
20
hosts/common/configs/system/boot/default.nix
Normal file
20
hosts/common/configs/system/boot/default.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
boot = {
|
||||
loader = {
|
||||
systemd-boot = {
|
||||
enable = true;
|
||||
editor = false;
|
||||
};
|
||||
|
||||
timeout = 1;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
initrd.systemd.enable = true;
|
||||
kernelPackages = pkgs.linuxPackages_latest;
|
||||
supportedFilesystems = [
|
||||
"btrfs"
|
||||
"ntfs"
|
||||
];
|
||||
};
|
||||
}
|
16
hosts/common/configs/system/brightnessctl/default.nix
Normal file
16
hosts/common/configs/system/brightnessctl/default.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [ brightnessctl ];
|
||||
|
||||
services.udev.extraRules =
|
||||
let
|
||||
chgrp = "${pkgs.coreutils}/bin/chgrp";
|
||||
chmod = "${pkgs.coreutils}/bin/chmod";
|
||||
in
|
||||
''
|
||||
ACTION=="add", SUBSYSTEM=="backlight", RUN+="${chgrp} video /sys/class/backlight/%k/brightness"
|
||||
ACTION=="add", SUBSYSTEM=="backlight", RUN+="${chmod} g+w /sys/class/backlight/%k/brightness"
|
||||
ACTION=="add", SUBSYSTEM=="leds", RUN+="${chgrp} input /sys/class/leds/%k/brightness"
|
||||
ACTION=="add", SUBSYSTEM=="leds", RUN+="${chmod} g+w /sys/class/leds/%k/brightness"
|
||||
'';
|
||||
}
|
4
hosts/common/configs/system/btop/default.nix
Normal file
4
hosts/common/configs/system/btop/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [ btop ];
|
||||
}
|
7
hosts/common/configs/system/btrfs/default.nix
Normal file
7
hosts/common/configs/system/btrfs/default.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.btrfs.autoScrub = {
|
||||
enable = true;
|
||||
interval = "weekly";
|
||||
};
|
||||
}
|
4
hosts/common/configs/system/cpu/default.nix
Normal file
4
hosts/common/configs/system/cpu/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ ... }:
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
}
|
17
hosts/common/configs/system/cpu/options.nix
Normal file
17
hosts/common/configs/system/cpu/options.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
options.hardware.cpu =
|
||||
with lib;
|
||||
with types;
|
||||
{
|
||||
cores = mkOption {
|
||||
type = ints.positive;
|
||||
description = "The number of cpu cores.";
|
||||
};
|
||||
|
||||
threads = mkOption {
|
||||
type = ints.positive;
|
||||
description = "The number of cpu threads.";
|
||||
};
|
||||
};
|
||||
}
|
29
hosts/common/configs/system/docker/default.nix
Normal file
29
hosts/common/configs/system/docker/default.nix
Normal file
@@ -0,0 +1,29 @@
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
virtualisation.docker = {
|
||||
enable = true;
|
||||
enableOnBoot = false;
|
||||
storageDriver = "btrfs";
|
||||
|
||||
daemon.settings = {
|
||||
experimental = true;
|
||||
ipv6 = true;
|
||||
fixed-cidr-v6 = "fd00::/80";
|
||||
};
|
||||
|
||||
autoPrune = {
|
||||
enable = true;
|
||||
flags = [ "--all" ];
|
||||
};
|
||||
};
|
||||
|
||||
environment = {
|
||||
persistence."/persist"."/var/lib/docker" = { };
|
||||
systemPackages = with pkgs; [ docker-compose ];
|
||||
};
|
||||
|
||||
systemd = {
|
||||
services.docker.after = [ config.environment.persistence."/persist"."/var/lib/docker".mount ];
|
||||
sockets.docker.after = [ config.environment.persistence."/persist"."/var/lib/docker".mount ];
|
||||
};
|
||||
}
|
4
hosts/common/configs/system/fastfetch/default.nix
Normal file
4
hosts/common/configs/system/fastfetch/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [ fastfetch ];
|
||||
}
|
9
hosts/common/configs/system/getty/default.nix
Normal file
9
hosts/common/configs/system/getty/default.nix
Normal file
@@ -0,0 +1,9 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
services.getty.extraArgs = lib.mkIf (config.services.getty.autologinUser != null) [
|
||||
"--skip-login"
|
||||
"--noissue"
|
||||
"--nohints"
|
||||
"--nohostname"
|
||||
];
|
||||
}
|
7
hosts/common/configs/system/git/default.nix
Normal file
7
hosts/common/configs/system/git/default.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
{ ... }:
|
||||
{
|
||||
programs.git = {
|
||||
enable = true;
|
||||
lfs.enable = true;
|
||||
};
|
||||
}
|
4
hosts/common/configs/system/gpg-agent/default.nix
Normal file
4
hosts/common/configs/system/gpg-agent/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ ... }:
|
||||
{
|
||||
programs.gnupg.agent.enable = true;
|
||||
}
|
45
hosts/common/configs/system/impermanence/default.nix
Normal file
45
hosts/common/configs/system/impermanence/default.nix
Normal file
@@ -0,0 +1,45 @@
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
imports = [ ./options.nix ];
|
||||
|
||||
boot.initrd.systemd = {
|
||||
enable = true;
|
||||
|
||||
initrdBin = with pkgs; [
|
||||
coreutils
|
||||
util-linux
|
||||
findutils
|
||||
btrfs-progs
|
||||
];
|
||||
|
||||
services.impermanence = {
|
||||
description = "Rollback BTRFS subvolumes to a pristine state";
|
||||
wantedBy = [ "initrd.target" ];
|
||||
before = [ "sysroot.mount" ];
|
||||
after = [ "cryptsetup.target" ];
|
||||
unitConfig.DefaultDependencies = false;
|
||||
serviceConfig.Type = "oneshot";
|
||||
environment.DEVICE = config.environment.impermanence.device;
|
||||
script = builtins.readFile ./scripts/wipe.sh;
|
||||
};
|
||||
};
|
||||
|
||||
# uuidgen -r | tr -d -
|
||||
# https://github.com/NixOS/nixpkgs/blob/master/nixos/doc/manual/administration/systemd-state.section.md
|
||||
# https://github.com/NixOS/nixpkgs/pull/286140/files
|
||||
# https://git.eisfunke.com/config/nixos/-/blob/e65e1dc21d06d07b454005762b177ef151f8bfb6/nixos/machine-id.nix
|
||||
sops.secrets."machineId".mode = "0444";
|
||||
|
||||
environment = {
|
||||
etc."machine-id".source = pkgs.runCommandLocal "machine-id-link" { } ''
|
||||
ln -s ${config.sops.secrets."machineId".path} $out
|
||||
'';
|
||||
|
||||
persistence."/persist" = {
|
||||
"/etc/nixos" = { };
|
||||
"/var/lib/nixos" = { };
|
||||
"/var/lib/systemd" = { };
|
||||
"/var/log" = { };
|
||||
};
|
||||
};
|
||||
}
|
258
hosts/common/configs/system/impermanence/options.nix
Normal file
258
hosts/common/configs/system/impermanence/options.nix
Normal file
@@ -0,0 +1,258 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.environment.persistence;
|
||||
|
||||
# ["/home/user/" "/.screenrc"] -> ["home" "user" ".screenrc"]
|
||||
splitPath =
|
||||
paths:
|
||||
(builtins.filter (s: builtins.typeOf s == "string" && s != "") (
|
||||
builtins.concatMap (builtins.split "/") paths
|
||||
));
|
||||
|
||||
# ["/home/user/" "/.screenrc"] -> "/home/user/.screenrc"
|
||||
mergePaths =
|
||||
paths:
|
||||
let
|
||||
prefix = lib.strings.optionalString (lib.strings.hasPrefix "/" (builtins.head paths)) "/";
|
||||
path = lib.strings.concatStringsSep "/" (splitPath paths);
|
||||
in
|
||||
prefix + path;
|
||||
|
||||
# "/home/user/.screenrc" -> ["/home", "/home/user"]
|
||||
parentsOf =
|
||||
path:
|
||||
let
|
||||
prefix = lib.strings.optionalString (lib.strings.hasPrefix "/" path) "/";
|
||||
split = splitPath [ path ];
|
||||
parents = lib.lists.take ((lib.lists.length split) - 1) split;
|
||||
in
|
||||
lib.lists.foldl' (
|
||||
state: item:
|
||||
state
|
||||
++ [
|
||||
(mergePaths [
|
||||
(if state != [ ] then lib.lists.last state else prefix)
|
||||
item
|
||||
])
|
||||
]
|
||||
) [ ] parents;
|
||||
in
|
||||
{
|
||||
options.environment =
|
||||
with lib;
|
||||
with types;
|
||||
{
|
||||
impermanence.device = mkOption {
|
||||
type = str;
|
||||
default = config.disko.devices.disk.main.content.partitions.root.content.name;
|
||||
description = ''
|
||||
LUKS BTRFS partition to wipe on boot.
|
||||
'';
|
||||
};
|
||||
|
||||
persistence =
|
||||
let
|
||||
isPathLike = strings.hasPrefix "/";
|
||||
in
|
||||
mkOption {
|
||||
type = (
|
||||
addCheck (attrsOf (
|
||||
attrsOf (
|
||||
submodule (
|
||||
{ name, config, ... }:
|
||||
{
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = "Whether to enable the item.";
|
||||
};
|
||||
|
||||
service = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
description = ''
|
||||
Systemd service that prepares and syncs the item.
|
||||
Can be used as a dependency in other units.
|
||||
'';
|
||||
};
|
||||
|
||||
mount = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
description = ''
|
||||
Systemd mount that binds the item.
|
||||
Can be used as a dependency in other units.
|
||||
'';
|
||||
};
|
||||
|
||||
_path = mkOption {
|
||||
type = str;
|
||||
internal = true;
|
||||
default = name;
|
||||
};
|
||||
|
||||
_sourceRoot = mkOption {
|
||||
type = str;
|
||||
internal = true;
|
||||
};
|
||||
|
||||
_source = mkOption {
|
||||
type = str;
|
||||
internal = true;
|
||||
};
|
||||
|
||||
_targetRoot = mkOption {
|
||||
type = str;
|
||||
internal = true;
|
||||
};
|
||||
|
||||
_target = mkOption {
|
||||
type = str;
|
||||
internal = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
)
|
||||
)) (attrs: lists.all isPathLike (builtins.attrNames attrs))
|
||||
);
|
||||
apply =
|
||||
ps:
|
||||
builtins.mapAttrs (
|
||||
persistence: items:
|
||||
builtins.mapAttrs (
|
||||
_: config:
|
||||
let
|
||||
_path = config._path;
|
||||
|
||||
_sourceRoot = persistence;
|
||||
|
||||
_source = mergePaths [
|
||||
_sourceRoot
|
||||
_path
|
||||
];
|
||||
|
||||
_targetRoot =
|
||||
let
|
||||
parents = lists.reverseList (parentsOf _path);
|
||||
in
|
||||
lists.foldl' (
|
||||
acc: parent:
|
||||
if acc == "/" then
|
||||
lists.findFirst (
|
||||
otherPersistence: lists.any (other: parent == other) (builtins.attrNames ps.${otherPersistence})
|
||||
) "/" (builtins.attrNames ps)
|
||||
else
|
||||
acc
|
||||
) "/" parents;
|
||||
|
||||
_target = mergePaths [
|
||||
_targetRoot
|
||||
_path
|
||||
];
|
||||
in
|
||||
config
|
||||
// {
|
||||
inherit
|
||||
_sourceRoot
|
||||
_source
|
||||
_targetRoot
|
||||
_target
|
||||
;
|
||||
service = "${utils.escapeSystemdPath _target}.service";
|
||||
mount = "${utils.escapeSystemdPath _target}.mount";
|
||||
}
|
||||
) items
|
||||
) ps;
|
||||
default = { };
|
||||
description = "Persistence config.";
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
all = lib.lists.flatten (builtins.concatMap builtins.attrValues (builtins.attrValues cfg));
|
||||
in
|
||||
{
|
||||
fileSystems = builtins.mapAttrs (_: _: { neededForBoot = true; }) cfg;
|
||||
|
||||
systemd = {
|
||||
mounts = builtins.map (c: {
|
||||
description = c._path;
|
||||
requiredBy = [ "local-fs.target" ];
|
||||
requires = [ c.service ];
|
||||
bindsTo = [ c.service ];
|
||||
after = [ c.service ];
|
||||
unitConfig.ConditionPathExists = [ (lib.strings.escape [ " " ] c._source) ];
|
||||
what = c._source;
|
||||
where = c._target;
|
||||
options = lib.strings.concatStringsSep "," ([
|
||||
"bind"
|
||||
"X-fstrim.notrim"
|
||||
"x-gvfs-hide"
|
||||
]);
|
||||
}) all;
|
||||
|
||||
services = builtins.listToAttrs (
|
||||
builtins.map (c: {
|
||||
name = utils.escapeSystemdPath c._target;
|
||||
value = {
|
||||
description = c._path;
|
||||
after = [ "local-fs-pre.target" ];
|
||||
requiredBy = [
|
||||
"local-fs.target"
|
||||
c.mount
|
||||
];
|
||||
before = [
|
||||
"local-fs.target"
|
||||
c.mount
|
||||
"umount.target"
|
||||
];
|
||||
conflicts = [ "umount.target" ];
|
||||
unitConfig = {
|
||||
DefaultDependencies = false;
|
||||
RefuseManualStart = true;
|
||||
RefuseManualStop = true;
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
source=${lib.strings.escapeShellArg c._sourceRoot}
|
||||
target=${lib.strings.escapeShellArg c._targetRoot}
|
||||
path=${lib.strings.escapeShellArg c._path}
|
||||
|
||||
${builtins.readFile ./scripts/start.sh}
|
||||
'';
|
||||
preStop = ''
|
||||
source=${lib.strings.escapeShellArg c._sourceRoot}
|
||||
target=${lib.strings.escapeShellArg c._targetRoot}
|
||||
path=${lib.strings.escapeShellArg c._path}
|
||||
|
||||
${builtins.readFile ./scripts/stop.sh}
|
||||
'';
|
||||
};
|
||||
}) all
|
||||
);
|
||||
};
|
||||
|
||||
assertions =
|
||||
let
|
||||
paths = builtins.map (c: c._path) all;
|
||||
duplicates = lib.lists.filter (t: lib.lists.count (o: o == t) paths > 1) (lib.lists.unique paths);
|
||||
in
|
||||
[
|
||||
{
|
||||
assertion = lib.lists.length duplicates == 0;
|
||||
message = "Each target must be defined under a single persistence. Duplicate targets found: ${lib.concatStringsSep ", " duplicates}";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
19
hosts/common/configs/system/impermanence/scripts/start.sh
Normal file
19
hosts/common/configs/system/impermanence/scripts/start.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
echo "Starting impermanence mount with source: ${source}, target: ${target}, path: ${path}."
|
||||
|
||||
source_current="${source}"
|
||||
target_current="${target}"
|
||||
|
||||
IFS='/' read -ra path_parts <<< "${path}"
|
||||
unset "path_parts[-1]"
|
||||
|
||||
for part in "${path_parts[@]}"; do
|
||||
source_current="${source_current}/${part}"
|
||||
target_current="${target_current}/${part}"
|
||||
|
||||
if [[ ! -d "${source_current}" ]]; then
|
||||
break
|
||||
fi
|
||||
|
||||
read -r mode owner group <<< "$(stat -c '%a %u %g' "${source_current}")"
|
||||
install -d -m "${mode}" -o "${owner}" -g "${group}" "${target_current}"
|
||||
done
|
38
hosts/common/configs/system/impermanence/scripts/stop.sh
Normal file
38
hosts/common/configs/system/impermanence/scripts/stop.sh
Normal file
@@ -0,0 +1,38 @@
|
||||
echo "Stopping impermanence mount with source: ${source}, target: ${target}, path: ${path}."
|
||||
|
||||
source_current="${source}"
|
||||
target_current="${target}"
|
||||
|
||||
IFS='/' read -ra path_parts <<< "${path}"
|
||||
unset "path_parts[-1]"
|
||||
|
||||
for part in "${path_parts[@]}"; do
|
||||
source_current="${source_current}/${part}"
|
||||
target_current="${target_current}/${part}"
|
||||
|
||||
if [[ ! -d "${target_current}" ]]; then
|
||||
break
|
||||
fi
|
||||
|
||||
if [[ -d "${source_current}" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
read -r mode owner group <<< "$(stat -c '%a %u %g' "${target_current}")"
|
||||
install -d -m "${mode}" -o "${owner}" -g "${group}" "${source_current}"
|
||||
done
|
||||
|
||||
source=$(realpath -m "${source}/${path}")
|
||||
target=$(realpath -m "${target}/${path}")
|
||||
|
||||
if [[ ! -e "${target}" ]] || { [[ -d "${target}" ]] && [[ -z "$(ls -A "${target}")" ]]; } || { [[ -f "${target}" ]] && [[ ! -s "${target}" ]]; }; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -e "${source}" ]]; then
|
||||
>&2 echo "Error: Source ${source} already exists. Cannot move ${target} to ${source}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Moving target ${target} to source ${source}."
|
||||
mv "${target}" "${source}"
|
30
hosts/common/configs/system/impermanence/scripts/wipe.sh
Normal file
30
hosts/common/configs/system/impermanence/scripts/wipe.sh
Normal file
@@ -0,0 +1,30 @@
|
||||
delete_subvolume_recursively() {
|
||||
IFS=$'\n'
|
||||
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
|
||||
delete_subvolume_recursively "/mnt/btrfs/${i}"
|
||||
done
|
||||
btrfs subvolume delete "$1"
|
||||
}
|
||||
|
||||
if [[ -z "$DEVICE" ]]; then
|
||||
echo "Error: DEVICE variable is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p /mnt/btrfs
|
||||
mount "/dev/mapper/$DEVICE" /mnt/btrfs
|
||||
|
||||
if [[ -e /mnt/btrfs/@ ]]; then
|
||||
mkdir -p /mnt/btrfs/@.bak
|
||||
timestamp=$(date --date="@$(stat -c %Y /mnt/btrfs/@)" "+%Y-%m-%d_%H:%M:%S")
|
||||
mv /mnt/btrfs/@ "/mnt/btrfs/@.bak/${timestamp}"
|
||||
fi
|
||||
|
||||
find /mnt/btrfs/@.bak/ -maxdepth 1 -mtime +14 | while IFS= read -r i; do
|
||||
delete_subvolume_recursively "${i}"
|
||||
done
|
||||
|
||||
btrfs subvolume create /mnt/btrfs/@
|
||||
|
||||
umount /mnt/btrfs
|
||||
rmdir /mnt/btrfs
|
39
hosts/common/configs/system/libvirt/default.nix
Normal file
39
hosts/common/configs/system/libvirt/default.nix
Normal file
@@ -0,0 +1,39 @@
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
virtualisation = {
|
||||
libvirtd = {
|
||||
enable = true;
|
||||
qemu = {
|
||||
swtpm.enable = true;
|
||||
ovmf.packages = [ pkgs.OVMFFull.fd ];
|
||||
};
|
||||
};
|
||||
|
||||
spiceUSBRedirection.enable = true;
|
||||
};
|
||||
|
||||
systemd.services.libvirtd-network-default = {
|
||||
description = "Start Default Virtual Network for Libvirt";
|
||||
script = "${config.virtualisation.libvirtd.package}/bin/virsh net-start default";
|
||||
preStop = "${config.virtualisation.libvirtd.package}/bin/virsh net-destroy default";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
wantedBy = [ "libvirtd.service" ];
|
||||
after = [ "libvirtd.service" ];
|
||||
};
|
||||
|
||||
environment = {
|
||||
systemPackages = [ config.virtualisation.libvirtd.qemu.swtpm.package ];
|
||||
etc = {
|
||||
"ovmf/edk2-x86_64-secure-code.fd".source =
|
||||
"${config.virtualisation.libvirtd.qemu.package}/share/qemu/edk2-x86_64-secure-code.fd";
|
||||
"ovmf/edk2-i386-vars.fd".source =
|
||||
"${config.virtualisation.libvirtd.qemu.package}/share/qemu/edk2-i386-vars.fd";
|
||||
};
|
||||
persistence."/persist"."/var/lib/libvirt" = { };
|
||||
};
|
||||
|
||||
programs.virt-manager.enable = true;
|
||||
}
|
4
hosts/common/configs/system/lsof/default.nix
Normal file
4
hosts/common/configs/system/lsof/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [ lsof ];
|
||||
}
|
13
hosts/common/configs/system/ncdu/default.nix
Normal file
13
hosts/common/configs/system/ncdu/default.nix
Normal file
@@ -0,0 +1,13 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment = {
|
||||
systemPackages = with pkgs; [ ncdu ];
|
||||
|
||||
etc."ncdu.conf".text = ''
|
||||
-1
|
||||
-e
|
||||
-t 0
|
||||
--confirm-quit
|
||||
'';
|
||||
};
|
||||
}
|
9
hosts/common/configs/system/neovim/default.nix
Normal file
9
hosts/common/configs/system/neovim/default.nix
Normal file
@@ -0,0 +1,9 @@
|
||||
{ ... }:
|
||||
{
|
||||
programs.neovim = {
|
||||
enable = true;
|
||||
defaultEditor = true;
|
||||
viAlias = true;
|
||||
vimAlias = true;
|
||||
};
|
||||
}
|
10
hosts/common/configs/system/networking/default.nix
Normal file
10
hosts/common/configs/system/networking/default.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{ config, ... }:
|
||||
{
|
||||
networking.networkmanager.enable = true;
|
||||
|
||||
environment.persistence."/persist"."/etc/NetworkManager/system-connections" = { };
|
||||
|
||||
systemd.services.NetworkManager.after = [
|
||||
config.environment.persistence."/persist"."/etc/NetworkManager/system-connections".mount
|
||||
];
|
||||
}
|
41
hosts/common/configs/system/nix-cleanup/cleanup.sh
Normal file
41
hosts/common/configs/system/nix-cleanup/cleanup.sh
Normal file
@@ -0,0 +1,41 @@
|
||||
if [[ "${EUID}" -ne 0 ]]; then
|
||||
echo "Please run the script as root."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
delete_subvolume_recursively() {
|
||||
IFS=$'\n'
|
||||
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
|
||||
delete_subvolume_recursively "/mnt/btrfs/${i}"
|
||||
done
|
||||
btrfs subvolume delete "$1"
|
||||
}
|
||||
|
||||
if [[ -e /mnt/btrfs && -n $(mountpoint -q /mnt/btrfs) ]]; then
|
||||
echo "/mnt/btrfs is already mounted. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$DEVICE" ]]; then
|
||||
echo "Error: DEVICE variable is not set."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p /mnt/btrfs
|
||||
mount "/dev/mapper/$DEVICE" /mnt/btrfs
|
||||
|
||||
if [[ -e /mnt/btrfs/@.bak ]]; then
|
||||
if [[ -n "$(ls -A /mnt/btrfs/@.bak)" ]]; then
|
||||
for i in /mnt/btrfs/@.bak/*; do
|
||||
delete_subvolume_recursively "${i}"
|
||||
done
|
||||
else
|
||||
echo "/mnt/btrfs/@.bak is empty. Nothing to delete."
|
||||
fi
|
||||
fi
|
||||
|
||||
umount /mnt/btrfs
|
||||
rmdir /mnt/btrfs
|
||||
|
||||
nix-collect-garbage -d
|
||||
nix-store --gc -v
|
17
hosts/common/configs/system/nix-cleanup/default.nix
Normal file
17
hosts/common/configs/system/nix-cleanup/default.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellApplication {
|
||||
name = "nix-cleanup";
|
||||
runtimeInputs = with pkgs; [
|
||||
coreutils
|
||||
util-linux
|
||||
findutils
|
||||
btrfs-progs
|
||||
nix
|
||||
];
|
||||
runtimeEnv.DEVICE = config.environment.impermanence.device;
|
||||
text = builtins.readFile ./cleanup.sh;
|
||||
})
|
||||
];
|
||||
}
|
7
hosts/common/configs/system/nix-ld/default.nix
Normal file
7
hosts/common/configs/system/nix-ld/default.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
{ ... }:
|
||||
{
|
||||
programs.nix-ld = {
|
||||
enable = true;
|
||||
libraries = [ ];
|
||||
};
|
||||
}
|
25
hosts/common/configs/system/nix/default.nix
Normal file
25
hosts/common/configs/system/nix/default.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
{ config, inputs, ... }:
|
||||
{
|
||||
sops.secrets."nix/accessTokens/github" = {
|
||||
sopsFile = ../../../../../secrets/personal/secrets.yaml;
|
||||
group = "users";
|
||||
};
|
||||
|
||||
nix = {
|
||||
settings = {
|
||||
use-xdg-base-directories = true;
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
};
|
||||
|
||||
registry.self.flake = inputs.self;
|
||||
gc.automatic = true;
|
||||
optimise.automatic = true;
|
||||
|
||||
extraOptions = ''
|
||||
!include ${config.sops.secrets."nix/accessTokens/github".path}
|
||||
'';
|
||||
};
|
||||
}
|
6
hosts/common/configs/system/nixpkgs/default.nix
Normal file
6
hosts/common/configs/system/nixpkgs/default.nix
Normal file
@@ -0,0 +1,6 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
imports = [ inputs.nur.modules.nixos.default ];
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
}
|
4
hosts/common/configs/system/ntp/default.nix
Normal file
4
hosts/common/configs/system/ntp/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.ntp.enable = true;
|
||||
}
|
20
hosts/common/configs/system/pipewire/default.nix
Normal file
20
hosts/common/configs/system/pipewire/default.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
alsa = {
|
||||
enable = true;
|
||||
support32Bit = true;
|
||||
};
|
||||
pulse.enable = true;
|
||||
jack.enable = true;
|
||||
extraConfig.pipewire-pulse = {
|
||||
pulse.cmd = [
|
||||
{
|
||||
cmd = "load-module";
|
||||
args = "module-switch-on-connect";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
27
hosts/common/configs/system/plymouth/default.nix
Normal file
27
hosts/common/configs/system/plymouth/default.nix
Normal file
@@ -0,0 +1,27 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
boot = {
|
||||
plymouth =
|
||||
let
|
||||
theme = "connect";
|
||||
in
|
||||
{
|
||||
enable = true;
|
||||
inherit theme;
|
||||
themePackages = with pkgs; [ (adi1090x-plymouth-themes.override { selected_themes = [ theme ]; }) ];
|
||||
};
|
||||
|
||||
initrd.verbose = false;
|
||||
consoleLogLevel = 0;
|
||||
|
||||
kernelParams = [
|
||||
"quiet"
|
||||
"loglevel=3"
|
||||
"splash"
|
||||
"boot.shell_on_fail"
|
||||
"rd.systemd.show_status=false"
|
||||
"rd.udev.log_level=3"
|
||||
"udev.log_priority=3"
|
||||
];
|
||||
};
|
||||
}
|
5
hosts/common/configs/system/powertop/default.nix
Normal file
5
hosts/common/configs/system/powertop/default.nix
Normal file
@@ -0,0 +1,5 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [ powertop ];
|
||||
powerManagement.powertop.enable = true;
|
||||
}
|
36
hosts/common/configs/system/printing/default.nix
Normal file
36
hosts/common/configs/system/printing/default.nix
Normal file
@@ -0,0 +1,36 @@
|
||||
{ pkgs, config, ... }:
|
||||
{
|
||||
services = {
|
||||
printing = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
drivers = with pkgs; [
|
||||
epson-escpr # Greece, Athens, Home
|
||||
];
|
||||
};
|
||||
|
||||
avahi = {
|
||||
enable = true;
|
||||
nssmdns4 = true;
|
||||
ipv6 = true;
|
||||
nssmdns6 = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence."/persist" = {
|
||||
"/var/lib/cups/ppd" = { };
|
||||
"/var/lib/cups/printers.conf" = { };
|
||||
};
|
||||
|
||||
systemd = {
|
||||
services.cups.after = [
|
||||
config.environment.persistence."/persist"."/var/lib/cups/ppd".mount
|
||||
config.environment.persistence."/persist"."/var/lib/cups/printers.conf".mount
|
||||
];
|
||||
sockets.cups.after = [
|
||||
config.environment.persistence."/persist"."/var/lib/cups/ppd".mount
|
||||
config.environment.persistence."/persist"."/var/lib/cups/printers.conf".mount
|
||||
];
|
||||
};
|
||||
}
|
4
hosts/common/configs/system/ranger/default.nix
Normal file
4
hosts/common/configs/system/ranger/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [ ranger ];
|
||||
}
|
15
hosts/common/configs/system/sops/default.nix
Normal file
15
hosts/common/configs/system/sops/default.nix
Normal file
@@ -0,0 +1,15 @@
|
||||
{ inputs, pkgs, ... }:
|
||||
{
|
||||
imports = [ inputs.sops-nix.nixosModules.sops ];
|
||||
|
||||
environment = {
|
||||
persistence."/persist"."/etc/ssh/ssh_host_ed25519_key" = { };
|
||||
systemPackages = with pkgs; [ sops ];
|
||||
};
|
||||
|
||||
sops.age = {
|
||||
generateKey = true;
|
||||
sshKeyPaths = [ "/persist/etc/ssh/ssh_host_ed25519_key" ];
|
||||
keyFile = "/var/lib/sops-nix/key.txt";
|
||||
};
|
||||
}
|
10
hosts/common/configs/system/ssh/default.nix
Normal file
10
hosts/common/configs/system/ssh/default.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{ ... }:
|
||||
{
|
||||
programs.ssh = {
|
||||
knownHosts = {
|
||||
installer.publicKeyFile = ../../../../installer/secrets/ssh_host_ed25519_key.pub;
|
||||
eirene.publicKeyFile = ../../../../eirene/secrets/ssh_host_ed25519_key.pub;
|
||||
elara.publicKeyFile = ../../../../elara/secrets/ssh_host_ed25519_key.pub;
|
||||
};
|
||||
};
|
||||
}
|
17
hosts/common/configs/system/system/default.nix
Normal file
17
hosts/common/configs/system/system/default.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
system = {
|
||||
autoUpgrade = {
|
||||
enable = true;
|
||||
flake = inputs.self.outPath;
|
||||
flags = [
|
||||
"--update-input"
|
||||
"nixpkgs"
|
||||
"-L"
|
||||
];
|
||||
dates = "02:00";
|
||||
};
|
||||
|
||||
stateVersion = "24.11";
|
||||
};
|
||||
}
|
14
hosts/common/configs/system/timezone/default.nix
Normal file
14
hosts/common/configs/system/timezone/default.nix
Normal file
@@ -0,0 +1,14 @@
|
||||
{ lib, pkgs, ... }:
|
||||
{
|
||||
networking.networkmanager.dispatcherScripts = [
|
||||
{
|
||||
source = lib.meta.getExe (
|
||||
pkgs.writeShellApplication {
|
||||
name = "timezone-sync";
|
||||
runtimeInputs = with pkgs; [ curl ];
|
||||
text = builtins.readFile ./timezone.sh;
|
||||
}
|
||||
);
|
||||
}
|
||||
];
|
||||
}
|
7
hosts/common/configs/system/timezone/timezone.sh
Normal file
7
hosts/common/configs/system/timezone/timezone.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
case "$2" in
|
||||
connectivity-change)
|
||||
if timezone=$(curl --fail https://ipapi.co/timezone); then
|
||||
timedatectl set-timezone "${timezone}"
|
||||
fi
|
||||
;;
|
||||
esac
|
12
hosts/common/configs/system/tlp/default.nix
Normal file
12
hosts/common/configs/system/tlp/default.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{ ... }:
|
||||
{
|
||||
services.tlp = {
|
||||
enable = true;
|
||||
settings = {
|
||||
CPU_SCALING_GOVERNOR_ON_AC = "performance";
|
||||
CPU_SCALING_GOVERNOR_ON_BAT = "powersave";
|
||||
CPU_ENERGY_PERF_POLICY_ON_AC = "performance";
|
||||
CPU_ENERGY_PERF_POLICY_ON_BAT = "power";
|
||||
};
|
||||
};
|
||||
}
|
10
hosts/common/configs/system/tmux/default.nix
Normal file
10
hosts/common/configs/system/tmux/default.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{ ... }:
|
||||
{
|
||||
programs.tmux = {
|
||||
enable = true;
|
||||
clock24 = true;
|
||||
historyLimit = 10000;
|
||||
keyMode = "vi";
|
||||
newSession = true;
|
||||
};
|
||||
}
|
4
hosts/common/configs/system/tree/default.nix
Normal file
4
hosts/common/configs/system/tree/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [ tree ];
|
||||
}
|
11
hosts/common/configs/system/users/default.nix
Normal file
11
hosts/common/configs/system/users/default.nix
Normal file
@@ -0,0 +1,11 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
users = {
|
||||
mutableUsers = false;
|
||||
defaultUserShell = pkgs.zsh;
|
||||
};
|
||||
|
||||
security.sudo.extraConfig = ''
|
||||
Defaults lecture = never
|
||||
'';
|
||||
}
|
4
hosts/common/configs/system/wget/default.nix
Normal file
4
hosts/common/configs/system/wget/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [ wget ];
|
||||
}
|
12
hosts/common/configs/system/zsh/default.nix
Normal file
12
hosts/common/configs/system/zsh/default.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{ ... }:
|
||||
{
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
histFile = "/var/lib/zsh/history";
|
||||
};
|
||||
|
||||
environment = {
|
||||
persistence."/persist"."/var/lib/zsh" = { };
|
||||
pathsToLink = [ "/share/zsh" ];
|
||||
};
|
||||
}
|
26
hosts/common/configs/user/console/android/default.nix
Normal file
26
hosts/common/configs/user/console/android/default.nix
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
android-tools = prev.android-tools.overrideAttrs (oldAttrs: {
|
||||
patches = oldAttrs.patches or [ ] ++ [ ./env-var-user-home.patch ];
|
||||
});
|
||||
})
|
||||
];
|
||||
|
||||
programs.adb.enable = true;
|
||||
services.gvfs.enable = true;
|
||||
|
||||
users.users.${user}.extraGroups = [ "adbusers" ];
|
||||
|
||||
environment.persistence."/persist" = {
|
||||
"${home}/.local/share/android/adbkey" = { };
|
||||
"${home}/.local/share/android/adbkey.pub" = { };
|
||||
};
|
||||
|
||||
home-manager.users.${user}.home.sessionVariables.ANDROID_USER_HOME = "${home}/.local/share/android";
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
--- a/vendor/adb/adb_utils.cpp
|
||||
+++ b/vendor/adb/adb_utils.cpp
|
||||
@@ -308,8 +308,16 @@
|
||||
}
|
||||
|
||||
std::string adb_get_android_dir_path() {
|
||||
- std::string user_dir = adb_get_homedir_path();
|
||||
- std::string android_dir = user_dir + OS_PATH_SEPARATOR + ".android";
|
||||
+ const char* android_user_home = getenv("ANDROID_USER_HOME");
|
||||
+ std::string android_dir;
|
||||
+
|
||||
+ if (android_user_home) {
|
||||
+ android_dir = std::string(android_user_home);
|
||||
+ } else {
|
||||
+ std::string user_dir = adb_get_homedir_path();
|
||||
+ android_dir = user_dir + OS_PATH_SEPARATOR + ".android";
|
||||
+ }
|
||||
+
|
||||
struct stat buf;
|
||||
if (stat(android_dir.c_str(), &buf) == -1) {
|
||||
if (adb_mkdir(android_dir, 0750) == -1) {
|
8
hosts/common/configs/user/console/bashmount/default.nix
Normal file
8
hosts/common/configs/user/console/bashmount/default.nix
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ lib, pkgs, ... }:
|
||||
{
|
||||
home-manager.users.${user}.programs.bashmount.enable = true;
|
||||
}
|
32
hosts/common/configs/user/console/bluetooth/default.nix
Normal file
32
hosts/common/configs/user/console/bluetooth/default.nix
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home-manager.users.${user}.systemd.user.services.mpris-proxy = {
|
||||
Unit = {
|
||||
Description = "MPRIS proxy";
|
||||
Requires = [ "sound.target" ];
|
||||
After = [
|
||||
"network.target"
|
||||
"sound.target"
|
||||
];
|
||||
};
|
||||
|
||||
Service.ExecStart = lib.meta.getExe (
|
||||
pkgs.writeShellApplication {
|
||||
name = "init-mpris-proxy";
|
||||
runtimeInputs = with pkgs; [ bluez ];
|
||||
text = "exec mpris-proxy";
|
||||
}
|
||||
);
|
||||
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
}
|
13
hosts/common/configs/user/console/brightnessctl/default.nix
Normal file
13
hosts/common/configs/user/console/brightnessctl/default.nix
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ lib, pkgs, ... }:
|
||||
{
|
||||
users.users.${user}.extraGroups = [
|
||||
"video"
|
||||
"inputs"
|
||||
];
|
||||
|
||||
home-manager.users.${user}.home.packages = with pkgs; [ brightnessctl ];
|
||||
}
|
20
hosts/common/configs/user/console/btop/default.nix
Normal file
20
hosts/common/configs/user/console/btop/default.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ ... }:
|
||||
{
|
||||
home-manager.users.${user}.programs.btop = {
|
||||
enable = true;
|
||||
settings = {
|
||||
theme_background = false;
|
||||
presets = "";
|
||||
vim_keys = true;
|
||||
shown_boxes = "cpu mem net proc gpu0 gpu1";
|
||||
update_ms = 1000;
|
||||
proc_tree = true;
|
||||
cpu_single_graph = true;
|
||||
disks_filter = "/ /nix /persist /cache";
|
||||
};
|
||||
};
|
||||
}
|
43
hosts/common/configs/user/console/docker/default.nix
Normal file
43
hosts/common/configs/user/console/docker/default.nix
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{
|
||||
config,
|
||||
inputs,
|
||||
utils,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
virtualisation.docker.rootless = {
|
||||
enable = true;
|
||||
setSocketVariable = true;
|
||||
enableOnBoot = false;
|
||||
storageDriver = "btrfs";
|
||||
|
||||
daemon.settings = {
|
||||
experimental = true;
|
||||
ipv6 = true;
|
||||
fixed-cidr-v6 = "fd00::/80";
|
||||
};
|
||||
|
||||
autoPrune = {
|
||||
enable = true;
|
||||
flags = [ "--all" ];
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence."/persist"."${home}/.local/share/docker" = { };
|
||||
|
||||
systemd.user = {
|
||||
services.docker.after = [
|
||||
config.environment.persistence."/persist"."${home}/.local/share/docker".mount
|
||||
];
|
||||
sockets.docker.after = [
|
||||
config.environment.persistence."/persist"."${home}/.local/share/docker".mount
|
||||
];
|
||||
};
|
||||
|
||||
home-manager.users.${user}.home.packages = with pkgs; [ docker-compose ];
|
||||
}
|
8
hosts/common/configs/user/console/fastfetch/default.nix
Normal file
8
hosts/common/configs/user/console/fastfetch/default.nix
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ ... }:
|
||||
{
|
||||
home-manager.users.${user}.programs.fastfetch.enable = true;
|
||||
}
|
8
hosts/common/configs/user/console/ffmpeg/default.nix
Normal file
8
hosts/common/configs/user/console/ffmpeg/default.nix
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home-manager.users.${user}.home.packages = with pkgs; [ ffmpeg ];
|
||||
}
|
3
hosts/common/configs/user/console/git/commit-msg.sh
Normal file
3
hosts/common/configs/user/console/git/commit-msg.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
git interpret-trailers --if-exists doNothing --trailer \
|
||||
"Signed-off-by: $(git config user.name) <$(git config user.email)>" \
|
||||
--in-place "$1"
|
47
hosts/common/configs/user/console/git/default.nix
Normal file
47
hosts/common/configs/user/console/git/default.nix
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
userConfig = config.users.users.${user};
|
||||
in
|
||||
{
|
||||
home-manager.users.${user} = {
|
||||
programs.git = {
|
||||
enable = true;
|
||||
lfs.enable = true;
|
||||
userName = userConfig.fullName;
|
||||
userEmail = userConfig.email;
|
||||
|
||||
signing = {
|
||||
signByDefault = true;
|
||||
key = null;
|
||||
};
|
||||
|
||||
extraConfig = {
|
||||
credential.helper = "store";
|
||||
push.autoSetupRemote = true;
|
||||
core.fsmonitor = true;
|
||||
feature.manyFiles = true;
|
||||
fetch.writeCommitGraph = true;
|
||||
http.cookiefile = "${home}/.config/git/cookies";
|
||||
};
|
||||
|
||||
hooks = {
|
||||
commit-msg = lib.meta.getExe (
|
||||
pkgs.writeShellApplication {
|
||||
name = "git-commit-msg-hook";
|
||||
runtimeInputs = with pkgs; [ git ];
|
||||
text = builtins.readFile ./commit-msg.sh;
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
69
hosts/common/configs/user/console/gpg-agent/default.nix
Normal file
69
hosts/common/configs/user/console/gpg-agent/default.nix
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home-manager.users.${user} = {
|
||||
# gpg --full-generate-key
|
||||
# gpg --list-secret-keys --keyid-format LONG
|
||||
# gpg --export-secret-keys -a $signature > priv.key
|
||||
# gpg --export -a $signature > pub.key
|
||||
programs.gpg = {
|
||||
enable = true;
|
||||
homedir = "${home}/.local/share/gnupg";
|
||||
};
|
||||
|
||||
services.gpg-agent = {
|
||||
enable = true;
|
||||
defaultCacheTtl = 31536000;
|
||||
maxCacheTtl = 31536000;
|
||||
};
|
||||
|
||||
systemd.user = {
|
||||
services.gpg-agent-import =
|
||||
let
|
||||
init = lib.meta.getExe (
|
||||
pkgs.writeShellApplication {
|
||||
name = "import-gpg-keys";
|
||||
runtimeInputs = with pkgs; [
|
||||
coreutils
|
||||
gnugrep
|
||||
gnupg
|
||||
];
|
||||
runtimeEnv = {
|
||||
GNUPGHOME = "${home}/.local/share/gnupg";
|
||||
HOME = home;
|
||||
};
|
||||
text = builtins.readFile ./import-gpg-keys.sh;
|
||||
}
|
||||
);
|
||||
in
|
||||
{
|
||||
Unit = {
|
||||
Description = "Auto-import GPG keys";
|
||||
Requires = [
|
||||
"sops-nix.service"
|
||||
"gpg-agent.socket"
|
||||
];
|
||||
After = [
|
||||
"sops-nix.service"
|
||||
"gpg-agent.socket"
|
||||
];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = init;
|
||||
};
|
||||
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
install -d -m 700 "${GNUPGHOME}"
|
||||
|
||||
for dir in "${HOME}"/.config/sops-nix/secrets/gpg/*; do
|
||||
keyfile="${dir}/key"
|
||||
passfile="${dir}/pass"
|
||||
|
||||
if [[ ! -f "${keyfile}" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ -f "${passfile}" ]]; then
|
||||
gpg2 --batch --yes --pinentry-mode loopback --passphrase-file "${passfile}" --import "${keyfile}"
|
||||
else
|
||||
gpg2 --batch --yes --import "${keyfile}"
|
||||
fi
|
||||
|
||||
gpg2 --with-colons --import-options show-only --import "${keyfile}" | grep '^fpr' | cut -d: -f10 | while read -r KEY_ID; do
|
||||
echo "${KEY_ID}:6:" >> "${GNUPGHOME}"/otrust.txt
|
||||
done
|
||||
done
|
||||
|
||||
gpg2 --import-ownertrust "${GNUPGHOME}"/otrust.txt
|
||||
rm "${GNUPGHOME}"/otrust.txt
|
29
hosts/common/configs/user/console/home-manager/default.nix
Normal file
29
hosts/common/configs/user/console/home-manager/default.nix
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ config, inputs, ... }:
|
||||
{
|
||||
imports = [ inputs.home-manager.nixosModules.default ];
|
||||
|
||||
programs.dconf.enable = true;
|
||||
|
||||
home-manager = {
|
||||
extraSpecialArgs = {
|
||||
inherit inputs;
|
||||
};
|
||||
backupFileExtension = "bak";
|
||||
useUserPackages = true;
|
||||
useGlobalPkgs = true;
|
||||
|
||||
users.${user} = {
|
||||
home.stateVersion = "24.11";
|
||||
systemd.user.startServices = true;
|
||||
|
||||
nix.settings.experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home-manager.users.${user}.home.packages = with pkgs; [ imagemagick ];
|
||||
}
|
16
hosts/common/configs/user/console/libvirt/default.nix
Normal file
16
hosts/common/configs/user/console/libvirt/default.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home-manager.users.${user}.dconf.settings = {
|
||||
"org/virt-manager/virt-manager/connections" = {
|
||||
autoconnect = [ "qemu:///system" ];
|
||||
uris = [ "qemu:///system" ];
|
||||
};
|
||||
"org/virt-manager/virt-manager".xmleditor-enabled = true;
|
||||
};
|
||||
|
||||
users.users.${user}.extraGroups = [ "libvirtd" ];
|
||||
}
|
17
hosts/common/configs/user/console/ncdu/default.nix
Normal file
17
hosts/common/configs/user/console/ncdu/default.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home-manager.users.${user} = {
|
||||
home.packages = with pkgs; [ ncdu ];
|
||||
|
||||
xdg.configFile."ncdu/config".text = ''
|
||||
-1
|
||||
-e
|
||||
-t 0
|
||||
--confirm-quit
|
||||
'';
|
||||
};
|
||||
}
|
20
hosts/common/configs/user/console/neovim/default.nix
Normal file
20
hosts/common/configs/user/console/neovim/default.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ ... }:
|
||||
{
|
||||
home-manager.users.${user}.programs.neovim = {
|
||||
enable = true;
|
||||
defaultEditor = true;
|
||||
viAlias = true;
|
||||
vimAlias = true;
|
||||
vimdiffAlias = true;
|
||||
extraConfig = ''
|
||||
set tabstop=2
|
||||
set shiftwidth=2
|
||||
set expandtab
|
||||
set smartindent
|
||||
'';
|
||||
};
|
||||
}
|
16
hosts/common/configs/user/console/nix-develop/default.nix
Normal file
16
hosts/common/configs/user/console/nix-develop/default.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ ... }:
|
||||
{
|
||||
home-manager.users.${user}.programs.zsh.initExtra = ''
|
||||
nix-develop() {
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: nix-develop <shell>"
|
||||
return 1
|
||||
fi
|
||||
nix develop self#"$1" -c "$SHELL"
|
||||
}
|
||||
'';
|
||||
}
|
33
hosts/common/configs/user/console/nix-direnv/default.nix
Normal file
33
hosts/common/configs/user/console/nix-direnv/default.nix
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ inputs, ... }:
|
||||
{
|
||||
home-manager.users.${user} = {
|
||||
programs.direnv = {
|
||||
enable = true;
|
||||
silent = true;
|
||||
nix-direnv.enable = true;
|
||||
enableZshIntegration = true;
|
||||
};
|
||||
|
||||
# https://github.com/direnv/direnv/wiki/Customizing-cache-location
|
||||
xdg.configFile."direnv/direnvrc".text = ''
|
||||
declare -A direnv_layout_dirs
|
||||
direnv_layout_dir() {
|
||||
local hash path
|
||||
echo "''${direnv_layout_dirs[$PWD]:=$(
|
||||
hash="$(sha1sum - <<< "$PWD" | head -c40)"
|
||||
path="''${PWD//[^a-zA-Z0-9]/-}"
|
||||
echo "${home}/.cache/direnv/layouts/''${hash}''${path}"
|
||||
)}"
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
environment.persistence = {
|
||||
"/persist"."${home}/.local/share/direnv/allow" = { };
|
||||
"/cache"."${home}/.cache/direnv" = { };
|
||||
};
|
||||
}
|
10
hosts/common/configs/user/console/nixpkgs/default.nix
Normal file
10
hosts/common/configs/user/console/nixpkgs/default.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ inputs, ... }:
|
||||
{
|
||||
home-manager.users.${user} = {
|
||||
imports = [ inputs.nur.modules.homeManager.default ];
|
||||
};
|
||||
}
|
21
hosts/common/configs/user/console/pipewire/default.nix
Normal file
21
hosts/common/configs/user/console/pipewire/default.nix
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
environment.persistence."/persist"."${home}/.local/state/wireplumber" = { };
|
||||
|
||||
systemd.user.services.wireplumber.after = [
|
||||
config.environment.persistence."/persist"."${home}/.local/state/wireplumber".mount
|
||||
];
|
||||
|
||||
home-manager.users.${user} = {
|
||||
home.packages = with pkgs; [
|
||||
wireplumber
|
||||
playerctl
|
||||
];
|
||||
|
||||
services.playerctld.enable = true;
|
||||
};
|
||||
}
|
17
hosts/common/configs/user/console/ranger/default.nix
Normal file
17
hosts/common/configs/user/console/ranger/default.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ ... }:
|
||||
{
|
||||
environment.persistence."/cache"."${home}/.cache/ranger" = { };
|
||||
|
||||
home-manager.users.${user}.programs.ranger = {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
preview_images = true;
|
||||
preview_images_method = "kitty";
|
||||
};
|
||||
};
|
||||
}
|
18
hosts/common/configs/user/console/sops/default.nix
Normal file
18
hosts/common/configs/user/console/sops/default.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ config, inputs, ... }:
|
||||
{
|
||||
environment.persistence."/persist"."${home}/.config/sops-nix/key.txt" = { };
|
||||
|
||||
home-manager.users.${user} = {
|
||||
imports = [ inputs.sops-nix.homeManagerModules.sops ];
|
||||
|
||||
sops.age.keyFile = "${home}/.config/sops-nix/key.txt";
|
||||
home.sessionVariables.SOPS_AGE_KEY_FILE = "${home}/.config/sops-nix/key.txt";
|
||||
systemd.user.services.sops-nix.Unit.After = [
|
||||
config.environment.persistence."/persist"."${home}/.config/sops-nix/key.txt".mount
|
||||
];
|
||||
};
|
||||
}
|
25
hosts/common/configs/user/console/ssh/default.nix
Normal file
25
hosts/common/configs/user/console/ssh/default.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home-manager.users.${user} = {
|
||||
programs.ssh = {
|
||||
enable = true;
|
||||
addKeysToAgent = "yes";
|
||||
userKnownHostsFile = lib.strings.concatStringsSep " " [
|
||||
../../../../../installer/secrets/ssh_host_ed25519_key.pub
|
||||
../../../../../eirene/secrets/ssh_host_ed25519_key.pub
|
||||
../../../../../elara/secrets/ssh_host_ed25519_key.pub
|
||||
];
|
||||
};
|
||||
|
||||
services.ssh-agent.enable = true;
|
||||
};
|
||||
}
|
49
hosts/common/configs/user/console/syncthing/default.nix
Normal file
49
hosts/common/configs/user/console/syncthing/default.nix
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ config, utils, ... }:
|
||||
{
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 22000 ];
|
||||
allowedUDPPorts = [
|
||||
21027
|
||||
22000
|
||||
];
|
||||
};
|
||||
|
||||
sops.secrets = {
|
||||
# openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:3072
|
||||
"syncthing/key" = {
|
||||
owner = user;
|
||||
group = "users";
|
||||
};
|
||||
# openssl req -new -x509 -key key.pem -out cert.pem -days 9999 -subj "/CN=syncthing"
|
||||
"syncthing/cert" = {
|
||||
owner = user;
|
||||
group = "users";
|
||||
};
|
||||
};
|
||||
|
||||
home-manager.users.${user} = {
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
key = config.sops.secrets."syncthing/key".path;
|
||||
cert = config.sops.secrets."syncthing/cert".path;
|
||||
extraOptions = [ "-no-default-folder" ];
|
||||
|
||||
settings = {
|
||||
options.urAccepted = -1;
|
||||
devices = {
|
||||
amalthea.id = "2W7YT6Q-TO7CYMW-JH6QZXE-7Q6MDQQ-HPHKP4A-VI5HP7G-KLMGMST-MNRYHQG"; # Google Pixel 8 Pro
|
||||
ganymede.id = "DXJPEJA-JNGF6I4-VIZYTX7-U345C5V-HIUTSFC-D36N2EM-Y3FAKJM-PRKYQAI"; # Samsung Galaxy Tab S7+
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.services.syncthing.Unit.After = [
|
||||
"sops-nix.service"
|
||||
"local-fs.target"
|
||||
];
|
||||
};
|
||||
}
|
8
hosts/common/configs/user/console/tmux/default.nix
Normal file
8
hosts/common/configs/user/console/tmux/default.nix
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ ... }:
|
||||
{
|
||||
home-manager.users.${user}.programs.tmux.enable = true;
|
||||
}
|
8
hosts/common/configs/user/console/tree/default.nix
Normal file
8
hosts/common/configs/user/console/tree/default.nix
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home-manager.users.${user}.home.packages = with pkgs; [ tree ];
|
||||
}
|
8
hosts/common/configs/user/console/wget/default.nix
Normal file
8
hosts/common/configs/user/console/wget/default.nix
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home-manager.users.${user}.home.packages = with pkgs; [ wget ];
|
||||
}
|
40
hosts/common/configs/user/console/xdg/default.nix
Normal file
40
hosts/common/configs/user/console/xdg/default.nix
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
environment.persistence."/persist" = {
|
||||
"${home}/Desktop" = { };
|
||||
"${home}/Documents" = { };
|
||||
"${home}/Downloads" = { };
|
||||
"${home}/Music" = { };
|
||||
"${home}/Pictures" = { };
|
||||
"${home}/Templates" = { };
|
||||
"${home}/Videos" = { };
|
||||
"${home}/Games" = { };
|
||||
"${home}/VMs" = { };
|
||||
"${home}/git" = { };
|
||||
};
|
||||
|
||||
home-manager.users.${user} = {
|
||||
imports = [ (import ./options.nix { inherit home; }) ];
|
||||
|
||||
xdg = {
|
||||
enable = true;
|
||||
mimeApps.enable = true;
|
||||
|
||||
userDirs = {
|
||||
enable = true;
|
||||
createDirectories = true;
|
||||
extraConfig = {
|
||||
XDG_GAME_DIR = "${home}/Games";
|
||||
XDG_VM_DIR = "${home}/VMs";
|
||||
XDG_GIT_DIR = "${home}/git";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
home.packages = with pkgs; [ xdg-utils ];
|
||||
};
|
||||
}
|
112
hosts/common/configs/user/console/xdg/options.nix
Normal file
112
hosts/common/configs/user/console/xdg/options.nix
Normal file
@@ -0,0 +1,112 @@
|
||||
{
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.xdg;
|
||||
in
|
||||
{
|
||||
options.xdg =
|
||||
with lib;
|
||||
with types;
|
||||
{
|
||||
relativeCacheHome = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
default = ".cache";
|
||||
description = "Relative path to directory holding application caches.";
|
||||
};
|
||||
|
||||
relativeConfigHome = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
default = ".config";
|
||||
description = "Relative path to directory holding application configurations.";
|
||||
};
|
||||
|
||||
relativeDataHome = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
default = ".local/share";
|
||||
description = "Relative path to directory holding application data.";
|
||||
};
|
||||
|
||||
relativeStateHome = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
default = ".local/state";
|
||||
description = "Relative path to directory holding application states.";
|
||||
};
|
||||
|
||||
userDirs = {
|
||||
relativeDesktop = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
default = "Desktop";
|
||||
description = "Relative path to the Desktop directory.";
|
||||
};
|
||||
|
||||
relativeDocuments = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
default = "Documents";
|
||||
description = "Relative path to the Documents directory.";
|
||||
};
|
||||
|
||||
relativeDownload = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
default = "Downloads";
|
||||
description = "Relative path to the Downloads directory.";
|
||||
};
|
||||
|
||||
relativeMusic = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
default = "Music";
|
||||
description = "Relative path to the Music directory.";
|
||||
};
|
||||
|
||||
relativePictures = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
default = "Pictures";
|
||||
description = "Relative path to the Pictures directory.";
|
||||
};
|
||||
|
||||
relativeTemplates = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
default = "Templates";
|
||||
description = "Relative path to the Templates directory.";
|
||||
};
|
||||
|
||||
relativeVideos = mkOption {
|
||||
type = str;
|
||||
readOnly = true;
|
||||
default = "Videos";
|
||||
description = "Relative path to the Videos directory.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config.xdg =
|
||||
with lib;
|
||||
with cfg;
|
||||
{
|
||||
cacheHome = mkDefault "${home}/${relativeCacheHome}";
|
||||
configHome = mkDefault "${home}/${relativeConfigHome}";
|
||||
dataHome = mkDefault "${home}/${relativeDataHome}";
|
||||
stateHome = mkDefault "${home}/${relativeStateHome}";
|
||||
|
||||
userDirs = with userDirs; {
|
||||
desktop = mkDefault "${home}/${relativeDesktop}";
|
||||
documents = mkDefault "${home}/${relativeDocuments}";
|
||||
download = mkDefault "${home}/${relativeDownload}";
|
||||
music = mkDefault "${home}/${relativeMusic}";
|
||||
pictures = mkDefault "${home}/${relativePictures}";
|
||||
templates = mkDefault "${home}/${relativeTemplates}";
|
||||
videos = mkDefault "${home}/${relativeVideos}";
|
||||
};
|
||||
};
|
||||
}
|
20
hosts/common/configs/user/console/yt-dlp/default.nix
Normal file
20
hosts/common/configs/user/console/yt-dlp/default.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ config, ... }:
|
||||
{
|
||||
home-manager.users.${user}.programs.yt-dlp = {
|
||||
enable = true;
|
||||
settings = {
|
||||
live-from-start = true;
|
||||
concurrent-fragments = config.hardware.cpu.threads;
|
||||
lazy-playlist = true;
|
||||
cookies-from-browser = "firefox";
|
||||
embed-subs = true;
|
||||
sub-langs = "all,-live_chat";
|
||||
embed-thumbnail = true;
|
||||
fixup = "detect_or_warn";
|
||||
};
|
||||
};
|
||||
}
|
249
hosts/common/configs/user/console/zsh/.p10k.zsh
Normal file
249
hosts/common/configs/user/console/zsh/.p10k.zsh
Normal file
@@ -0,0 +1,249 @@
|
||||
'builtin' 'local' '-a' 'p10k_config_opts'
|
||||
[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases')
|
||||
[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob')
|
||||
[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand')
|
||||
'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand'
|
||||
|
||||
() {
|
||||
emulate -L zsh -o extended_glob
|
||||
unset -m '(POWERLEVEL9K_*|DEFAULT_USER)~POWERLEVEL9K_GITSTATUS_DIR'
|
||||
|
||||
typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
|
||||
# =========================[ Line #1 ]=========================
|
||||
dir
|
||||
vcs
|
||||
# =========================[ Line #2 ]=========================
|
||||
newline
|
||||
prompt_char
|
||||
)
|
||||
|
||||
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(
|
||||
# =========================[ Line #1 ]=========================
|
||||
status
|
||||
command_execution_time
|
||||
background_jobs
|
||||
direnv
|
||||
ranger
|
||||
vim_shell
|
||||
nix_shell
|
||||
per_directory_history
|
||||
"${P10K_EXTRA_RIGHT_PROMPT_ELEMENTS[@]}"
|
||||
context
|
||||
# =========================[ Line #2 ]=========================
|
||||
newline
|
||||
)
|
||||
|
||||
typeset -g POWERLEVEL9K_MODE=ascii
|
||||
typeset -g POWERLEVEL9K_ICON_PADDING=none
|
||||
typeset -g POWERLEVEL9K_BACKGROUND=
|
||||
typeset -g POWERLEVEL9K_{LEFT,RIGHT}_{LEFT,RIGHT}_WHITESPACE=
|
||||
typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SUBSEGMENT_SEPARATOR=' '
|
||||
typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SEGMENT_SEPARATOR=
|
||||
typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT=true
|
||||
typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true
|
||||
typeset -g POWERLEVEL9K_SHOW_RULER=false
|
||||
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' '
|
||||
|
||||
################################[ prompt_char: prompt symbol ]################################
|
||||
typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=76
|
||||
typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=196
|
||||
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='>'
|
||||
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='<'
|
||||
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='V'
|
||||
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='^'
|
||||
typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true
|
||||
typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=''
|
||||
|
||||
##################################[ dir: current directory ]##################################
|
||||
typeset -g POWERLEVEL9K_DIR_FOREGROUND=31
|
||||
typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique
|
||||
typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=103
|
||||
typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=39
|
||||
typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true
|
||||
local anchor_files=(
|
||||
.git
|
||||
flake.nix
|
||||
Cargo.toml
|
||||
go.mod
|
||||
package.json
|
||||
)
|
||||
typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})"
|
||||
typeset -g POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=false
|
||||
typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1
|
||||
typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80
|
||||
typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40
|
||||
typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50
|
||||
typeset -g POWERLEVEL9K_DIR_HYPERLINK=false
|
||||
|
||||
typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=v3
|
||||
|
||||
typeset -g POWERLEVEL9K_DIR_CLASSES=()
|
||||
|
||||
#####################################[ vcs: git status ]######################################
|
||||
typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?'
|
||||
|
||||
function my_git_formatter() {
|
||||
emulate -L zsh
|
||||
|
||||
if [[ -n $P9K_CONTENT ]]; then
|
||||
typeset -g my_git_format=$P9K_CONTENT
|
||||
return
|
||||
fi
|
||||
|
||||
if (( $1 )); then
|
||||
local meta='%f'
|
||||
local clean='%76F'
|
||||
local modified='%178F'
|
||||
local untracked='%39F'
|
||||
local conflicted='%196F'
|
||||
else
|
||||
local meta='%244F'
|
||||
local clean='%244F'
|
||||
local modified='%244F'
|
||||
local untracked='%244F'
|
||||
local conflicted='%244F'
|
||||
fi
|
||||
|
||||
local res
|
||||
|
||||
if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then
|
||||
local branch=${(V)VCS_STATUS_LOCAL_BRANCH}
|
||||
(( $#branch > 32 )) && branch[13,-13]=".."
|
||||
res+="${clean}${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}${branch//\%/%%}"
|
||||
fi
|
||||
|
||||
if [[ -n $VCS_STATUS_TAG
|
||||
&& -z $VCS_STATUS_LOCAL_BRANCH
|
||||
]]; then
|
||||
local tag=${(V)VCS_STATUS_TAG}
|
||||
(( $#tag > 32 )) && tag[13,-13]=".."
|
||||
res+="${meta}#${clean}${tag//\%/%%}"
|
||||
fi
|
||||
|
||||
[[ -z $VCS_STATUS_LOCAL_BRANCH && -z $VCS_STATUS_TAG ]] &&
|
||||
res+="${meta}@${clean}${VCS_STATUS_COMMIT[1,8]}"
|
||||
|
||||
if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then
|
||||
res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}"
|
||||
fi
|
||||
|
||||
if [[ $VCS_STATUS_COMMIT_SUMMARY == (|*[^[:alnum:]])(wip|WIP)(|[^[:alnum:]]*) ]]; then
|
||||
res+=" ${modified}wip"
|
||||
fi
|
||||
|
||||
if (( VCS_STATUS_COMMITS_AHEAD || VCS_STATUS_COMMITS_BEHIND )); then
|
||||
(( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}<${VCS_STATUS_COMMITS_BEHIND}"
|
||||
(( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" "
|
||||
(( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}>${VCS_STATUS_COMMITS_AHEAD}"
|
||||
fi
|
||||
|
||||
(( VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" ${clean}<-${VCS_STATUS_PUSH_COMMITS_BEHIND}"
|
||||
(( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" "
|
||||
(( VCS_STATUS_PUSH_COMMITS_AHEAD )) && res+="${clean}->${VCS_STATUS_PUSH_COMMITS_AHEAD}"
|
||||
(( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}"
|
||||
[[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}"
|
||||
(( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}"
|
||||
(( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}"
|
||||
(( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}"
|
||||
(( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}"
|
||||
(( VCS_STATUS_HAS_UNSTAGED == -1 )) && res+=" ${modified}-"
|
||||
|
||||
typeset -g my_git_format=$res
|
||||
}
|
||||
functions -M my_git_formatter 2>/dev/null
|
||||
|
||||
typeset -g POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=-1
|
||||
|
||||
typeset -g POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN='~'
|
||||
|
||||
typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true
|
||||
typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter(1)))+${my_git_format}}'
|
||||
typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION='${$((my_git_formatter(0)))+${my_git_format}}'
|
||||
typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1
|
||||
|
||||
typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_COLOR=76
|
||||
typeset -g POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR=244
|
||||
typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION=
|
||||
|
||||
typeset -g POWERLEVEL9K_VCS_BACKENDS=(git)
|
||||
|
||||
typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND=76
|
||||
typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND=76
|
||||
typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND=178
|
||||
|
||||
##########################[ status: exit code of the last command ]###########################
|
||||
typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true
|
||||
|
||||
typeset -g POWERLEVEL9K_STATUS_OK=true
|
||||
typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=70
|
||||
typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='ok'
|
||||
|
||||
typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true
|
||||
typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=70
|
||||
typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='ok'
|
||||
|
||||
typeset -g POWERLEVEL9K_STATUS_ERROR=false
|
||||
typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=160
|
||||
typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='err'
|
||||
|
||||
typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true
|
||||
typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=160
|
||||
typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=true
|
||||
typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION=
|
||||
|
||||
typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true
|
||||
typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=160
|
||||
typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='err'
|
||||
|
||||
###################[ command_execution_time: duration of the last command ]###################
|
||||
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=0
|
||||
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=2
|
||||
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=101
|
||||
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s'
|
||||
|
||||
#######################[ background_jobs: presence of background jobs ]#######################
|
||||
typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false
|
||||
typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=70
|
||||
|
||||
#######################[ direnv: direnv status (https://direnv.net/) ]########################
|
||||
typeset -g POWERLEVEL9K_DIRENV_FOREGROUND=178
|
||||
|
||||
#################[ ranger: ranger shell (https://github.com/ranger/ranger) ]##################
|
||||
typeset -g POWERLEVEL9K_RANGER_FOREGROUND=178
|
||||
|
||||
###########################[ vim_shell: vim shell indicator (:sh) ]###########################
|
||||
typeset -g POWERLEVEL9K_VIM_SHELL_FOREGROUND=34
|
||||
|
||||
#[ nix_shell: nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) ]##
|
||||
typeset -g POWERLEVEL9K_NIX_SHELL_FOREGROUND=74
|
||||
|
||||
typeset -g POWERLEVEL9K_NIX_SHELL_INFER_FROM_PATH=true
|
||||
|
||||
######[ per_directory_history: Oh My Zsh per-directory-history local/global indicator ]#######
|
||||
typeset -g POWERLEVEL9K_PER_DIRECTORY_HISTORY_LOCAL_FOREGROUND=135
|
||||
typeset -g POWERLEVEL9K_PER_DIRECTORY_HISTORY_GLOBAL_FOREGROUND=130
|
||||
|
||||
##################################[ context: user@hostname ]##################################
|
||||
typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=178
|
||||
typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=180
|
||||
typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=180
|
||||
|
||||
typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%B%n@%m'
|
||||
typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m'
|
||||
typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m'
|
||||
|
||||
typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION=
|
||||
|
||||
#####################################[ Other Settings ]#######################################
|
||||
|
||||
typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=always
|
||||
typeset -g POWERLEVEL9K_INSTANT_PROMPT=quiet
|
||||
typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true
|
||||
|
||||
(( ! $+functions[p10k] )) || p10k reload
|
||||
}
|
||||
|
||||
typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a}
|
||||
|
||||
(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]}
|
||||
'builtin' 'unset' 'p10k_config_opts'
|
39
hosts/common/configs/user/console/zsh/default.nix
Normal file
39
hosts/common/configs/user/console/zsh/default.nix
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
environment = {
|
||||
sessionVariables.ZDOTDIR = "$HOME/.config/zsh";
|
||||
persistence."/persist"."${home}/.local/share/zsh" = { };
|
||||
};
|
||||
|
||||
home-manager.users.${user} = {
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
dotDir = ".config/zsh";
|
||||
autocd = true;
|
||||
history = {
|
||||
path = "${home}/.local/share/zsh/history";
|
||||
expireDuplicatesFirst = true;
|
||||
append = true;
|
||||
};
|
||||
historySubstringSearch.enable = true;
|
||||
autosuggestion.enable = true;
|
||||
syntaxHighlighting.enable = true;
|
||||
plugins = [
|
||||
{
|
||||
name = "powerlevel10k";
|
||||
src = pkgs.zsh-powerlevel10k;
|
||||
file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
|
||||
}
|
||||
];
|
||||
initExtra = ''
|
||||
source ${./.p10k.zsh}
|
||||
'';
|
||||
};
|
||||
|
||||
home.file.".zshenv".enable = false;
|
||||
};
|
||||
}
|
2
hosts/common/configs/user/gui/astal/config/.gitignore
vendored
Normal file
2
hosts/common/configs/user/gui/astal/config/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules/
|
||||
@girs/
|
23
hosts/common/configs/user/gui/astal/config/app.ts
Normal file
23
hosts/common/configs/user/gui/astal/config/app.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { App } from "astal/gtk3"
|
||||
import Bar from "./widget/Bar"
|
||||
import { monitorFile } from "astal/file"
|
||||
import { exec } from "astal/process"
|
||||
import GLib from "gi://GLib"
|
||||
|
||||
const HOME = GLib.getenv("HOME")
|
||||
const css = `${HOME}/.config/astal/theme.css`;
|
||||
const scss = `${HOME}/.config/astal/theme.sass`;
|
||||
|
||||
monitorFile(scss, () => {
|
||||
exec(`sassc ${scss} ${css}`);
|
||||
App.apply_css(css, true);
|
||||
});
|
||||
|
||||
exec(`sassc ${scss} ${css}`);
|
||||
|
||||
App.start({
|
||||
css,
|
||||
main() {
|
||||
App.get_monitors().map(Bar)
|
||||
},
|
||||
})
|
26
hosts/common/configs/user/gui/astal/config/env.d.ts
vendored
Normal file
26
hosts/common/configs/user/gui/astal/config/env.d.ts
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
export const SRC: string
|
||||
|
||||
declare module "inline:*" {
|
||||
const content: string
|
||||
export default content
|
||||
}
|
||||
|
||||
declare module "*.scss" {
|
||||
const content: string
|
||||
export default content
|
||||
}
|
||||
|
||||
declare module "*.sass" {
|
||||
const content: string
|
||||
export default content
|
||||
}
|
||||
|
||||
declare module "*.blp" {
|
||||
const content: string
|
||||
export default content
|
||||
}
|
||||
|
||||
declare module "*.css" {
|
||||
const content: string
|
||||
export default content
|
||||
}
|
3
hosts/common/configs/user/gui/astal/config/lib.ts
Normal file
3
hosts/common/configs/user/gui/astal/config/lib.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const range = (length: number, start = 1) => {
|
||||
return Array.from({ length }, (n, i) => i + start);
|
||||
};
|
20
hosts/common/configs/user/gui/astal/config/tsconfig.json
Normal file
20
hosts/common/configs/user/gui/astal/config/tsconfig.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"strict": true,
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "Bundler",
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "/nix/store/ii2w7wv88fjvmldn8kzz8ni20kzpkld4-astal-gjs/share/astal/gjs/gtk3",
|
||||
"paths": {
|
||||
"astal": [
|
||||
"/nix/store/ii2w7wv88fjvmldn8kzz8ni20kzpkld4-astal-gjs/share/astal/gjs"
|
||||
],
|
||||
"astal/*": [
|
||||
"/nix/store/ii2w7wv88fjvmldn8kzz8ni20kzpkld4-astal-gjs/share/astal/gjs/*"
|
||||
]
|
||||
},
|
||||
}
|
||||
}
|
29
hosts/common/configs/user/gui/astal/config/widget/Bar.tsx
Normal file
29
hosts/common/configs/user/gui/astal/config/widget/Bar.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { App, Astal, Gtk, Gdk } from 'astal/gtk3'
|
||||
import Launcher from './components/Launcher';
|
||||
import Workspace from './components/Workspaces';
|
||||
import Date from './components/Date';
|
||||
import Systray from './components/Tray';
|
||||
|
||||
const anchor = Astal.WindowAnchor.TOP
|
||||
| Astal.WindowAnchor.LEFT
|
||||
| Astal.WindowAnchor.RIGHT;
|
||||
|
||||
export default (monitor: Gdk.Monitor) => <window
|
||||
className='bar'
|
||||
gdkmonitor={monitor}
|
||||
exclusivity={Astal.Exclusivity.EXCLUSIVE}
|
||||
anchor={anchor}
|
||||
application={App}>
|
||||
<centerbox className='widgets'>
|
||||
<box hexpand halign={Gtk.Align.START}>
|
||||
<Launcher />
|
||||
<Workspace />
|
||||
</box>
|
||||
<box hexpand halign={Gtk.Align.CENTER}>
|
||||
<Date />
|
||||
</box>
|
||||
<box hexpand halign={Gtk.Align.END}>
|
||||
<Systray />
|
||||
</box>
|
||||
</centerbox>
|
||||
</window>
|
@@ -0,0 +1,13 @@
|
||||
|
||||
import { Variable } from 'astal/variable';
|
||||
import { GLib } from 'astal';
|
||||
|
||||
const time = Variable<string>("").poll(1000, () => GLib.DateTime.new_now_local().format('%H:%M - %A, %d %B %Y')!)
|
||||
|
||||
export default () => <button className='date'>
|
||||
<label
|
||||
className='label'
|
||||
onDestroy={() => time.drop()}
|
||||
label={time()}
|
||||
/>
|
||||
</button>;
|
@@ -0,0 +1,7 @@
|
||||
import { execAsync } from "astal/process"
|
||||
|
||||
export default () => <button
|
||||
className="launcher"
|
||||
onClickRelease={() => execAsync('bash -c "rofi -cache-dir $XDG_CACHE_HOME/rofi -show drun"')}>
|
||||
<icon className="icon" icon="nix-snowflake-symbolic" />;
|
||||
</button>;
|
@@ -0,0 +1,30 @@
|
||||
import { App, Gdk } from 'astal/gtk3'
|
||||
import { bind } from 'astal'
|
||||
import Tray from 'gi://AstalTray'
|
||||
|
||||
const tray = Tray.get_default()
|
||||
|
||||
const TrayButton = ({ item }: { item: Tray.TrayItem }) => {
|
||||
const menu = item.create_menu();
|
||||
|
||||
return <button
|
||||
className='item'
|
||||
tooltipMarkup={bind(item, 'tooltipMarkup')}
|
||||
onClickRelease={self => {
|
||||
menu?.popup_at_widget(self, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null)
|
||||
}}
|
||||
onDestroy={() => menu?.destroy()}
|
||||
>
|
||||
<icon
|
||||
className='icon'
|
||||
gIcon={bind(item, 'gicon')} />
|
||||
</button>;
|
||||
}
|
||||
|
||||
export default () => <box className='systray'>
|
||||
{
|
||||
bind(tray, 'items').as(items => items.map(item => {
|
||||
if (item.iconThemePath) App.add_icons(item.iconThemePath);
|
||||
return <TrayButton item={item} />;
|
||||
}))}
|
||||
</box>;
|
@@ -0,0 +1,44 @@
|
||||
import { bind, Binding, Variable } from "astal";
|
||||
import Hyprland from "gi://AstalHyprland";
|
||||
import { range } from '../../lib';
|
||||
|
||||
const hyprland = Hyprland.get_default();
|
||||
|
||||
const Workspace = ({ id }: { id: number }) => {
|
||||
const className = Variable.derive(
|
||||
[bind(hyprland, "workspaces"), bind(hyprland, "focusedWorkspace")],
|
||||
(workspaces, focused) => {
|
||||
const workspace = workspaces.find((w) => w.id === id);
|
||||
|
||||
if (!workspace) return "button";
|
||||
|
||||
const occupied = workspace.get_clients().length > 0;
|
||||
const active = focused.id === id;
|
||||
|
||||
return `button ${active ? "active" : occupied && "occupied"}`;
|
||||
},
|
||||
);
|
||||
|
||||
return <box vertical>
|
||||
<box vexpand />
|
||||
<eventbox
|
||||
onClickRelease={() => hyprland.dispatch("workspace", `${id}`)}
|
||||
>
|
||||
<label
|
||||
className={className()}
|
||||
/>
|
||||
</eventbox>
|
||||
<box vexpand />
|
||||
</box>;
|
||||
};
|
||||
|
||||
export default () => <eventbox
|
||||
className="workspaces"
|
||||
onScroll={(_, e) => {
|
||||
hyprland.dispatch("workspace", e.delta_y > 0 ? "+1" : "-1");
|
||||
}}
|
||||
>
|
||||
<box>
|
||||
{range(10).map((i) => <Workspace id={i} />)}
|
||||
</box>
|
||||
</eventbox>
|
43
hosts/common/configs/user/gui/astal/default.nix
Normal file
43
hosts/common/configs/user/gui/astal/default.nix
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home-manager.users.${user} = {
|
||||
imports = [ inputs.ags.homeManagerModules.default ];
|
||||
|
||||
programs.ags = {
|
||||
enable = true;
|
||||
configDir = ./config;
|
||||
systemd.enable = true;
|
||||
|
||||
extraPackages = with pkgs; [
|
||||
inputs.ags.packages.${pkgs.system}.hyprland
|
||||
inputs.ags.packages.${pkgs.system}.tray
|
||||
sassc
|
||||
hyprland
|
||||
nixos-icons
|
||||
(pkgs.callPackage ../cliphist/rofi.nix { })
|
||||
];
|
||||
};
|
||||
|
||||
theme.template."${home}/.config/astal/theme.sass".source = ./theme.sass;
|
||||
|
||||
systemd.user = {
|
||||
targets.tray.Unit = {
|
||||
BindsTo = [ "ags.service" ];
|
||||
After = [
|
||||
"graphical-session.target"
|
||||
"ags.service"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
73
hosts/common/configs/user/gui/astal/theme.sass
Normal file
73
hosts/common/configs/user/gui/astal/theme.sass
Normal file
@@ -0,0 +1,73 @@
|
||||
.bar
|
||||
background-color: {{colors.surface.default.hex}}
|
||||
|
||||
@mixin interactive
|
||||
min-height: {{custom.font_size}}pt
|
||||
border-radius: .5 * {{custom.font_size}}pt
|
||||
padding: 2pt
|
||||
margin: 0 2pt 0
|
||||
transition: .25s
|
||||
|
||||
background-color: {{colors.surface.default.hex}}
|
||||
|
||||
&:hover
|
||||
background-color: {{colors.surface_container_high.default.hex}}
|
||||
|
||||
&:active
|
||||
background-color: {{colors.surface_container_highest.default.hex}}
|
||||
|
||||
.widgets
|
||||
padding: .2 * {{custom.padding}}pt
|
||||
|
||||
.launcher
|
||||
@include interactive
|
||||
|
||||
min-width: {{custom.font_size}}pt
|
||||
|
||||
.icon
|
||||
font-size: {{custom.font_size}}pt
|
||||
padding: 0 .3 * {{custom.padding}}pt
|
||||
color: {{colors.on_surface.default.hex}}
|
||||
|
||||
.workspaces
|
||||
@include interactive
|
||||
|
||||
.button
|
||||
font-size: 0
|
||||
transition: .5s
|
||||
margin: 0 .3 * {{custom.padding}}pt
|
||||
background-color: {{colors.outline_variant.default.hex}}
|
||||
min-width: .4 * {{custom.font_size}}pt
|
||||
min-height: .4 * {{custom.font_size}}pt
|
||||
border-radius: .5 * {{custom.font_size}}pt
|
||||
|
||||
&.occupied
|
||||
background-color: {{colors.on_surface.default.hex}}
|
||||
min-width: .6 * {{custom.font_size}}pt
|
||||
min-height: .6 * {{custom.font_size}}pt
|
||||
border-radius: .5 * {{custom.font_size}}pt
|
||||
|
||||
&.active
|
||||
background-color: {{colors.primary.default.hex}}
|
||||
min-width: 1.67 * {{custom.font_size}}pt
|
||||
min-height: {{custom.font_size}}pt
|
||||
border-radius: .4 * {{custom.font_size}}pt
|
||||
|
||||
.date
|
||||
@include interactive
|
||||
|
||||
.label
|
||||
color: {{colors.on_surface.default.hex}}
|
||||
font-size: {{custom.font_size}}pt
|
||||
font-family: {{custom.font_sans_serif_all}}
|
||||
font-weight: 500
|
||||
margin: 0 .5 * {{custom.padding}}pt
|
||||
|
||||
.systray
|
||||
.item
|
||||
@include interactive
|
||||
|
||||
.icon
|
||||
font-size: {{custom.font_size}}pt
|
||||
padding: 0 .3 * {{custom.padding}}pt
|
||||
color: {{colors.on_surface.default.hex}}
|
18
hosts/common/configs/user/gui/bluetooth/default.nix
Normal file
18
hosts/common/configs/user/gui/bluetooth/default.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
services.blueman.enable = true;
|
||||
|
||||
home-manager.users.${user} = {
|
||||
services.blueman-applet.enable = true;
|
||||
systemd.user.services.blueman-applet.Unit.After = [ "graphical-session.target" ];
|
||||
};
|
||||
}
|
20
hosts/common/configs/user/gui/brightnessctl/default.nix
Normal file
20
hosts/common/configs/user/gui/brightnessctl/default.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ lib, pkgs, ... }:
|
||||
{
|
||||
users.users.${user}.extraGroups = [
|
||||
"video"
|
||||
"inputs"
|
||||
];
|
||||
|
||||
home-manager.users.${user}.wayland.windowManager.hyprland.settings.bindle =
|
||||
let
|
||||
brightnessctl = lib.meta.getExe pkgs.brightnessctl;
|
||||
in
|
||||
[
|
||||
", XF86MonBrightnessUp, exec, ${brightnessctl} -q s 5%+"
|
||||
", XF86MonBrightnessDown, exec, ${brightnessctl} -q s 5%-"
|
||||
];
|
||||
}
|
29
hosts/common/configs/user/gui/btop/default.nix
Normal file
29
hosts/common/configs/user/gui/btop/default.nix
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home-manager.users.${user} = {
|
||||
programs.btop.settings.color_theme = "matugen";
|
||||
|
||||
theme = {
|
||||
template."${home}/.config/btop/themes/matugen.theme".source = ./theme.theme;
|
||||
|
||||
reloadExtraConfig = "${
|
||||
lib.meta.getExe (
|
||||
pkgs.writeShellApplication {
|
||||
name = "reload-btop";
|
||||
runtimeInputs = with pkgs; [ procps ];
|
||||
text = "exec pkill btop -SIGUSR2";
|
||||
}
|
||||
)
|
||||
} &";
|
||||
};
|
||||
};
|
||||
}
|
50
hosts/common/configs/user/gui/btop/theme.theme
Normal file
50
hosts/common/configs/user/gui/btop/theme.theme
Normal file
@@ -0,0 +1,50 @@
|
||||
theme[main_bg]="{{colors.surface.default.hex}}"
|
||||
theme[main_fg]="{{colors.on_surface.default.hex}}"
|
||||
|
||||
theme[title]="{{colors.on_surface.default.hex}}"
|
||||
theme[hi_fg]="{{colors.primary.default.hex}}"
|
||||
|
||||
theme[selected_bg]="{{colors.primary_container.default.hex}}"
|
||||
theme[selected_fg]="{{colors.on_primary_container.default.hex}}"
|
||||
theme[inactive_fg]="{{colors.surface_variant.default.hex}}"
|
||||
|
||||
theme[graph_text]="{{colors.on_surface_variant.default.hex}}"
|
||||
theme[proc_misc]="{{colors.primary.default.hex}}"
|
||||
|
||||
theme[cpu_box]="{{colors.outline.default.hex}}"
|
||||
theme[mem_box]="{{colors.outline.default.hex}}"
|
||||
theme[net_box]="{{colors.outline.default.hex}}"
|
||||
theme[proc_box]="{{colors.outline.default.hex}}"
|
||||
theme[div_line]="{{colors.outline_variant.default.hex}}"
|
||||
|
||||
theme[temp_start]="{{colors.primary.default.hex}}"
|
||||
theme[temp_mid]=""
|
||||
theme[temp_end]="{{colors.error.default.hex}}"
|
||||
|
||||
theme[cpu_start]="{{colors.primary.default.hex}}"
|
||||
theme[cpu_mid]=""
|
||||
theme[cpu_end]="{{colors.error.default.hex}}"
|
||||
|
||||
theme[used_start]="{{colors.primary.default.hex}}"
|
||||
theme[used_mid]=""
|
||||
theme[used_end]="{{colors.secondary.default.hex}}"
|
||||
|
||||
theme[available_start]="{{colors.tertiary.default.hex}}"
|
||||
theme[available_mid]=""
|
||||
theme[available_end]="{{colors.secondary.default.hex}}"
|
||||
|
||||
theme[cached_start]="{{colors.primary.default.hex}}"
|
||||
theme[cached_mid]=""
|
||||
theme[cached_end]="{{colors.secondary.default.hex}}"
|
||||
|
||||
theme[free_start]="{{colors.tertiary.default.hex}}"
|
||||
theme[free_mid]=""
|
||||
theme[free_end]="{{colors.secondary.default.hex}}"
|
||||
|
||||
theme[download_start]="{{colors.primary.default.hex}}"
|
||||
theme[download_mid]=""
|
||||
theme[download_end]="{{colors.secondary.default.hex}}"
|
||||
|
||||
theme[upload_start]="{{colors.primary.default.hex}}"
|
||||
theme[upload_mid]=""
|
||||
theme[upload_end]="{{colors.tertiary.default.hex}}"
|
21
hosts/common/configs/user/gui/cbatticon/default.nix
Normal file
21
hosts/common/configs/user/gui/cbatticon/default.nix
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home-manager.users.${user} = {
|
||||
services.cbatticon = {
|
||||
enable = true;
|
||||
lowLevelPercent = 20;
|
||||
criticalLevelPercent = 10;
|
||||
};
|
||||
|
||||
systemd.user.services.cbatticon.Unit.After = [ "graphical-session.target" ];
|
||||
};
|
||||
}
|
44
hosts/common/configs/user/gui/chromium/default.nix
Normal file
44
hosts/common/configs/user/gui/chromium/default.nix
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{ config, ... }:
|
||||
{
|
||||
programs.chromium = {
|
||||
enable = true;
|
||||
extraOpts = {
|
||||
DefaultSearchProviderEnabled = true;
|
||||
DefaultSearchProviderName = "DuckDuckGo";
|
||||
DefaultSearchProviderIconURL = "https://duckduckgo.com/favicon.ico";
|
||||
DefaultSearchProviderSearchURL = "https://duckduckgo.com/?q={searchTerms}";
|
||||
DefaultSearchProviderSuggestURL = "https://duckduckgo.com/ac/?q={searchTerms}&type=list";
|
||||
DefaultBrowserSettingEnabled = false;
|
||||
DefaultDownloadDirectory = "$HOME/Downloads";
|
||||
PasswordManagerEnabled = false;
|
||||
HomepageIsNewTabPage = true;
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence = {
|
||||
"/persist"."${home}/.config/chromium" = { };
|
||||
"/cache"."${home}/.cache/chromium" = { };
|
||||
};
|
||||
|
||||
home-manager.users.${user} = {
|
||||
programs.chromium = {
|
||||
enable = true;
|
||||
|
||||
extensions = [
|
||||
"oldceeleldhonbafppcapldpdifcinji" # LanguageTool
|
||||
"nngceckbapebfimnlniiiahkandclblb" # Bitwarden
|
||||
"eimadpbcbfnmbkopoojfekhnkhdbieeh" # Dark Reader
|
||||
"doojmbjmlfjjnbmnoijecmcbfeoakpjm" # NoScript
|
||||
"gebbhagfogifgggkldgodflihgfeippi" # Return YouTube Dislike
|
||||
"mnjggcdmjocbbbhaepdhchncahnbgone" # Sponsorblock
|
||||
"cjpalhdlnbpafiamejdnhcphjbkeiagm" # uBlock Origin
|
||||
"jinjaccalgkegednnccohejagnlnfdag" # Violentmonkey
|
||||
"fpnmgdkabkmnadcjpehmlllkndpkmiak" # Wayback Machine
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
85
hosts/common/configs/user/gui/cliphist/default.nix
Normal file
85
hosts/common/configs/user/gui/cliphist/default.nix
Normal file
@@ -0,0 +1,85 @@
|
||||
{
|
||||
user ? throw "user argument is required",
|
||||
home ? throw "home argument is required",
|
||||
}:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
hmConfig = config.home-manager.users.${user};
|
||||
in
|
||||
{
|
||||
environment.persistence."/cache"."${home}/.cache/cliphist" = { };
|
||||
|
||||
home-manager.users.${user} = {
|
||||
home.packages = with pkgs; [
|
||||
wl-clipboard
|
||||
cliphist
|
||||
];
|
||||
|
||||
systemd.user.services = {
|
||||
cliphist = {
|
||||
Unit = {
|
||||
Description = "Clipboard manager";
|
||||
BindsTo = [ "graphical-session.target" ];
|
||||
After = [
|
||||
"graphical-session.target"
|
||||
config.environment.persistence."/cache"."${home}/.cache/cliphist".mount
|
||||
];
|
||||
};
|
||||
|
||||
Service.ExecStart = lib.meta.getExe (
|
||||
pkgs.writeShellApplication {
|
||||
name = "init-cliphist";
|
||||
runtimeInputs = with pkgs; [
|
||||
wl-clipboard
|
||||
cliphist
|
||||
];
|
||||
text = "exec wl-paste --watch cliphist store";
|
||||
}
|
||||
);
|
||||
|
||||
Install.WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
|
||||
cliphist-image = {
|
||||
Unit = {
|
||||
Description = "Clipboard manager (images)";
|
||||
BindsTo = [ "graphical-session.target" ];
|
||||
After = [
|
||||
"graphical-session.target"
|
||||
config.environment.persistence."/cache"."${home}/.cache/cliphist".mount
|
||||
];
|
||||
};
|
||||
|
||||
Service.ExecStart = lib.meta.getExe (
|
||||
pkgs.writeShellApplication {
|
||||
name = "init-cliphist-image";
|
||||
runtimeInputs = with pkgs; [
|
||||
wl-clipboard
|
||||
cliphist
|
||||
];
|
||||
text = "exec wl-paste --type image --watch cliphist store";
|
||||
}
|
||||
);
|
||||
|
||||
Install.WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
};
|
||||
|
||||
wayland.windowManager.hyprland.settings.bind =
|
||||
let
|
||||
cliphist-rofi = lib.meta.getExe (
|
||||
pkgs.callPackage ./rofi.nix { rofi = hmConfig.programs.rofi.finalPackage; }
|
||||
);
|
||||
cliphist = lib.meta.getExe pkgs.cliphist;
|
||||
in
|
||||
[
|
||||
"$mod, v, exec, ${cliphist-rofi}"
|
||||
"$mod_Ctrl, v, exec, ${cliphist} wipe"
|
||||
];
|
||||
};
|
||||
}
|
31
hosts/common/configs/user/gui/cliphist/rofi.nix
Normal file
31
hosts/common/configs/user/gui/cliphist/rofi.nix
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
rofi ? throw "rofi package is required",
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
copy = lib.meta.getExe (
|
||||
pkgs.writeShellApplication {
|
||||
name = "copy";
|
||||
runtimeInputs = with pkgs; [
|
||||
cliphist
|
||||
wl-clipboard
|
||||
];
|
||||
text = builtins.readFile ./scripts/copy.sh;
|
||||
}
|
||||
);
|
||||
|
||||
delete = lib.meta.getExe (
|
||||
pkgs.writeShellApplication {
|
||||
name = "delete";
|
||||
runtimeInputs = with pkgs; [ cliphist ];
|
||||
text = builtins.readFile ./scripts/delete.sh;
|
||||
}
|
||||
);
|
||||
in
|
||||
pkgs.writeShellApplication {
|
||||
name = "cliphist-rofi";
|
||||
runtimeInputs = [ rofi ];
|
||||
text = "rofi -modi \"copy:${copy},delete:${delete}\" -show copy";
|
||||
}
|
13
hosts/common/configs/user/gui/cliphist/scripts/copy.sh
Executable file
13
hosts/common/configs/user/gui/cliphist/scripts/copy.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
list() {
|
||||
echo -en "\0keep-selection\x1ftrue\n"
|
||||
cliphist list
|
||||
}
|
||||
|
||||
handle() {
|
||||
cliphist decode <<< "$1" | wl-copy
|
||||
}
|
||||
|
||||
case ${ROFI_RETV} in
|
||||
0) list ;;
|
||||
1) handle "$@" ;;
|
||||
esac
|
13
hosts/common/configs/user/gui/cliphist/scripts/delete.sh
Executable file
13
hosts/common/configs/user/gui/cliphist/scripts/delete.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
list() {
|
||||
echo -en "\0keep-selection\x1ftrue\n"
|
||||
cliphist list
|
||||
}
|
||||
|
||||
handle() {
|
||||
cliphist delete <<< "$1"
|
||||
}
|
||||
|
||||
case ${ROFI_RETV} in
|
||||
0) list ;;
|
||||
1) handle "$@" && list ;;
|
||||
esac
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user