diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..d8e7406 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,9 @@ +keys: + - &imxyy-nix age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns + - &imxyy-nix-server age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6 +creation_rules: + - path_regex: secrets/.*\.(yaml|toml|json|env|dae|txt)$ + key_groups: + - age: + - *imxyy-nix + - *imxyy-nix-server diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9da6021 --- /dev/null +++ b/Makefile @@ -0,0 +1,45 @@ +all: fmt switch + +switch: + @echo "Rebuilding NixOS..." + @nixos-rebuild switch --flake . --use-remote-sudo + +boot: + @echo "Rebuilding NixOS..." + @nixos-rebuild boot --flake . --use-remote-sudo + +vm: + @echo "Building NixOS VM..." + @nixos-rebuild build-vm --flake . + +update: + @echo "Updating flakes..." + @nix flake update + +history: + @nix profile history --profile /nix/var/nix/profiles/system + +replpkgs: + @nix repl -f flake:nixpkgs + +repl: + @nixos-rebuild repl --flake . + +cleandry: + @echo "Listing all generations older than 15 days..." + @sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --dry-run --older-than 15d + @nix run home-manager#home-manager -- expire-generations -15days --dry-run + +clean: + @echo "Removing all generations older than 15 days..." + @sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 15d + @nix run home-manager#home-manager -- expire-generations -15days + +gc: + @nix store gc --debug + +fmt: + @echo "Formatting nix files..." + @nix fmt + +.PHONY: os home news update history repl clean gc fmt diff --git a/README.md.bak b/README.md.bak deleted file mode 100644 index d9ef10c..0000000 --- a/README.md.bak +++ /dev/null @@ -1,290 +0,0 @@ -# Nix Starter Config - -This repo contains a few a simple nix flake templates for getting started with -NixOS + home-manager. - -# What this provides - -- [Minimal version](./minimal): - - NixOS configuration on `nixos/configuration.nix`, accessible via - `nixos-rebuild --flake .` - - Home-manager configuration on `home-manager/home.nix`, accessible via - `home-manager --flake .` -- [Standard version](./standard): - - Basic boilerplate for adding custom packages (under `pkgs`) and overlays - (under `overlay`). Accessible on your system, home config, as well as `nix - build .#package-name`. - - Boilerplate for custom NixOS (`modules/nixos`) and home-manager - (`modules/home-manager`) modules - - NixOS and home-manager configurations from minimal, and they should - also use your overlays and custom packages right out of the box. - -# Getting started - -Assuming you have a basic NixOS booted up (either live or installed, anything -works). [Here's a link to the latest NixOS downloads, just for -you](https://nixos.org/download#download-nixos). - -Alternatively, you can totally use `nix` and `home-manager` on your existing -distro (or even on Darwin). [Install nix](https://nixos.org/download.html#nix) -and follow along (just ignore the `nixos-*` commands). - -## What template to chose? - -If this is your first trying flakes, or you're attempting to migrate your -(simple) config to it; you should use the minimal version. - -If you're here looking for inspiration/tips/good practices (and you already use -flakes), or you're migrating a config that already has overlays and custom -packages; try the standard version. - -## I like your funny words, magic man - -Not sure what this all means? - -Take a look at [the learn hub on the NixOS -website](https://nixos.org/learn.html) (scroll down to guides, the manuals, and -the other awesome learning resources). - -Learning the basics of what Nix (the package manager) is, how the Nix language -works, and a bit of NixOS basics should get you up and running. Don't worry if -it seems a little confusing at first. Get confortable with the basic concepts -and come back here to get your feet wet, it's the best way to learn! - -## The repo - -- [Install git](https://nixos.wiki/wiki/git), if you haven't already. -- Create a repository for your config, for example: -```bash -cd ~/Documents -git init nix-config -cd nix-config -``` -- Make sure you're running Nix 2.4+, and opt into the experimental `flakes` and `nix-command` features: -```bash -# Should be 2.4+ -nix --version -export NIX_CONFIG="experimental-features = nix-command flakes" -``` -- Get the template: -```bash -# For minimal version -nix flake init -t github:misterio77/nix-starter-config#minimal - -# For standard version -nix flake init -t github:misterio77/nix-starter-config#standard -``` -- If you want to use NixOS: add stuff you currently have on `/etc/nixos/` to - `nixos` (usually `configuration.nix` and `hardware-configuration.nix`, when - you're starting out). - - The included file has some options you might want, specially if you don't - have a configuration ready. Make sure you have generated your own - `hardware-configuration.nix`; if not, just mount your partitions to - `/mnt` and run: `nixos-generate-config --root /mnt`. -- If you want to use home-manager: add your stuff from `~/.config/nixpkgs` - to `home-manager` (probably `home.nix`). - - The included file is also a good starting point if you don't have a config - yet. -- Take a look at `flake.nix`, making sure to fill out anything marked with - FIXME (required) or TODO (usually tips or optional stuff you might want) -- `git add` and `git push` your changes! Or at least copy them somewhere if - you're on a live medium. - -## Usage - -- Run `sudo nixos-rebuild switch --flake .#hostname` to apply your system - configuration. - - If you're still on a live installation medium, run `nixos-install --flake - .#hostname` instead, and reboot. -- Run `home-manager switch --flake .#username@hostname` to apply your home - configuration. - - If you don't have home-manager installed, try `nix shell nixpkgs#home-manager`. - -And that's it, really! You're ready to have fun with your configurations using -the latest and greatest nix3 flake-enabled command UX. - -# What next? - -## Use home-manager as a NixOS module - -If you prefer to build your home configuration together with your NixOS one, -it's pretty simple. - -Simply remove the `homeConfigurations` block from the `flake.nix` file; then -add this to your NixOS configuration (either directly on -`nixos/configuration.nix` or on a separate file and import it): - -```nix -{ inputs, outputs, ... }: { - imports = [ - # Import home-manager's NixOS module - inputs.home-manager.nixosModules.home-manager - ]; - - home-manager = { - extraSpecialArgs = { inherit inputs outputs; }; - users = { - # Import your home-manager configuration - your-username = import ../home-manager/home.nix; - }; - }; -} -``` - -In this setup, the `home-manager` tool will not be installed (see -[nix-community/home-manager#4342](https://github.com/nix-community/home-manager/pull/4342)). -To rebuild your home configuration, use `nixos-rebuild` instead. - -But if you want to install the `home-manager` tool anyways, you can add the -package into your configuration: - -```nix -# To install it for a specific user -users.users = { - your-username = { - packages = [ inputs.home-manager.packages.${pkgs.system}.default ]; - }; -}; - -# To install it globally -environment.systemPackages = - [ inputs.home-manager.packages.${pkgs.system}.default ]; -``` - -## Adding more hosts or users - -You can organize them by hostname and username on `nixos` and `home-manager` -directories, be sure to also add them to `flake.nix`. - -You can take a look at my (beware, here be reproductible dragons) -[configuration repo](https://github.com/misterio77/nix-config) for ideas. - -NixOS makes it easy to share common configuration between hosts (you might want -to create a common directory for these), while keeping everything in sync. -home-manager can help you sync your environment (from editor to WM and -everything in between) anywhere you use it. Have fun! - -## User password and secrets - -You have basically two ways of setting up default passwords: -- By default, you'll be prompted for a root password when installing with - `nixos-install`. After you reboot, be sure to add a password to your own - account and lock root using `sudo passwd -l root`. -- Alternatively, you can specify `initialPassword` for your user. This will - give your account a default password, be sure to change it after rebooting! - If you do, you should pass `--no-root-passwd` to `nixos-install`, to skip - setting a password on the root account. - -If you don't want to set your password imperatively, you can also use -`passwordFile` for safely and declaratively setting a password from a file -outside the nix store. - -There's also [more advanced options for secret -management](https://nixos.wiki/wiki/Comparison_of_secret_managing_schemes), -including some that can include them (encrypted) into your config repo and/or -nix store, be sure to check them out if you're interested. - -## Dotfile management with home-manager - -Besides just adding packages to your environment, home-manager can also manage -your dotfiles. I strongly recommend you do, it's awesome! - -For full nix goodness, check out the home-manager options with `man -home-configuration.nix`. Using them, you'll be able to fully configure any -program with nix syntax and its powerful abstractions. - -Alternatively, if you're still not ready to rewrite all your configs to nix -syntax, there's home-manager options (such as `xdg.configFile`) for including -files from your config repository into your usual dot directories. Add your -existing dotfiles to this repo and try it out! - -## Try opt-in persistance - -You might have noticed that there's impurity in your NixOS system, in the form -of configuration files and other cruft your system generates when running. What -if you change them in a whim to get something working and forget about it? -Boom, your system is not fully reproductible anymore. - -You can instead fully delete your `/` and `/home` on every boot! Nix is okay -with a empty root on boot (all you need is `/boot` and `/nix`), and will -happily reapply your configurations. - -There's two main approaches to this: mount a `tmpfs` (RAM disk) to `/`, or -(using a filesystem such as btrfs or zfs) mount a blank snapshot and reset it -on boot. - -For stuff that can't be managed through nix (such as games downloaded from -steam, or logs), use [impermanence](https://github.com/nix-community/impermanence) -for mounting stuff you to keep to a separate partition/volume (such as -`/nix/persist` or `/persist`). This makes everything vanish by default, and you -can keep track of what you specifically asked to be kept. - -Here's some awesome blog posts about it: -- [Erase your darlings](https://grahamc.com/blog/erase-your-darlings) -- [Encrypted BTRFS with Opt-In State on - NixOS](https://mt-caret.github.io/blog/posts/2020-06-29-optin-state.html) -- [NixOS: tmpfs as root](https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/) and - [tmpfs as home](https://elis.nu/blog/2020/06/nixos-tmpfs-as-home/) - -Note that for `home-manager` to work correctly here, you need to set up its -NixOS module, as described in the [previous section](#use-home-manager-as-a-nixos-module). - -## Adding custom packages - -Something you want to use that's not in nixpkgs yet? You can easily build and -iterate on a derivation (package) from this very repository. - -Create a folder with the desired name inside `pkgs`, and add a `default.nix` -file containing a derivation. Be sure to also `callPackage` them on -`pkgs/default.nix`. - -You'll be able to refer to that package from anywhere on your -home-manager/nixos configurations, build them with `nix build .#package-name`, -or bring them into your shell with `nix shell .#package-name`. - -See [the manual](https://nixos.org/manual/nixpkgs/stable/) for some tips on how -to package stuff. - -## Adding overlays - -Found some outdated package on nixpkgs you need the latest version of? Perhaps -you want to apply a patch to fix a behaviour you don't like? Nix makes it easy -and manageble with overlays! - -Use the `overlays/default.nix` file for this. - -If you're creating patches, you can keep them on the `overlays` folder as well. - -See [the wiki article](https://nixos.wiki/wiki/Overlays) to see how it all -works. - -## Adding your own modules - -Got some configurations you want to create an abstraction of? Modules are the -answer. These awesome files can expose _options_ and implement _configurations_ -based on how the options are set. - -Create a file for them on either `modules/nixos` or `modules/home-manager`. Be -sure to also add them to the listing at `modules/nixos/default.nix` or -`modules/home-manager/default.nix`. - -See [the wiki article](https://nixos.wiki/wiki/Module) to learn more about -them. - -# Troubleshooting / FAQ - -Please [let me know](https://github.com/Misterio77/nix-starter-config/issues) -any questions or issues you face with these templates, so I can add more info -here! - -## Nix says my repo files don't exist, even though they do! - -Nix flakes only see files that git is currently tracked, so just `git add .` -and you should be good to go. Files on `.gitignore`, of course, are invisible -to nix - this is to guarantee your build won't depend on anything that is not -on your repo. - - diff --git a/config/base.nix b/config/base.nix new file mode 100644 index 0000000..9657036 --- /dev/null +++ b/config/base.nix @@ -0,0 +1,26 @@ +{ lib, hostname, ... }: +{ + environment.etc.issue.text = "\\e{lightcyan}\\S\\e{reset} Login (\\l)\n\n"; + networking.hostName = hostname; + system.stateVersion = "24.11"; + systemd.services."systemd-machine-id-commit".enable = lib.mkForce false; + + my = { + home = { + # Nicely reload system units when changing configs + systemd.user.startServices = "sd-switch"; + home.stateVersion = "24.11"; + }; + + xdg.enable = true; + persist = { + nixosDirs = [ + "/root" + "/var" + ]; + nixosFiles = [ + "/etc/machine-id" + ]; + }; + }; +} diff --git a/config/hosts/imxyy-nix-server/ai.nix b/config/hosts/imxyy-nix-server/ai.nix new file mode 100644 index 0000000..a206279 --- /dev/null +++ b/config/hosts/imxyy-nix-server/ai.nix @@ -0,0 +1,15 @@ +{ ... }: +{ + services.open-webui = { + enable = true; + host = "127.0.0.1"; + port = 8089; + }; + services.caddy.virtualHosts."ai.imxyy.top" = { + extraConfig = '' + reverse_proxy :8089 { + header_up X-Real-IP {remote_host} + } + ''; + }; +} diff --git a/config/hosts/imxyy-nix-server/caddy.nix b/config/hosts/imxyy-nix-server/caddy.nix new file mode 100644 index 0000000..3222427 --- /dev/null +++ b/config/hosts/imxyy-nix-server/caddy.nix @@ -0,0 +1,11 @@ +{ ... }: +{ + services.caddy = { + enable = true; + email = "acme@imxyy.top"; + }; + security.acme = { + acceptTerms = true; + defaults.email = "acme@imxyy.top"; + }; +} diff --git a/config/hosts/imxyy-nix-server/code.nix b/config/hosts/imxyy-nix-server/code.nix new file mode 100644 index 0000000..4f93786 --- /dev/null +++ b/config/hosts/imxyy-nix-server/code.nix @@ -0,0 +1,38 @@ +{ config, ... }: +{ + services.postgresql.ensureUsers = [ + { + name = "coder"; + ensureDBOwnership = true; + } + ]; + services.postgresql.ensureDatabases = [ "coder" ]; + virtualisation.oci-containers = { + containers = { + coder = { + image = "ghcr.io/coder/coder:latest"; + environment = { + CODER_ACCESS_URL = "https://coder.imxyy.top"; + CODER_HTTP_ADDRESS = "0.0.0.0:8086"; + CODER_PG_CONNECTION_URL = "postgresql://coder:coderdatabase@127.0.0.1/coder?sslmode=disable"; + }; + extraOptions = [ + "--network=host" + "--group-add=${toString config.users.groups.podman.gid}" + ]; + volumes = [ + "/var/lib/coder:/home/coder/.config" + "/var/run/docker.sock:/var/run/docker.sock" + ]; + ports = [ "8086:8086" ]; + }; + }; + }; + services.caddy.virtualHosts."coder.imxyy.top" = { + extraConfig = '' + reverse_proxy :8086 { + header_up X-Real-IP {remote_host} + } + ''; + }; +} diff --git a/config/hosts/imxyy-nix-server/default.nix b/config/hosts/imxyy-nix-server/default.nix new file mode 100644 index 0000000..1e88cc8 --- /dev/null +++ b/config/hosts/imxyy-nix-server/default.nix @@ -0,0 +1,26 @@ +{ ... }: +{ + imports = [ + ./nixos.nix + ./hardware.nix + ./home.nix + ./virt.nix + ./docker.nix + ./minecraft.nix + ./samba.nix + ./net.nix + ./caddy.nix + ./nextcloud.nix + ./mail.nix + ./gitea.nix + ./vault.nix + ./homepage.nix + ./code.nix + ./yesplaymusic.nix + ./ai.nix + ./grafana.nix + ./note.nix + ./matrix.nix + ./minio.nix + ]; +} diff --git a/config/hosts/imxyy-nix-server/docker.nix b/config/hosts/imxyy-nix-server/docker.nix new file mode 100644 index 0000000..ec2064c --- /dev/null +++ b/config/hosts/imxyy-nix-server/docker.nix @@ -0,0 +1,9 @@ +{ lib, ... }: +{ + virtualisation.oci-containers.backend = lib.mkForce "podman"; + virtualisation.podman = { + enable = true; + dockerCompat = true; + dockerSocket.enable = true; + }; +} diff --git a/config/hosts/imxyy-nix-server/gitea.nix b/config/hosts/imxyy-nix-server/gitea.nix new file mode 100644 index 0000000..ebcd205 --- /dev/null +++ b/config/hosts/imxyy-nix-server/gitea.nix @@ -0,0 +1,46 @@ +{ ... }: +{ + services.caddy.virtualHosts."git.imxyy.top" = { + extraConfig = '' + reverse_proxy :8082 { + header_up X-Real-IP {remote_host} + } + ''; + }; + services.gitea = { + enable = true; + appName = "imxyy_soope_'s Gitea"; + user = "git"; + group = "git"; + mailerPasswordFile = "/var/lib/gitea/smtp_password"; + stateDir = "/mnt/nas/gitea"; + settings = { + globalSection = { + LANDING_PAGE = "explore"; + }; + server = { + DOMAIN = "git.imxyy.top"; + HTTP_ADDR = "127.0.0.1"; + HTTP_PORT = 8082; + ROOT_URL = "https://git.imxyy.top/"; + SSH_PORT = 2222; + }; + service = { + REGISTER_MANUAL_CONFIRM = true; + }; + }; + }; + services.openssh.ports = [ + 22 + 2222 + ]; + users = { + users.git = { + isNormalUser = true; + description = "git user"; + group = "git"; + home = "/mnt/nas/gitea"; + }; + groups.git = { }; + }; +} diff --git a/config/hosts/imxyy-nix-server/grafana.nix b/config/hosts/imxyy-nix-server/grafana.nix new file mode 100644 index 0000000..ad1ea54 --- /dev/null +++ b/config/hosts/imxyy-nix-server/grafana.nix @@ -0,0 +1,45 @@ +{ pkgs, ... }: +{ + services.grafana = { + enable = true; + settings = { + server = { + http_addr = "0.0.0.0"; + http_port = 8090; + domain = "grafana.imxyy.top"; + }; + }; + }; + services.prometheus = { + enable = true; + package = pkgs.stable.prometheus; + port = 8091; + exporters = { + node = { + enable = true; + port = 8092; + enabledCollectors = [ + "systemd" + "zfs" + ]; + }; + }; + scrapeConfigs = [ + { + job_name = "node"; + static_configs = [ + { + targets = [ "127.0.0.1:8092" ]; + } + ]; + } + ]; + }; + services.caddy.virtualHosts."grafana.imxyy.top" = { + extraConfig = '' + reverse_proxy :8090 { + header_up X-Real-IP {remote_host} + } + ''; + }; +} diff --git a/config/hosts/imxyy-nix-server/hardware.nix b/config/hosts/imxyy-nix-server/hardware.nix new file mode 100644 index 0000000..a0e7abb --- /dev/null +++ b/config/hosts/imxyy-nix-server/hardware.nix @@ -0,0 +1,99 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + boot.initrd.availableKernelModules = [ + "xhci_pci" + "ahci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + ]; + boot.initrd.kernelModules = [ "amdgpu" ]; + boot.kernelModules = [ "kvm-amd" ]; + boot.kernelPackages = lib.mkForce pkgs.stable.linuxKernel.packages.linux_zen; + boot.extraModulePackages = [ ]; + boot.tmp.useTmpfs = true; + boot.supportedFilesystems = [ "zfs" ]; + boot.zfs = { + extraPools = [ "data" ]; + forceImportRoot = false; + }; + services.zfs.autoScrub.enable = true; + services.btrfs.autoScrub.enable = true; + networking.hostId = "10ca95b4"; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0"; + fsType = "btrfs"; + options = [ + "compress=zstd" + "subvol=root" + ]; + }; + + fileSystems."/nix" = { + device = "/dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0"; + fsType = "btrfs"; + options = [ + "compress=zstd" + "subvol=nix" + ]; + }; + + fileSystems."/persistent" = { + device = "/dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0"; + fsType = "btrfs"; + options = [ + "compress=zstd" + "subvol=persist" + ]; + neededForBoot = true; + }; + + boot.initrd.postDeviceCommands = lib.mkAfter '' + mkdir /btrfs_tmp + mount /dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0 /btrfs_tmp + mkdir -p /btrfs_tmp/old_roots + if [[ -e /btrfs_tmp/root ]]; then + timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S") + mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp" + fi + + delete_subvolume_recursively() { + IFS=$'\n' + for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do + delete_subvolume_recursively "/btrfs_tmp/$i" + done + btrfs subvolume delete "$1" + } + + for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +14); do + delete_subvolume_recursively "$i" + done + + btrfs subvolume create /btrfs_tmp/root + umount /btrfs_tmp + ''; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/32AA-2998"; + fsType = "vfat"; + }; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault false; + + hardware.enableRedistributableFirmware = lib.mkDefault true; + hardware.cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware; + + nixpkgs.hostPlatform = lib.mkForce "x86_64-linux"; +} diff --git a/config/hosts/imxyy-nix-server/home.nix b/config/hosts/imxyy-nix-server/home.nix new file mode 100644 index 0000000..5cfa02b --- /dev/null +++ b/config/hosts/imxyy-nix-server/home.nix @@ -0,0 +1,37 @@ +{ lib, ... }: +{ + my.home = { + programs.zsh = { + shellAliases = { + proxy_on = lib.mkForce "export http_proxy=http://127.0.0.1:7890 https_proxy=http://127.0.0.1:7890 all_proxy=socks://127.0.0.1:7891"; + }; + sessionVariables = { + no_proxy = "192.168.3.0/24"; + }; + }; + }; + my = { + cmd.all.enable = true; + coding.editor.neovim.enable = true; + coding.misc.enable = true; + coding.langs.lua.enable = true; + persist = { + enable = true; + homeDirs = [ + "workspace" + "Virt" + + ".ssh" + ".local/state" + ".local/share" + ".local/share/nvim" + ".cache" + + ".ollama" + ]; + nixosDirs = [ + "/etc/ssh" + ]; + }; + }; +} diff --git a/config/hosts/imxyy-nix-server/homepage.nix b/config/hosts/imxyy-nix-server/homepage.nix new file mode 100644 index 0000000..4bb4846 --- /dev/null +++ b/config/hosts/imxyy-nix-server/homepage.nix @@ -0,0 +1,19 @@ +{ ... }: +{ + virtualisation.oci-containers = { + containers = { + sun-panel = { + image = "hslr/sun-panel:latest"; + volumes = [ + "/var/lib/sun-panel:/app/conf" + ]; + ports = [ "8085:3002" ]; + }; + }; + }; + services.caddy.virtualHosts."home.imxyy.top" = { + extraConfig = '' + reverse_proxy :8085 + ''; + }; +} diff --git a/config/hosts/imxyy-nix-server/mail.nix b/config/hosts/imxyy-nix-server/mail.nix new file mode 100644 index 0000000..7c9e747 --- /dev/null +++ b/config/hosts/imxyy-nix-server/mail.nix @@ -0,0 +1,54 @@ +{ pkgs, ... }: +{ + services.roundcube = { + enable = true; + hostName = "mail.imxyy.top"; + plugins = [ + "contextmenu" + "persistent_login" + ]; + package = pkgs.roundcube.withPlugins ( + plugins: with plugins; [ + contextmenu + persistent_login + ] + ); + extraConfig = '' + # starttls needed for authentication, so the fqdn required to match + # the certificate + $config['imap_conn_options'] = [ + 'ssl' => [ + 'verify_peer_name' => false, + ], + ]; + $config['imap_host'] = "tls://mail10.serv00.com"; + $config['imap_user'] = "%u"; + $config['imap_pass'] = "%p"; + $config['smtp_conn_options'] = [ + 'ssl' => [ + 'verify_peer_name' => false, + ], + ]; + $config['smtp_host'] = "tls://mail10.serv00.com"; + $config['smtp_user'] = "%u"; + $config['smtp_pass'] = "%p"; + ''; + }; + services.nginx.virtualHosts."mail.imxyy.top" = { + listen = [ + { + addr = "0.0.0.0"; + port = 8087; + } + ]; + forceSSL = false; + enableACME = false; + }; + services.caddy.virtualHosts."mail.imxyy.top" = { + extraConfig = '' + reverse_proxy :8087 { + header_up X-Real-IP {remote_host} + } + ''; + }; +} diff --git a/config/hosts/imxyy-nix-server/matrix.nix b/config/hosts/imxyy-nix-server/matrix.nix new file mode 100644 index 0000000..c833822 --- /dev/null +++ b/config/hosts/imxyy-nix-server/matrix.nix @@ -0,0 +1,47 @@ +{ ... }: +{ + services.matrix-synapse = { + enable = true; + settings = { + server_name = "matrix.imxyy.top"; + public_baseurl = "https://matrix.imxyy.top"; + listeners = [ + { + port = 8094; + bind_addresses = [ "127.0.0.1" ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = [ + { + names = [ + "client" + "federation" + ]; + compress = true; + } + ]; + } + ]; + turn_uris = [ "turns:vkvm.imxyy.top:5349" ]; + turn_shared_secret = "ac779a48c03bb451839569d295a29aa6ab8c264277bec2df9c9c7f5e22936288"; + turn_user_lifetime = "1h"; + database_type = "psycopg2"; + database_args.database = "matrix-synapse"; + }; + extraConfigFiles = [ + "/var/lib/matrix-synapse/secret" + ]; + }; + services.caddy.virtualHosts."matrix.imxyy.top" = { + extraConfig = '' + reverse_proxy :8094 + handle_path /_matrix { + reverse_proxy :8094 + } + handle_path /_synapse/client { + reverse_proxy :8094 + } + ''; + }; +} diff --git a/config/hosts/imxyy-nix-server/minecraft.nix b/config/hosts/imxyy-nix-server/minecraft.nix new file mode 100644 index 0000000..bc77ee3 --- /dev/null +++ b/config/hosts/imxyy-nix-server/minecraft.nix @@ -0,0 +1,19 @@ +{ lib, pkgs, ... }: +{ + systemd.services."fabric1.20.6" = { + description = "fabric 1.20.6 minecraft server"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + WorkingDirectory = "/opt/minecraft/fabric1.20.6"; + ExecStart = "${lib.getExe' pkgs.openjdk21 "java"} -Xms1G -Xmx5G -jar fabric-server-mc.1.20.6-loader.0.15.11-launcher.1.0.1.jar"; + Restart = "always"; + RestartSec = "10s"; + }; + }; + my.persist = { + nixosDirs = [ + "/opt/minecraft" + ]; + }; +} diff --git a/config/hosts/imxyy-nix-server/minio.nix b/config/hosts/imxyy-nix-server/minio.nix new file mode 100644 index 0000000..7968e8f --- /dev/null +++ b/config/hosts/imxyy-nix-server/minio.nix @@ -0,0 +1,26 @@ +{ config, sopsRoot, ... }: +{ + sops.secrets.minio-env = { + sopsFile = sopsRoot + /minio.env; + format = "dotenv"; + }; + services.minio = { + enable = true; + listenAddress = ":9000"; + consoleAddress = ":9001"; + region = "cn-south-gz"; + + configDir = "/mnt/nas/minio/config"; + dataDir = [ + "/mnt/nas/minio/data" + ]; + rootCredentialsFile = config.sops.secrets.minio-env.path; + }; + services.caddy.virtualHosts."minio.imxyy.top" = { + extraConfig = '' + handle_path /* { + reverse_proxy :9000 + } + ''; + }; +} diff --git a/config/hosts/imxyy-nix-server/net.nix b/config/hosts/imxyy-nix-server/net.nix new file mode 100644 index 0000000..6913135 --- /dev/null +++ b/config/hosts/imxyy-nix-server/net.nix @@ -0,0 +1,645 @@ +{ + config, + lib, + pkgs, + username, + sopsRoot, + ... +}: +{ + boot.kernelParams = [ + "biosdevname=0" + "net.ifnames=0" + ]; + networking = { + useDHCP = lib.mkForce false; + dhcpcd = { + wait = "background"; + IPv6rs = true; + extraConfig = '' + interface mac0 + noipv4 + ''; + }; + interfaces = { + eth0.wakeOnLan.enable = true; + eth1.wakeOnLan.enable = true; + mac0 = { + useDHCP = true; + ipv4.addresses = [ + { + address = "192.168.3.2"; + prefixLength = 24; + } + ]; + }; + }; + macvlans."mac0" = { + interface = "eth0"; + mode = "bridge"; + }; + defaultGateway = { + address = "192.168.3.1"; + interface = "mac0"; + }; + nameservers = [ + "192.168.3.1" + ]; + + firewall.enable = false; + nftables = { + enable = true; + flushRuleset = true; + ruleset = '' + table inet firewall { + set LANv4 { + type ipv4_addr + flags interval + + elements = { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 } + } + set LANv6 { + type ipv6_addr + flags interval + + elements = { fd00::/8, fe80::/10 } + } + set tcp_ports { + type inet_service + flags interval + + elements = { + http, + https, + 2222, + 25565 + } + } + + chain prerouting { + type filter hook prerouting priority mangle; policy accept; + + ip daddr @LANv4 accept + ip6 daddr @LANv6 accept + } + + chain output { + type filter hook output priority 100; policy accept; + + ip daddr @LANv4 accept + ip6 daddr @LANv6 accept + } + + chain input { + type filter hook input priority 0; policy drop; + iif lo accept + ct state invalid drop + ct state established,related accept + + ip protocol { icmp, igmp } accept + + ip saddr @LANv4 accept + ip6 saddr @LANv6 accept + + tcp dport 2222 ct state new limit rate 15/minute counter accept + + tcp dport @tcp_ports counter accept + } + + chain forward { + type filter hook forward priority 0; policy accept; + } + + chain nat { + type nat hook postrouting priority 0; policy accept; + ip saddr 192.168.3.0/24 masquerade + } + } + ''; + }; + }; + + services.openssh = { + enable = true; + settings = { + # PermitRootLogin = "yes"; + PermitRootLogin = "prohibit-password"; + PasswordAuthentication = true; + }; + }; + users.users.root.openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOEFLUkyeaK8ZPPZdVNEmtx8zvoxi7xqS2Z6oxRBuUPO imxyy@imxyy-nix" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKqza/3b6a9JxsNxytHF5GPe4gQhbLrKxAPyZ0GpfVQt imxyy-hisense-pad" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8pivvE8PMtsOxmccfNhH/4KehDKhBfUfJbQZxo/SZT imxyy-ace5" + ]; + users.users.${username}.openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOEFLUkyeaK8ZPPZdVNEmtx8zvoxi7xqS2Z6oxRBuUPO imxyy@imxyy-nix" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKqza/3b6a9JxsNxytHF5GPe4gQhbLrKxAPyZ0GpfVQt imxyy-hisense-pad" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8pivvE8PMtsOxmccfNhH/4KehDKhBfUfJbQZxo/SZT imxyy-ace5" + ]; + + sops.secrets.dae-imxyy-nix-server = { + sopsFile = sopsRoot + /dae-imxyy-nix-server.dae; + format = "binary"; + }; + services.dae = { + enable = true; + configFile = config.sops.secrets.dae-imxyy-nix-server.path; + }; + systemd.services.dae.after = [ "sops-nix.service" ]; + sops.secrets.mihomo = { + sopsFile = sopsRoot + /mihomo.yaml; + format = "yaml"; + key = ""; + }; + systemd.services.mihomo.after = [ "sops-nix.service" ]; + services.mihomo = { + enable = true; + configFile = config.sops.secrets.mihomo.path; + webui = pkgs.metacubexd; + }; + + sops.secrets.frp-env = { + sopsFile = sopsRoot + /frp.env; + format = "dotenv"; + }; + systemd.services.frp.serviceConfig.EnvironmentFile = [ + config.sops.secrets.frp-env.path + ]; + services.frp = { + enable = true; + role = "client"; + settings = { + serverAddr = "vkvm.imxyy.top"; + serverPort = 7000; + auth.token = "{{ .Envs.FRP_AUTH_TOKEN }}"; + proxies = [ + { + name = "nextcloud-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "nextcloud.imxyy.top" ]; + } + { + name = "nextcloud-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "nextcloud.imxyy.top" ]; + } + + { + name = "oidc-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "oidc.imxyy.top" ]; + } + { + name = "oidc-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "oidc.imxyy.top" ]; + } + { + name = "headscale-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "headscale.imxyy.top" ]; + } + { + name = "headscale-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "headscale.imxyy.top" ]; + } + + { + name = "mail-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "mail.imxyy.top" ]; + } + { + name = "mail-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "mail.imxyy.top" ]; + } + + { + name = "gitea-ssh"; + type = "tcp"; + localIP = "127.0.0.1"; + localPort = 2222; + remotePort = 2222; + } + { + name = "gitea-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "git.imxyy.top" ]; + } + { + name = "gitea-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "git.imxyy.top" ]; + } + + { + name = "vault-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "vault.imxyy.top" ]; + } + { + name = "vault-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "vault.imxyy.top" ]; + } + + { + name = "home-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "home.imxyy.top" ]; + } + { + name = "home-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "home.imxyy.top" ]; + } + + { + name = "coder-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "coder.imxyy.top" ]; + } + { + name = "coder-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "coder.imxyy.top" ]; + } + + { + name = "music-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "music.imxyy.top" ]; + } + { + name = "music-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "music.imxyy.top" ]; + } + + { + name = "ai-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "ai.imxyy.top" ]; + } + { + name = "ai-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "ai.imxyy.top" ]; + } + + { + name = "grafana-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "grafana.imxyy.top" ]; + } + { + name = "grafana-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "grafana.imxyy.top" ]; + } + + { + name = "note-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "note.imxyy.top" ]; + } + { + name = "note-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "note.imxyy.top" ]; + } + + { + name = "siyuan-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "sy.imxyy.top" ]; + } + { + name = "siyuan-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "sy.imxyy.top" ]; + } + + { + name = "matrix-http"; + type = "http"; + localIP = "127.0.0.1"; + localPort = 80; + customDomains = [ "matrix.imxyy.top" ]; + } + { + name = "matrix-https"; + type = "https"; + localIP = "127.0.0.1"; + localPort = 443; + customDomains = [ "matrix.imxyy.top" ]; + } + + { + name = "minecraft"; + type = "tcp"; + localIP = "127.0.0.1"; + localPort = 25565; + remotePort = 25565; + } + ]; + }; + }; + + services.tailscale = { + enable = true; + useRoutingFeatures = "both"; + extraSetFlags = [ "--accept-dns=false" ]; + }; + services.headscale = { + enable = true; + address = "0.0.0.0"; + port = 8080; + settings = { + logtail.enabled = false; + server_url = "https://headscale.imxyy.top"; + dns = { + base_domain = "tailnet.imxyy.top"; + extra_records = [ + { + "name" = "home.imxyy.top"; + "type" = "A"; + "value" = "100.64.0.2"; + } + { + "name" = "nextcloud.imxyy.top"; + "type" = "A"; + "value" = "100.64.0.2"; + } + { + "name" = "mail.imxyy.top"; + "type" = "A"; + "value" = "100.64.0.2"; + } + { + "name" = "git.imxyy.top"; + "type" = "A"; + "value" = "100.64.0.2"; + } + { + "name" = "vault.imxyy.top"; + "type" = "A"; + "value" = "100.64.0.2"; + } + { + "name" = "mc.imxyy.top"; + "type" = "A"; + "value" = "100.64.0.2"; + } + { + "name" = "home.imxyy.top"; + "type" = "A"; + "value" = "100.64.0.2"; + } + { + "name" = "coder.imxyy.top"; + "type" = "A"; + "value" = "100.64.0.2"; + } + { + "name" = "music.imxyy.top"; + "type" = "A"; + "value" = "100.64.0.2"; + } + ]; + }; + ip_prefixes = "100.64.0.0/10"; + derp.paths = [ + (toString ( + pkgs.writeText "derp.yaml" '' + regions: + 900: + regionid: 900 + regioncode: custom-tok + regionname: imxyy_soope_ Tokyo + nodes: + - name: 900a + regionid: 900 + hostname: vkvm.imxyy.top + # 901: + # regionid: 901 + # regioncode: custom-cn + # regionname: imxyy_soope_ Hu Bei + # nodes: + # - name: 901a + # regionid: 901 + # hostname: ry.imxyy.top + # derpport: 1443 + '' + )) + ]; + derp.urls = lib.mkForce [ ]; + + oidc = { + only_start_if_oidc_is_available = true; + issuer = "https://oidc.imxyy.top"; + client_id = "https://headscale.imxyy.top"; + allowed_domains = [ + "imxyy.top" + "*.imxyy.top" + ]; + client_secret = ""; + expiry = 0; + extra_params.domain_hint = "imxyy.top"; + strip_email_domain = true; + }; + }; + }; + systemd.services."headscale" = { + serviceConfig = { + Restart = lib.mkOverride 500 "always"; + RestartMaxDelaySec = lib.mkOverride 500 "1m"; + RestartSec = lib.mkOverride 500 "100ms"; + RestartSteps = lib.mkOverride 500 9; + }; + after = [ + "podman-obligator.service" + ]; + requires = [ + "podman-obligator.service" + ]; + }; + + sops.secrets.et-imxyy-nix-server = { + sopsFile = sopsRoot + /et-imxyy-nix-server.toml; + format = "binary"; + }; + environment.systemPackages = [ pkgs.easytier ]; + systemd.services."easytier" = { + enable = true; + script = "easytier-core -c ${config.sops.secrets.et-imxyy-nix-server.path}"; + serviceConfig = { + Restart = lib.mkOverride 500 "always"; + RestartMaxDelaySec = lib.mkOverride 500 "1m"; + RestartSec = lib.mkOverride 500 "100ms"; + RestartSteps = lib.mkOverride 500 9; + User = "root"; + }; + wantedBy = [ "multi-user.target" ]; + after = [ + "network.target" + "sops-nix.service" + ]; + path = with pkgs; [ + easytier + iproute2 + bash + ]; + }; + + virtualisation.oci-containers = { + containers = { + obligator = { + image = "anderspitman/obligator:latest"; + volumes = [ + "/var/lib/obligator:/data" + "/var/lib/obligator:/api" + ]; + ports = [ "8081:1616" ]; + cmd = [ + "-storage-dir" + "/data" + "-api-socket-dir" + "/api" + "-root-uri" + "https://oidc.imxyy.top" + "-port" + "1616" + ]; + }; + }; + }; + services.caddy.virtualHosts."headscale.imxyy.top" = { + extraConfig = '' + reverse_proxy :8080 { + header_up X-Real-IP {remote_host} + } + ''; + }; + services.caddy.virtualHosts."oidc.imxyy.top" = { + extraConfig = '' + reverse_proxy :8081 { + header_up X-Real-IP {remote_host} + } + ''; + }; + + systemd.services.ddns-go = + let + ddns-go = pkgs.buildGoModule rec { + pname = "ddns-go"; + version = "6.6.7"; + src = pkgs.fetchFromGitHub { + owner = "jeessy2"; + repo = "ddns-go"; + rev = "v${version}"; + hash = "sha256-Ejoe6e9GFhHxQ9oIBDgDRQW9Xx1XZK+qSAXiRXLdn+c="; + }; + meta.mainProgram = "ddns-go"; + vendorHash = "sha256-XZii7gV3DmTunYyGYzt5xXhv/VpTPIoYKbW4LnmlAgs="; + doCheck = false; + }; + in + { + description = "Go Dynamic DNS"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = "${lib.getExe ddns-go} -l :9876 -f 10 -cacheTimes 180 -c /var/lib/ddns-go/config.yaml"; + Restart = "always"; + RestartSec = 120; + }; + }; + + services.dnsmasq = + let + subDomains = [ + "home" + "nextcloud" + "mail" + "git" + "vault" + "coder" + "headscale" + "oidc" + "mc" + "music" + "ai" + ]; + in + { + enable = true; + resolveLocalQueries = false; + settings = { + server = [ + "120.53.53.53" + "223.5.5.5" + ]; + address = map (sub: "/${sub}.imxyy.top/192.168.3.2") subDomains ++ [ + "/imxyy-nix-server/192.168.3.2" + "/imxyy-cloudwin/192.168.3.4" + "/printer.home/192.168.3.53" + ]; + }; + }; +} diff --git a/config/hosts/imxyy-nix-server/nextcloud.nix b/config/hosts/imxyy-nix-server/nextcloud.nix new file mode 100644 index 0000000..42c6847 --- /dev/null +++ b/config/hosts/imxyy-nix-server/nextcloud.nix @@ -0,0 +1,143 @@ +{ + lib, + pkgs, + hostname, + ... +}: +let + nextcloud = "nextcloud.${imxyy}"; + imxyy = "imxyy.top"; +in +{ + environment.systemPackages = with pkgs; [ + exiftool + ffmpeg + rclone + ]; + + services.nextcloud = { + enable = true; + package = pkgs.nextcloud31; + extraApps = { + inherit (pkgs.nextcloud31.packages.apps) + bookmarks + previewgenerator + spreed + notes + registration + ; + }; + extraAppsEnable = true; + hostName = nextcloud; + home = "/mnt/nas/nextcloud"; + https = true; + nginx.recommendedHttpHeaders = true; + caching.redis = true; + configureRedis = true; + database.createLocally = true; + config = { + dbtype = "pgsql"; + adminpassFile = toString (pkgs.writeText "nextcloud-pass" "admin12345!"); + adminuser = "admin"; + }; + settings.trusted_domains = [ + hostname + "192.168.3.2" + "10.0.0.1" + ]; + phpExtraExtensions = + all: with all; [ + pdlib + ]; + maxUploadSize = "16G"; + phpOptions = { + "opcache.enable" = 1; + "opcache.enable_cli" = 1; + "opcache.interned_strings_buffer" = 8; + "opcache.max_accelerated_files" = 10000; + "opcache.memory_consumption" = 128; + "opcache.save_comments" = 1; + "opcache.revalidate_freq" = 1; + memory_limit = lib.mkForce "2G"; + }; + poolSettings = { + pm = "dynamic"; + "pm.max_children" = "12"; + "pm.min_spare_servers" = "6"; + "pm.max_spare_servers" = "12"; + }; + }; + services.nginx.virtualHosts."nextcloud.imxyy.top" = { + listen = [ + { + addr = "0.0.0.0"; + port = 8084; + } + ]; + }; + /* + services.caddy.virtualHosts.":80" = { + extraConfig = '' + redir https://{host}{uri} + ''; + }; + services.caddy.virtualHosts.":443" = { + extraConfig = + let + path = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/nextcloud.imxyy.top"; + in + '' + reverse_proxy :8084 + tls ${path}/nextcloud.imxyy.top.crt ${path}/nextcloud.imxyy.top.key + ''; + }; + */ + services.caddy.virtualHosts."nextcloud.imxyy.top" = { + extraConfig = '' + reverse_proxy :8084 { + header_up X-Real-IP {remote_host} + } + ''; + }; + + /* + systemd.timers."kopia" = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "daily"; + Persistent = true; + Unit = "kopia.service"; + }; + }; + */ + + systemd.services."kopia" = { + script = '' + ${pkgs.kopia}/bin/kopia snapshot create /mnt/nas/share + ${pkgs.kopia}/bin/kopia snapshot create /mnt/nas/nextcloud/data + ''; + serviceConfig = { + Type = "oneshot"; + User = "nextcloud"; + }; + }; + + systemd.timers."nextcloud-cronjobs" = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "daily"; + Persistent = true; + Unit = "nextcloud-cronjobs.service"; + }; + }; + + systemd.services."nextcloud-cronjobs" = { + script = '' + /run/current-system/sw/bin/nextcloud-occ preview:pre-generate + ''; + serviceConfig = { + Type = "oneshot"; + User = "nextcloud"; + }; + }; +} diff --git a/config/hosts/imxyy-nix-server/nginx.nix b/config/hosts/imxyy-nix-server/nginx.nix new file mode 100644 index 0000000..6d80a41 --- /dev/null +++ b/config/hosts/imxyy-nix-server/nginx.nix @@ -0,0 +1,15 @@ +{ ... }: +{ + services.nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + clientMaxBodySize = "0"; + }; + security.acme = { + acceptTerms = true; + defaults.email = "acme@imxyy.top"; + }; +} diff --git a/config/hosts/imxyy-nix-server/nixos.nix b/config/hosts/imxyy-nix-server/nixos.nix new file mode 100644 index 0000000..5fc6c84 --- /dev/null +++ b/config/hosts/imxyy-nix-server/nixos.nix @@ -0,0 +1,32 @@ +{ + lib, + config, + username, + sopsRoot, + ... +}: +{ + boot.loader = { + efi.canTouchEfiVariables = true; + systemd-boot.enable = true; + grub.enable = false; + timeout = 0; + }; + + hardware.bluetooth.enable = true; + hardware.bluetooth.powerOnBoot = true; + + systemd.services.nix-daemon = { + environment.TMPDIR = "/var/cache/nix"; + serviceConfig.CacheDirectory = "nix"; + }; + environment.variables.NIX_REMOTE = "daemon"; + + sops.secrets.imxyy-nix-server-hashed-password = { + sopsFile = sopsRoot + /imxyy-nix-server-hashed-password.txt; + format = "binary"; + }; + users.users.${username}.hashedPasswordPath = + lib.mkForce config.sops.secrets.imxyy-nix-server-hashed-password.path; + users.users.root.hashedPassword = lib.mkForce config.sops.secrets.imxyy-nix-server-hashed-password.path; +} diff --git a/config/hosts/imxyy-nix-server/note.nix b/config/hosts/imxyy-nix-server/note.nix new file mode 100644 index 0000000..d0c7ee2 --- /dev/null +++ b/config/hosts/imxyy-nix-server/note.nix @@ -0,0 +1,61 @@ +{ + config, + sopsRoot, + ... +}: +{ + sops.secrets = { + flatnote-env = { + sopsFile = sopsRoot + /flatnote.env; + format = "dotenv"; + }; + siyuan-env = { + sopsFile = sopsRoot + /siyuan.env; + format = "dotenv"; + }; + }; + virtualisation.oci-containers = { + containers = { + flatnotes = { + image = "dullage/flatnotes:latest"; + volumes = [ + "/mnt/nas/flatnotes/data:/data" + ]; + environmentFiles = [ + "${config.sops.secrets.flatnote-env.path}" + ]; + ports = [ "8093:8080" ]; + }; + siyuan = { + image = "apkdv/siyuan-unlock:v3.1.24"; + volumes = [ + "/mnt/nas/siyuan/workspace:/workspace" + "/mnt/nas/siyuan:/home/siyuan" + ]; + cmd = [ + "--workspace=/workspace" + ]; + environment = { + PUID = "0"; + PGID = "0"; + }; + environmentFiles = [ + "${config.sops.secrets.siyuan-env.path}" + ]; + ports = [ "8095:6806" ]; + }; + }; + }; + services.caddy.virtualHosts = { + "note.imxyy.top" = { + extraConfig = '' + reverse_proxy :8093 + ''; + }; + "sy.imxyy.top" = { + extraConfig = '' + reverse_proxy :8095 + ''; + }; + }; +} diff --git a/config/hosts/imxyy-nix-server/samba.nix b/config/hosts/imxyy-nix-server/samba.nix new file mode 100644 index 0000000..2574deb --- /dev/null +++ b/config/hosts/imxyy-nix-server/samba.nix @@ -0,0 +1,36 @@ +{ ... }: +{ + services.samba = { + enable = true; + nsswins = true; + settings = { + global = { + security = "user"; + "netbios name" = "NAS"; + }; + share = { + path = "/mnt/nas/share"; + browseable = "yes"; + "read only" = "no"; + "guest ok" = "no"; + "create mask" = "0664"; + "directory mask" = "0775"; + "force user" = "nextcloud"; + "force group" = "nextcloud"; + }; + }; + }; + services.samba-wsdd.enable = true; + # ensure dir exists + systemd.tmpfiles.rules = [ + "d /mnt/nas/share 0775 nextcloud nextcloud - -" + ]; + users = { + users.nas = { + isNormalUser = true; + home = "/var/empty"; + description = "nas user"; + group = "nextcloud"; + }; + }; +} diff --git a/config/hosts/imxyy-nix-server/vault.nix b/config/hosts/imxyy-nix-server/vault.nix new file mode 100644 index 0000000..5d34027 --- /dev/null +++ b/config/hosts/imxyy-nix-server/vault.nix @@ -0,0 +1,31 @@ +{ config, sopsRoot, ... }: +{ + sops.secrets.vaultwarden-env = { + sopsFile = sopsRoot + /vaultwarden.env; + format = "dotenv"; + }; + services.postgresql.ensureUsers = [ + { + name = "vaultwarden"; + ensureDBOwnership = true; + } + ]; + services.postgresql.ensureDatabases = [ "vaultwarden" ]; + services.vaultwarden = { + enable = true; + dbBackend = "postgresql"; + config = { + ROCKET_ADDRESS = "127.0.0.1"; + ROCKET_PORT = 8083; + DOMAIN = "https://vault.imxyy.top"; + }; + environmentFile = "${config.sops.secrets.vaultwarden-env.path}"; + }; + services.caddy.virtualHosts."vault.imxyy.top" = { + extraConfig = '' + reverse_proxy :8083 { + header_up X-Real-IP {remote_host} + } + ''; + }; +} diff --git a/config/hosts/imxyy-nix-server/virt.nix b/config/hosts/imxyy-nix-server/virt.nix new file mode 100644 index 0000000..3a6bed5 --- /dev/null +++ b/config/hosts/imxyy-nix-server/virt.nix @@ -0,0 +1,28 @@ +{ lib, ... }: +let + # T400 + gpuIDs = [ + "8086:56a0" # A770 + + "10de:1f82" # 1650 + "10de:10fa" # 1650 + + "10de:1fb2" # T400 + ]; +in +{ + boot = { + initrd.kernelModules = [ + "vfio_pci" + "vfio" + "vfio_iommu_type1" + ]; + kernelParams = [ + "pcie_acs_override=downstream,multifunction" + "amd_iommu=on" + "vfio-pci.ids=${lib.concatStringsSep "," gpuIDs}" + ]; + }; + virtualisation.spiceUSBRedirection.enable = true; + my.virt.enable = true; +} diff --git a/config/hosts/imxyy-nix-server/yesplaymusic.nix b/config/hosts/imxyy-nix-server/yesplaymusic.nix new file mode 100644 index 0000000..e150cb0 --- /dev/null +++ b/config/hosts/imxyy-nix-server/yesplaymusic.nix @@ -0,0 +1,24 @@ +{ ... }: +{ + virtualisation.oci-containers.containers."YesPlayMusic" = { + image = "git.imxyy.top/imxyy1soope1/yesplaymusic:latest"; + environment = { + "NODE_TLS_REJECT_UNAUTHORIZED" = "0"; + }; + volumes = [ + "/etc/localtime:/etc/localtime:ro" + ]; + ports = [ + "8088:80/tcp" + ]; + log-driver = "journald"; + }; + + services.caddy.virtualHosts."music.imxyy.top" = { + extraConfig = '' + reverse_proxy :8088 { + header_up X-Real-IP {remote_host} + } + ''; + }; +} diff --git a/config/hosts/imxyy-nix-wsl/default.nix b/config/hosts/imxyy-nix-wsl/default.nix new file mode 100644 index 0000000..5105fd6 --- /dev/null +++ b/config/hosts/imxyy-nix-wsl/default.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + imports = [ + ./nixos.nix + ./home.nix + ]; +} diff --git a/config/hosts/imxyy-nix-wsl/home.nix b/config/hosts/imxyy-nix-wsl/home.nix new file mode 100644 index 0000000..1fcb4d0 --- /dev/null +++ b/config/hosts/imxyy-nix-wsl/home.nix @@ -0,0 +1,13 @@ +{ ... }: +{ + my.home.programs.zsh.shellAliases = { + localproxy_on = "export http_proxy=http://192.168.128.1:7890 https_proxy=http://192.168.128.1:7890 all_proxy=socks://192.168.128.1:7890"; + }; + my = { + coding.all.enable = true; + cmd.misc.enable = true; + xdg.enable = true; + cmd.media.all.enable = true; + desktop.media.all.enable = true; + }; +} diff --git a/config/hosts/imxyy-nix-wsl/nixos.nix b/config/hosts/imxyy-nix-wsl/nixos.nix new file mode 100644 index 0000000..b5db845 --- /dev/null +++ b/config/hosts/imxyy-nix-wsl/nixos.nix @@ -0,0 +1,17 @@ +{ username, nixos-wsl, ... }: +{ + imports = [ + nixos-wsl.nixosModules.wsl + ]; + wsl.enable = true; + wsl.defaultUser = "${username}"; + + services.openssh = { + enable = true; + settings = { + # Forbid root login through SSH. + PermitRootLogin = "no"; + PasswordAuthentication = true; + }; + }; +} diff --git a/config/hosts/imxyy-nix/default.nix b/config/hosts/imxyy-nix/default.nix new file mode 100644 index 0000000..7c1657b --- /dev/null +++ b/config/hosts/imxyy-nix/default.nix @@ -0,0 +1,10 @@ +{ ... }: +{ + imports = [ + ./nixos.nix + ./hardware.nix + ./home.nix + ./virt.nix + ./net.nix + ]; +} diff --git a/config/hosts/imxyy-nix/hardware.nix b/config/hosts/imxyy-nix/hardware.nix new file mode 100644 index 0000000..6848146 --- /dev/null +++ b/config/hosts/imxyy-nix/hardware.nix @@ -0,0 +1,165 @@ +{ + config, + lib, + pkgs, + username, + ... +}: + +{ + boot = { + initrd = { + kernelModules = [ "amdgpu" ]; + availableKernelModules = [ + "xhci_pci" + "ahci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + ]; + verbose = false; + }; + + kernelPackages = lib.mkForce pkgs.linuxKernel.packages.linux_zen; + kernelModules = [ "kvm-amd" ]; + + tmp.useTmpfs = true; + kernel.sysctl = { + "fs.file-max" = 9223372036854775807; + }; + + resumeDevice = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c"; + kernelParams = [ + "resume_offset=6444127" + + # "quiet" + # "splash" + # "log_level=3" + ]; + consoleLogLevel = 3; + + /* + plymouth = { + enable = true; + theme = "bgrt"; + themePackages = [ pkgs.nixos-bgrt-plymouth ]; + }; + */ + }; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c"; + fsType = "btrfs"; + options = [ + "compress=zstd" + "subvol=root" + ]; + }; + + fileSystems."/nix" = { + device = "/dev/disk/by-uuid/843c36ae-f6d0-46a1-b5c7-8ab569e1e63f"; + fsType = "btrfs"; + options = [ "compress=zstd" ]; + }; + + fileSystems."/persistent" = { + device = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c"; + fsType = "btrfs"; + options = [ + "compress=zstd" + "subvol=persistent" + ]; + neededForBoot = true; + }; + + fileSystems."/swap" = { + device = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c"; + fsType = "btrfs"; + options = [ + "compress=zstd" + "subvol=swap" + ]; + neededForBoot = true; + }; + + boot.initrd.postDeviceCommands = lib.mkAfter '' + mkdir /btrfs_tmp + mount /dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c /btrfs_tmp + mkdir -p /btrfs_tmp/old_roots + if [[ -e /btrfs_tmp/root ]]; then + timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S") + mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp" + fi + + delete_subvolume_recursively() { + IFS=$'\n' + for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do + delete_subvolume_recursively "/btrfs_tmp/$i" + done + btrfs subvolume delete "$1" + } + + for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +14); do + delete_subvolume_recursively "$i" + done + + btrfs subvolume create /btrfs_tmp/root + umount /btrfs_tmp + ''; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/B7DC-E9AC"; + fsType = "vfat"; + }; + + fileSystems."/home/${username}/Documents" = { + device = "/dev/disk/by-uuid/a4e37dcd-764a-418c-aa1c-484f1fbd4bbe"; + fsType = "ext4"; + }; + + fileSystems."/home/${username}/Downloads" = { + device = "/dev/disk/by-uuid/18717cb4-49ac-40fa-95d4-29523a458dd0"; + fsType = "ext4"; + }; + + fileSystems."/home/${username}/Videos" = { + device = "/dev/disk/by-uuid/b67bbeab-58bc-4814-b5e3-08404e78b25e"; + fsType = "ext4"; + }; + + fileSystems."/home/${username}/Pictures" = { + device = "/dev/disk/by-uuid/a31bfe7e-cc17-4bd2-af74-ae5de9be35d3"; + fsType = "ext4"; + }; + + fileSystems."/home/${username}/Music" = { + device = "//192.168.3.2/share/imxyy_soope_/Music"; + fsType = "cifs"; + options = [ + "username=nas" + "password=nasshare" + "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s" + "nodev" + "nofail" + "uid=1000" + "gid=100" + "vers=3" + "rw" + ]; + }; + + swapDevices = [ + { + device = "/swap/swapfile"; + size = 32 * 1024; + } + ]; + + networking.useDHCP = lib.mkDefault false; + + hardware.enableRedistributableFirmware = lib.mkDefault true; + hardware.cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware; + + nixpkgs.hostPlatform = lib.mkForce "x86_64-linux"; +} diff --git a/config/hosts/imxyy-nix/home.nix b/config/hosts/imxyy-nix/home.nix new file mode 100644 index 0000000..d281171 --- /dev/null +++ b/config/hosts/imxyy-nix/home.nix @@ -0,0 +1,215 @@ +{ + config, + lib, + pkgs, + username, + ... +}: +{ + my.home = { + home.packages = with pkgs; [ + localsend + + rclone + + wpsoffice-cn + wps-office-fonts + evince + # siyuan-unlock + + anki + + ayugram-desktop + telegram-desktop + signal-desktop + cinny-desktop + discord + qq + + gnome-clocks + + wineWowPackages.waylandFull + + pavucontrol + pamixer + ]; + programs.zsh = { + shellAliases = { + cageterm = "cage -m DP-2 -s -- alacritty -o font.size=20"; + cagefoot = "cage -m DP-2 -s -- foot --font=monospace:size=20"; + cagekitty = "cage -m DP-2 -s -- kitty -o font_size=20"; + }; + sessionVariables = { + no_proxy = "192.168.3.0/24"; + PATH = "/home/${username}/bin:$PATH"; + }; + profileExtra = '' + if [ `tty` = "/dev/tty1" -a $XDG_RUNTIME_DIR ]; then + echo 'Starting Niri...' + exec uwsm start niri-uwsm.desktop + elif [ `tty` = "/dev/tty6" ]; then + clear + fi + ''; + }; + + programs.niri.settings.outputs = { + DP-2 = { + enable = true; + mode = { + width = 2560; + height = 1440; + refresh = 75.033; + }; + scale = 1.25; + position = { + x = 0; + y = 0; + }; + }; + DP-3 = { + enable = true; + mode = { + width = 2560; + height = 1440; + refresh = 75.033; + }; + scale = 1.25; + }; + }; + + }; + my = { + autologin = { + enable = true; + user = "${username}"; + ttys = [ + 1 + 6 + ]; + }; + + gpg.enable = true; + cmd.all.enable = true; + coding.all.enable = true; + desktop.all.enable = true; + + desktop.wm.dwm.enable = lib.mkForce false; + + desktop.browser.librewolf.enable = lib.mkForce false; + + i18n.fcitx5.enable = true; + + xdg = { + enable = true; + defaultApplications = + let + browser = [ "chromium-browser.desktop" ]; + editor = [ "codium.desktop" ]; + imageviewer = [ "org.gnome.Shotwell-Viewer.desktop" ]; + in + { + "inode/directory" = [ "nemo.desktop" ]; + + "application/pdf" = [ "evince.desktop" ]; + + "text/*" = editor; + "application/json" = editor; + "text/html" = editor; + "text/xml" = editor; + "application/xml" = editor; + "application/xhtml+xml" = editor; + "application/xhtml_xml" = editor; + "application/rdf+xml" = editor; + "application/rss+xml" = editor; + "application/x-extension-htm" = editor; + "application/x-extension-html" = editor; + "application/x-extension-shtml" = editor; + "application/x-extension-xht" = editor; + "application/x-extension-xhtml" = editor; + + "x-scheme-handler/about" = browser; + "x-scheme-handler/ftp" = browser; + "x-scheme-handler/http" = browser; + "x-scheme-handler/https" = browser; + "x-scheme-handler/unknown" = browser; + + "audio/*" = imageviewer; + "video/*" = imageviewer; + "image/*" = imageviewer; + "image/gif" = imageviewer; + "image/jpeg" = imageviewer; + "image/png" = imageviewer; + "image/webp" = imageviewer; + }; + extraBookmarks = + let + homedir = config.my.home.home.homeDirectory; + in + [ + "file://${homedir}/Documents/%E7%8F%AD%E7%BA%A7%E4%BA%8B%E5%8A%A1 班级事务" + "file://${homedir}/NAS NAS" + "file://${homedir}/NAS/imxyy_soope_ NAS imxyy_soope_" + "file://${homedir}/NAS/imxyy_soope_/OS NAS OS" + ]; + }; + persist = { + enable = true; + homeDirs = [ + ".android" + "Android" + + ".ssh" + + "bin" + "workspace" + "WineApps" + "Virt" + + ".cache" + ".local/state" + ".local/share/Anki2" + ".local/share/dooit" + ".local/share/nvim" + ".local/share/shotwell" + ".local/share/Steam" + ".local/share/SteamOS" + ".local/share/Trash" + ".local/share/cheat.sh" + ".local/share/Kingsoft" + ".local/share/oss.krtirtho.spotube" + + ".local/share/AyuGramDesktop" + ".local/share/TelegramDesktop" + ".local/share/cinny" + ".config/Signal" + ".config/discord" + ".config/QQ" + + ".config/Kingsoft" + ".config/dconf" + ".config/gh" + ".config/pulse" + ".config/chromium" + ".config/go-musicfox/db" + ".config/tmux/plugins" + ".config/pip" + ".config/obs-studio" + ".config/libreoffice" + ".config/Moonlight Game Streaming Project" + ".config/sunshine" + ]; + nixosDirs = [ + "/etc/ssh" + ]; + homeFiles = [ + ".config/mpd/mpd.db" # requires bindfs + ".config/go-musicfox/cookie" + ".hmcl.json" + ]; + nixosFiles = [ + "/etc/davfs2/secrets" + ]; + }; + }; +} diff --git a/config/hosts/imxyy-nix/net.nix b/config/hosts/imxyy-nix/net.nix new file mode 100644 index 0000000..25f3eee --- /dev/null +++ b/config/hosts/imxyy-nix/net.nix @@ -0,0 +1,136 @@ +{ + config, + lib, + pkgs, + sopsRoot, + ... +}: +{ + boot.kernelParams = [ + "biosdevname=0" + "net.ifnames=0" + ]; + networking = { + useDHCP = lib.mkForce false; + dhcpcd = { + wait = "background"; + IPv6rs = true; + extraConfig = '' + interface eth0 + noipv4 + ''; + }; + interfaces = { + eth0 = { + useDHCP = lib.mkForce true; + wakeOnLan.enable = true; + macAddress = "3C:7C:3F:7C:D3:9D"; + ipv4 = { + addresses = [ + { + address = "192.168.3.3"; + prefixLength = 24; + } + ]; + }; + }; + }; + defaultGateway = { + address = "192.168.3.1"; + interface = "eth0"; + }; + nameservers = [ + "192.168.3.2" + ]; + + firewall.enable = false; + nftables = { + enable = true; + flushRuleset = true; + ruleset = '' + table inet firewall { + set LANv4 { + type ipv4_addr + flags interval + + elements = { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 } + } + set LANv6 { + type ipv6_addr + flags interval + + elements = { fd00::/8, fe80::/10 } + } + + chain output { + type filter hook output priority 100; policy accept; + } + + chain input { + type filter hook input priority 0; policy drop; + iif lo accept + ct state invalid drop + ct state established,related accept + + ip saddr @LANv4 accept + ip6 saddr @LANv6 accept + } + + chain forward { + type filter hook forward priority 0; policy drop; + } + } + ''; + }; + }; + + sops.secrets.dae-imxyy-nix = { + sopsFile = sopsRoot + /dae-imxyy-nix.dae; + format = "binary"; + }; + services.dae = { + enable = true; + configFile = config.sops.secrets.dae-imxyy-nix.path; + }; + systemd.services.dae.after = [ "sops-nix.service" ]; + sops.secrets.mihomo = { + sopsFile = sopsRoot + /mihomo.yaml; + format = "yaml"; + key = ""; + }; + systemd.services.mihomo.after = [ "sops-nix.service" ]; + services.mihomo = { + enable = true; + configFile = config.sops.secrets.mihomo.path; + webui = pkgs.metacubexd; + }; + + services.tailscale.enable = true; + + sops.secrets.et-imxyy-nix = { + sopsFile = sopsRoot + /et-imxyy-nix.toml; + format = "binary"; + }; + environment.systemPackages = [ pkgs.easytier ]; + systemd.services."easytier" = { + enable = true; + script = "easytier-core -c ${config.sops.secrets.et-imxyy-nix.path}"; + serviceConfig = { + Restart = lib.mkOverride 500 "always"; + RestartMaxDelaySec = lib.mkOverride 500 "1m"; + RestartSec = lib.mkOverride 500 "100ms"; + RestartSteps = lib.mkOverride 500 9; + User = "root"; + }; + wantedBy = [ "multi-user.target" ]; + after = [ + "network.target" + "sops-nix.service" + ]; + path = with pkgs; [ + easytier + iproute2 + bash + ]; + }; +} diff --git a/config/hosts/imxyy-nix/nixos.nix b/config/hosts/imxyy-nix/nixos.nix new file mode 100644 index 0000000..96d70a6 --- /dev/null +++ b/config/hosts/imxyy-nix/nixos.nix @@ -0,0 +1,319 @@ +{ + lib, + pkgs, + username, + ... +}: +let + btreset = pkgs.writeScriptBin "btreset" '' + #!${lib.getExe pkgs.python3} + + import subprocess + import os + import sys + + SYM = "BT" + + def action(line: str) -> bool: + if line.find(SYM) == -1: + return False + temp = line.split(" ") + bus = temp[1] + device = temp[3][:-1] + subprocess.run(["${lib.getExe usbreset}", f"/dev/bus/usb/{bus}/{device}"]) + return True + + if __name__ == "__main__": + if os.path.exists("/tmp/.btreseted") and len(sys.argv) == 1 and "-f" not in sys.argv[1:]: + exit(0) + res_byte = subprocess.check_output("/run/current-system/sw/bin/lsusb") + res = res_byte.decode() + lst = res.split("\n") + + if any(tuple(map(action, lst))): + with open("/tmp/.btreseted", "w"): + ... + ''; + usbreset = pkgs.writeCBin "usbreset" '' + #include + #include + #include + #include + + #include + + int main(int argc, char **argv) + { + const char *filename; + int fd; + int rc; + + if (argc != 2) { + fprintf(stderr, "Usage: usbreset device-filename\n"); + return 1; + } + filename = argv[1]; + + fd = open(filename, O_WRONLY); + if (fd < 0) { + perror("Error opening output file"); + return 1; + } + + printf("Resetting USB device %s\n", filename); + rc = ioctl(fd, USBDEVFS_RESET, 0); + if (rc < 0) { + perror("Error in ioctl"); + return 1; + } + printf("Reset successful\n"); + + close(fd); + return 0; + } + ''; +in +{ + security.pam.loginLimits = [ + { + domain = "*"; + type = "soft"; + item = "nofile"; + value = "524288"; + } + ]; + + systemd.services.btreset = { + script = lib.getExe btreset; + wantedBy = [ "multi-user.target" ]; + serviceConfig.Type = "oneshot"; + }; + boot.kernelParams = [ + "usbcore.autosuspend=-1" # Avoid usb autosuspend (for usb bluetooth adapter) + "fsck.mode=skip" + ]; + + boot.loader = { + efi.canTouchEfiVariables = true; + systemd-boot.enable = true; + grub.enable = false; + timeout = 0; + }; + + hardware.graphics.enable = true; + hardware.graphics.enable32Bit = true; + + systemd.services.nix-daemon = { + environment.TMPDIR = "/var/cache/nix"; + serviceConfig.CacheDirectory = "nix"; + }; + environment.variables.NIX_REMOTE = "daemon"; + + # services.pipewire.enable = false; + security.rtkit.enable = true; + services.pipewire = { + enable = true; + # alsa.enable = true; + # alsa.support32Bit = true; + # pulse.enable = true; + alsa.enable = false; + alsa.support32Bit = false; + pulse.enable = false; + audio.enable = false; + configPackages = [ + /* + (pkgs.writeTextDir "share/pipewire/media-session.d/bluez-monitor.conf" '' + rules = [ + { + actions = { + update-props = { + bluez5.autoswitch-profile = true; + } + } + } + ] + '') + */ + ]; + }; + services.pipewire.wireplumber.extraConfig = { + /* + "10-bluez" = { + "monitor.bluez.properties" = { + "bluez5.enable-sbc-xq" = true; + "bluez5.enable-msbc" = true; + "bluez5.enable-hw-volume" = true; + "bluez5.roles" = [ + "hsp_hs" + "hsp_ag" + "hfp_hf" + "hfp_ag" + ]; + }; + }; + */ + /* + "11-bluetooth-policy" = { + "wireplumber.settings" = { + "bluetooth.autoswitch-to-headset-profile" = false; + }; + }; + */ + }; + services.pulseaudio = { + enable = true; + support32Bit = true; + package = pkgs.pulseaudioFull; + extraConfig = '' + load-module module-switch-on-connect + unload-module module-suspend-on-idle + ''; + }; + hardware.bluetooth = { + enable = true; + powerOnBoot = true; + settings = { + General.Enable = "Source,Sink,Media,Socket"; + }; + }; + users.extraUsers.${username}.extraGroups = [ "audio" ]; + + fonts = { + enableDefaultPackages = false; + fontDir.enable = true; + + packages = with pkgs; [ + noto-fonts + noto-fonts-cjk-sans + noto-fonts-emoji + + jetbrains-mono + + nerd-fonts.symbols-only + ]; + + fontconfig.defaultFonts = { + serif = [ + "Noto Serif CJK SC" + "Noto Serif" + "Symbols Nerd Font" + "Noto Color Emoji" + ]; + sansSerif = [ + "Noto Sans CJK SC" + "Noto Sans" + "Symbols Nerd Font" + "Noto Color Emoji" + ]; + monospace = [ + "JetBrains Mono" + "Noto Sans Mono CJK SC" + "Symbols Nerd Font Mono" + "Noto Color Emoji" + ]; + emoji = [ "Noto Color Emoji" ]; + }; + }; + + services.printing.enable = true; + + services.keyd = { + enable = true; + keyboards.default.settings = { + main = { + capslock = "overload(control, esc)"; + home = "end"; + }; + shift = { + home = "home"; + }; + control = { + delete = "print"; + }; + }; + }; + + services.gvfs.enable = true; + + virtualisation.waydroid.enable = true; + + programs.wireshark.enable = true; + programs.wireshark.package = pkgs.wireshark; + users.users.${username}.extraGroups = [ "wireshark" ]; + + services.sunshine = { + enable = true; + autoStart = true; + capSysAdmin = true; + applications.apps = [ + { + name = "Desktop"; + image-path = "desktop.png"; + } + ]; + }; + services.openssh = { + enable = true; + settings = { + # Forbid root login through SSH. + PermitRootLogin = null; + PasswordAuthentication = true; + }; + }; + + environment.systemPackages = [ + pkgs.rclone + btreset + ]; + + fileSystems = + let + config = pkgs.writeText "rclone.conf" '' + [Nextcloud] + type = webdav + url = https://192.168.3.2/remote.php/dav/files/imxyy_soope_ + vendor = nextcloud + user = imxyy_soope_ + pass = C2UUiMyPoynWWKS9kf_Fr8rcoXxgUswPYi4s + + [NAS] + type = smb + host = 192.168.3.2 + user = nas + pass = O74S6-7jDFykwCvZ8vuIxohh00Ty7XJF + ''; + in + { + "/home/${username}/Nextcloud" = { + device = "Nextcloud:"; + fsType = "rclone"; + options = [ + "nodev" + "nofail" + "allow_other" + "args2env" + "config=${toString config}" + "uid=1000" + "gid=100" + "rw" + "no-check-certificate" + "vfs-cache-mode=full" + ]; + }; + "/home/${username}/NAS" = { + device = "//192.168.3.2/share"; + fsType = "cifs"; + options = [ + "username=nas" + "password=nasshare" + "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s" + "nodev" + "nofail" + "uid=1000" + "gid=100" + "vers=3" + "rw" + ]; + }; + }; +} diff --git a/config/hosts/imxyy-nix/rule_sets/steamcn.json b/config/hosts/imxyy-nix/rule_sets/steamcn.json new file mode 100644 index 0000000..f67f290 --- /dev/null +++ b/config/hosts/imxyy-nix/rule_sets/steamcn.json @@ -0,0 +1,35 @@ +{ + "version": 1, + "rules": [ + { + "domain": [ + "cm.steampowered.com", + "ol.epicgames.com", + "csgo.wmsj.cn", + "dota2.wmsj.cn", + "wmsjsteam.com", + "dl.steam.clngaa.com", + "dl.steam.ksyna.com", + "gstore.val.manlaxy.com", + "st.dl.bscstorage.net", + "st.dl.eccdnx.com", + "st.dl.pinyuncloud.com", + "steampipe.steamcontent.tnkjmec.com", + "steampowered.com.8686c.com", + "steamstatic.com.8686c.com", + "steambroadcast.akamaized.net", + "steamcdn-a.akamaihd.net", + "steamcommunity-a.akamaihd.net", + "steamstore-a.akamaihd.net", + "steamusercontent-a.akamaihd.net", + "steamuserimages-a.akamaihd.net" + ], + "domain_suffix": [ + ".steamcontent.com", + ".steamserver.net", + ".steamchina.com" + ], + "invert": false + } + ] +} diff --git a/config/hosts/imxyy-nix/virt.nix b/config/hosts/imxyy-nix/virt.nix new file mode 100644 index 0000000..dc39819 --- /dev/null +++ b/config/hosts/imxyy-nix/virt.nix @@ -0,0 +1,12 @@ +{ + ... +}: +{ + hardware.graphics.enable = true; + virtualisation.spiceUSBRedirection.enable = true; + + my.virt = { + enable = true; + moonlight.enable = true; + }; +} diff --git a/docker_proxy.sh b/docker_proxy.sh new file mode 100755 index 0000000..6ac6dc2 --- /dev/null +++ b/docker_proxy.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +sudo mkdir -p /run/systemd/system/docker.service.d +sudo su -c 'cat << EOF >/run/systemd/system/docker.service.d/override.conf +[Service] +Environment="http_proxy=http://127.0.0.1:7890" +Environment="https_proxy=http://127.0.0.1:7890" +Environment="all_proxy=socks5h://127.0.0.1:7891" +EOF' +sudo systemctl daemon-reload +sudo systemctl restart docker diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f88b8d4 --- /dev/null +++ b/flake.lock @@ -0,0 +1,1419 @@ +{ + "nodes": { + "base16": { + "inputs": { + "fromYaml": "fromYaml" + }, + "locked": { + "lastModified": 1732200724, + "narHash": "sha256-+R1BH5wHhfnycySb7Sy5KbYEaTJZWm1h+LW1OtyhiTs=", + "owner": "SenchoPens", + "repo": "base16.nix", + "rev": "153d52373b0fb2d343592871009a286ec8837aec", + "type": "github" + }, + "original": { + "owner": "SenchoPens", + "repo": "base16.nix", + "type": "github" + } + }, + "base16-fish": { + "flake": false, + "locked": { + "lastModified": 1622559957, + "narHash": "sha256-PebymhVYbL8trDVVXxCvZgc0S5VxI7I1Hv4RMSquTpA=", + "owner": "tomyun", + "repo": "base16-fish", + "rev": "2f6dd973a9075dabccd26f1cded09508180bf5fe", + "type": "github" + }, + "original": { + "owner": "tomyun", + "repo": "base16-fish", + "type": "github" + } + }, + "base16-helix": { + "flake": false, + "locked": { + "lastModified": 1736852337, + "narHash": "sha256-esD42YdgLlEh7koBrSqcT7p2fsMctPAcGl/+2sYJa2o=", + "owner": "tinted-theming", + "repo": "base16-helix", + "rev": "03860521c40b0b9c04818f2218d9cc9efc21e7a5", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-helix", + "type": "github" + } + }, + "base16-vim": { + "flake": false, + "locked": { + "lastModified": 1732806396, + "narHash": "sha256-e0bpPySdJf0F68Ndanwm+KWHgQiZ0s7liLhvJSWDNsA=", + "owner": "tinted-theming", + "repo": "base16-vim", + "rev": "577fe8125d74ff456cf942c733a85d769afe58b7", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-vim", + "rev": "577fe8125d74ff456cf942c733a85d769afe58b7", + "type": "github" + } + }, + "cachix": { + "inputs": { + "devenv": [ + "go-musicfox", + "devenv" + ], + "flake-compat": [ + "go-musicfox", + "devenv" + ], + "git-hooks": [ + "go-musicfox", + "devenv" + ], + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1728672398, + "narHash": "sha256-KxuGSoVUFnQLB2ZcYODW7AVPAh9JqRlD5BrfsC/Q4qs=", + "owner": "cachix", + "repo": "cachix", + "rev": "aac51f698309fd0f381149214b7eee213c66ef0a", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "latest", + "repo": "cachix", + "type": "github" + } + }, + "darkly": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744332724, + "narHash": "sha256-0Z91+x5ChjEBqXzbbv6oGzVjuLXvIb8S8493c9vNBJI=", + "owner": "Bali10050", + "repo": "Darkly", + "rev": "542c9ace5b7e69f87807bc205c0deae695247c3d", + "type": "github" + }, + "original": { + "owner": "Bali10050", + "repo": "Darkly", + "type": "github" + } + }, + "devenv": { + "inputs": { + "cachix": "cachix", + "flake-compat": "flake-compat", + "git-hooks": "git-hooks", + "nix": "nix", + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1738772960, + "narHash": "sha256-Wz0srkcU6SZxZKcehVr0S6Vb8l1h6+rrMmqDvjZBJkc=", + "owner": "cachix", + "repo": "devenv", + "rev": "7f756cdf3fbb01cab243dcec4de0ca94e6aaa2af", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "dwm": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703321746, + "narHash": "sha256-W6wBfx8LmyAFY7jEAlol6A9kvDpC9QqxNAJfvAxIm8A=", + "owner": "imxyy1soope1", + "repo": "dwm", + "rev": "d38da01cf2957ddac8cd827c84aab076f1555daf", + "type": "github" + }, + "original": { + "owner": "imxyy1soope1", + "ref": "master", + "repo": "dwm", + "type": "github" + } + }, + "fenix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1744231114, + "narHash": "sha256-60gLl2rJFt6SRwqWimsTAeHgfsIE1iV0zChdJFOvx8w=", + "owner": "nix-community", + "repo": "fenix", + "rev": "0ccfe532b1433da8e5a23cd513ff6847e0f6a8c2", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "firefox-gnome-theme": { + "flake": false, + "locked": { + "lastModified": 1743774811, + "narHash": "sha256-oiHLDHXq7ymsMVYSg92dD1OLnKLQoU/Gf2F1GoONLCE=", + "owner": "rafaelmardojai", + "repo": "firefox-gnome-theme", + "rev": "df53a7a31872faf5ca53dd0730038a62ec63ca9e", + "type": "github" + }, + "original": { + "owner": "rafaelmardojai", + "repo": "firefox-gnome-theme", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1733328505, + "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_3": { + "locked": { + "lastModified": 1733328505, + "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "go-musicfox", + "devenv", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1738453229, + "narHash": "sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm+zmZ7vxbJdo=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "32ea77a06711b758da0ad9bd6a844c5740a87abd", + "type": "github" + }, + "original": { + "id": "flake-parts", + "type": "indirect" + } + }, + "flake-parts_3": { + "inputs": { + "nixpkgs-lib": [ + "nur", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1733312601, + "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_4": { + "inputs": { + "nixpkgs-lib": [ + "stylix", + "nur", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1733312601, + "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-root": { + "locked": { + "lastModified": 1723604017, + "narHash": "sha256-rBtQ8gg+Dn4Sx/s+pvjdq3CB2wQNzx9XGFq/JVGCB6k=", + "owner": "srid", + "repo": "flake-root", + "rev": "b759a56851e10cb13f6b8e5698af7b59c44be26e", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "flake-root", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_4": { + "inputs": { + "systems": "systems_4" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_5": { + "inputs": { + "systems": [ + "stylix", + "systems" + ] + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "fromYaml": { + "flake": false, + "locked": { + "lastModified": 1731966426, + "narHash": "sha256-lq95WydhbUTWig/JpqiB7oViTcHFP8Lv41IGtayokA8=", + "owner": "SenchoPens", + "repo": "fromYaml", + "rev": "106af9e2f715e2d828df706c386a685698f3223b", + "type": "github" + }, + "original": { + "owner": "SenchoPens", + "repo": "fromYaml", + "type": "github" + } + }, + "git-hooks": { + "inputs": { + "flake-compat": [ + "go-musicfox", + "devenv" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "go-musicfox", + "devenv", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1737301351, + "narHash": "sha256-2UNmLCKORvdBRhPGI8Vx0b6l7M8/QBey/nHLIxOl4jE=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "15a87cedeb67e3dbc8d2f7b9831990dffcf4e69f", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "git-hooks_2": { + "inputs": { + "flake-compat": [ + "stylix", + "flake-compat" + ], + "gitignore": "gitignore_2", + "nixpkgs": [ + "stylix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1742649964, + "narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "go-musicfox", + "devenv", + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "gitignore_2": { + "inputs": { + "nixpkgs": [ + "stylix", + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "gnome-shell": { + "flake": false, + "locked": { + "lastModified": 1732369855, + "narHash": "sha256-JhUWbcYPjHO3Xs3x9/Z9RuqXbcp5yhPluGjwsdE2GMg=", + "owner": "GNOME", + "repo": "gnome-shell", + "rev": "dadd58f630eeea41d645ee225a63f719390829dc", + "type": "github" + }, + "original": { + "owner": "GNOME", + "ref": "47.2", + "repo": "gnome-shell", + "type": "github" + } + }, + "go-musicfox": { + "inputs": { + "devenv": "devenv", + "flake-parts": "flake-parts_2", + "flake-root": "flake-root", + "mission-control": "mission-control", + "mk-shell-bin": "mk-shell-bin", + "nix2container": "nix2container", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1740479287, + "narHash": "sha256-uIyQi1XF6uKDEvDiH+V7bJtbnwhHfPGJ3f1/4uivCwQ=", + "owner": "imxyy1soope1", + "repo": "go-musicfox", + "rev": "0012d41c6004fc18b9b9605b6dfaecd0460a0b0d", + "type": "github" + }, + "original": { + "owner": "imxyy1soope1", + "ref": "master", + "repo": "go-musicfox", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744400600, + "narHash": "sha256-qYhUgA98mhq1QK13r9qVY+sG1ri6FBgyp+GApX6wS20=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "b74b22bb6167e8dff083ec6988c98798bf8954d3", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "stylix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1743869639, + "narHash": "sha256-Xhe3whfRW/Ay05z9m1EZ1/AkbV1yo0tm1CbgjtCi4rQ=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "d094c6763c6ddb860580e7d3b4201f8f496a6836", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "impermanence": { + "locked": { + "lastModified": 1737831083, + "narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, + "libgit2": { + "flake": false, + "locked": { + "lastModified": 1697646580, + "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=", + "owner": "libgit2", + "repo": "libgit2", + "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5", + "type": "github" + }, + "original": { + "owner": "libgit2", + "repo": "libgit2", + "type": "github" + } + }, + "mission-control": { + "locked": { + "lastModified": 1733438716, + "narHash": "sha256-1tt43rwHk0N5fwEhbpsHWO4nBVFCQN0w1KM427DNycM=", + "owner": "Platonic-Systems", + "repo": "mission-control", + "rev": "65d04c4ab9db076eff09824d2936a5c215c21f36", + "type": "github" + }, + "original": { + "owner": "Platonic-Systems", + "repo": "mission-control", + "type": "github" + } + }, + "mk-shell-bin": { + "locked": { + "lastModified": 1677004959, + "narHash": "sha256-/uEkr1UkJrh11vD02aqufCxtbF5YnhRTIKlx5kyvf+I=", + "owner": "rrbutani", + "repo": "nix-mk-shell-bin", + "rev": "ff5d8bd4d68a347be5042e2f16caee391cd75887", + "type": "github" + }, + "original": { + "owner": "rrbutani", + "repo": "nix-mk-shell-bin", + "type": "github" + } + }, + "niri": { + "inputs": { + "niri-stable": "niri-stable", + "niri-unstable": "niri-unstable", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": [ + "nixpkgs-stable" + ], + "xwayland-satellite-stable": "xwayland-satellite-stable", + "xwayland-satellite-unstable": "xwayland-satellite-unstable" + }, + "locked": { + "lastModified": 1744381460, + "narHash": "sha256-ay8Vijc8IuQiA+bMmKaKFy/2iTtvB9K7xqrirhnwivU=", + "owner": "sodiboo", + "repo": "niri-flake", + "rev": "4e592d48fb54ed742fb1ab14972a11432b2cbc31", + "type": "github" + }, + "original": { + "owner": "sodiboo", + "repo": "niri-flake", + "type": "github" + } + }, + "niri-stable": { + "flake": false, + "locked": { + "lastModified": 1740117926, + "narHash": "sha256-mTTHA0RAaQcdYe+9A3Jx77cmmyLFHmRoZdd8RpWa+m8=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "b94a5db8790339cf9134873d8b490be69e02ac71", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "ref": "v25.02", + "repo": "niri", + "type": "github" + } + }, + "niri-unstable": { + "flake": false, + "locked": { + "lastModified": 1744271375, + "narHash": "sha256-W4h6ZX2WHJ6k0ApUTpuxkDPZ5JAI3MLWFP4lpfu3iv8=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "df9466243504a00240f7048a1f9644cb002776a8", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "repo": "niri", + "type": "github" + } + }, + "nix": { + "inputs": { + "flake-compat": [ + "go-musicfox", + "devenv" + ], + "flake-parts": "flake-parts", + "libgit2": "libgit2", + "nixpkgs": "nixpkgs_2", + "nixpkgs-23-11": [ + "go-musicfox", + "devenv" + ], + "nixpkgs-regression": [ + "go-musicfox", + "devenv" + ], + "pre-commit-hooks": [ + "go-musicfox", + "devenv" + ] + }, + "locked": { + "lastModified": 1734114420, + "narHash": "sha256-n52PUzub5jZWc8nI/sR7UICOheU8rNA+YZ73YaHeCBg=", + "owner": "domenkozar", + "repo": "nix", + "rev": "bde6a1a0d1f2af86caa4d20d23eca019f3d57eee", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.24", + "repo": "nix", + "type": "github" + } + }, + "nix-vscode-extensions": { + "inputs": { + "flake-utils": "flake-utils_3", + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "lastModified": 1744422829, + "narHash": "sha256-rvWFZG02MQuzKLueDQryCLEljRV0Ot4uo44hoKC3CHg=", + "owner": "nix-community", + "repo": "nix-vscode-extensions", + "rev": "eda6606c9e4790ebe074d18ef074906a750f0d53", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-vscode-extensions", + "type": "github" + } + }, + "nix2container": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": [ + "go-musicfox", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1730479402, + "narHash": "sha256-79NLeNjpCa4mSasmFsE3QA6obURezF0TUO5Pm+1daog=", + "owner": "nlewo", + "repo": "nix2container", + "rev": "5fb215a1564baa74ce04ad7f903d94ad6617e17a", + "type": "github" + }, + "original": { + "owner": "nlewo", + "repo": "nix2container", + "type": "github" + } + }, + "nixos-wsl": { + "inputs": { + "flake-compat": "flake-compat_2", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744290088, + "narHash": "sha256-/X9XVEl0EiyisNbF5srrxXRSVoRqdwExuqyspYqqEjQ=", + "owner": "nix-community", + "repo": "NixOS-WSL", + "rev": "60b4904a1390ac4c89e93d95f6ed928975e525ed", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "NixOS-WSL", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1730531603, + "narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1738452942, + "narHash": "sha256-vJzFZGaCpnmo7I6i416HaBLpC+hvcURh/BQwROcGIp8=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" + } + }, + "nixpkgs-master": { + "locked": { + "lastModified": 1744454940, + "narHash": "sha256-0m9xgwSZPxTWddz5Iij4lMja3o0sFiXoDyuWFQFYmeI=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d73c877f053c3af021775cc48f4e72248bae949b", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "master", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1744452923, + "narHash": "sha256-42QOX/fppMcKVPL7V1plRwH4HZWXzSyQ9AkbWH54BPQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d067330e18d535ed53b470de2a641d37ed3376f9", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1744414260, + "narHash": "sha256-zzmnpcGCX9W73fL6se8atCzyAtlDsSXxPW/wvopLGgg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "e58dd8c9bc2a6b5bd4c8a07ac4080e9909be7ab6", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1717432640, + "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1716977621, + "narHash": "sha256-Q1UQzYcMJH4RscmpTkjlgqQDX5yi1tZL0O345Ri6vXQ=", + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "4267e705586473d3e5c8d50299e71503f16a6fb6", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1740547748, + "narHash": "sha256-Ly2fBL1LscV+KyCqPRufUBuiw+zmWrlJzpWOWbahplg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3a05eebede89661660945da1f151959900903b6a", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3a05eebede89661660945da1f151959900903b6a", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1744232761, + "narHash": "sha256-gbl9hE39nQRpZaLjhWKmEu5ejtQsgI5TWYrIVVJn30U=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "f675531bc7e6657c10a18b565cfebd8aa9e24c14", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nur": { + "inputs": { + "flake-parts": "flake-parts_3", + "nixpkgs": "nixpkgs_5", + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1744454766, + "narHash": "sha256-24qW6Oqdxr9MGwGXqFwQCuV2kcHeWQmMSKax0bLKNXg=", + "owner": "nix-community", + "repo": "NUR", + "rev": "d4aafd7c84f836cc89b27424314785e2acacfe51", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "NUR", + "type": "github" + } + }, + "nur_2": { + "inputs": { + "flake-parts": "flake-parts_4", + "nixpkgs": [ + "stylix", + "nixpkgs" + ], + "treefmt-nix": "treefmt-nix_2" + }, + "locked": { + "lastModified": 1743884191, + "narHash": "sha256-foVcginhVvjg8ZnTzY5wwMeZ4wjJ8yX66PW5kgyivPE=", + "owner": "nix-community", + "repo": "NUR", + "rev": "fde90f5f52e13eed110a0e53a2818a2b09e4d37c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "NUR", + "type": "github" + } + }, + "omz": { + "inputs": { + "flake-utils": "flake-utils_4", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1704103295, + "narHash": "sha256-BAwAKajpAUC78z0IMJt6LXGV8dLdUMYXe6CxbGA0JP0=", + "owner": "imxyy1soope1", + "repo": "omz", + "rev": "e581a6d0d47291a3ddd7da5046bea59b29631a3f", + "type": "github" + }, + "original": { + "owner": "imxyy1soope1", + "ref": "master", + "repo": "omz", + "type": "github" + } + }, + "quickshell": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1743928855, + "narHash": "sha256-6skFnvfLbslUOieffviT+XNH/M1HOQDQJhJLsG0UM2o=", + "ref": "refs/heads/master", + "rev": "ed528268e0c0a2f6be2b5aca7089ebc3e214d446", + "revCount": 505, + "type": "git", + "url": "https://git.outfoxxed.me/outfoxxed/quickshell" + }, + "original": { + "type": "git", + "url": "https://git.outfoxxed.me/outfoxxed/quickshell" + } + }, + "root": { + "inputs": { + "darkly": "darkly", + "dwm": "dwm", + "fenix": "fenix", + "go-musicfox": "go-musicfox", + "home-manager": "home-manager", + "impermanence": "impermanence", + "niri": "niri", + "nix-vscode-extensions": "nix-vscode-extensions", + "nixos-wsl": "nixos-wsl", + "nixpkgs": [ + "nixpkgs-unstable" + ], + "nixpkgs-master": "nixpkgs-master", + "nixpkgs-stable": "nixpkgs-stable", + "nixpkgs-unstable": "nixpkgs-unstable", + "nur": "nur", + "omz": "omz", + "quickshell": "quickshell", + "sops-nix": "sops-nix", + "stylix": "stylix" + } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1742296961, + "narHash": "sha256-gCpvEQOrugHWLimD1wTFOJHagnSEP6VYBDspq96Idu0=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "15d87419f1a123d8f888d608129c3ce3ff8f13d4", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744103455, + "narHash": "sha256-SR6+qjkPjGQG+8eM4dCcVtss8r9bre/LAxFMPJpaZeU=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "69d5a5a4635c27dae5a742f36108beccc506c1ba", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, + "stylix": { + "inputs": { + "base16": "base16", + "base16-fish": "base16-fish", + "base16-helix": "base16-helix", + "base16-vim": "base16-vim", + "firefox-gnome-theme": "firefox-gnome-theme", + "flake-compat": "flake-compat_3", + "flake-utils": "flake-utils_5", + "git-hooks": "git-hooks_2", + "gnome-shell": "gnome-shell", + "home-manager": "home-manager_2", + "nixpkgs": [ + "nixpkgs" + ], + "nur": "nur_2", + "systems": "systems_5", + "tinted-foot": "tinted-foot", + "tinted-kitty": "tinted-kitty", + "tinted-schemes": "tinted-schemes", + "tinted-tmux": "tinted-tmux", + "tinted-zed": "tinted-zed" + }, + "locked": { + "lastModified": 1744270948, + "narHash": "sha256-+1psY8uBaDdkqV/P3G40SzulPvUcb9VHisqQnDozC0U=", + "owner": "danth", + "repo": "stylix", + "rev": "ce45f19e8acb43e5f02888d873d451e2f994546b", + "type": "github" + }, + "original": { + "owner": "danth", + "repo": "stylix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_5": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "tinted-foot": { + "flake": false, + "locked": { + "lastModified": 1726913040, + "narHash": "sha256-+eDZPkw7efMNUf3/Pv0EmsidqdwNJ1TaOum6k7lngDQ=", + "owner": "tinted-theming", + "repo": "tinted-foot", + "rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "tinted-foot", + "rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4", + "type": "github" + } + }, + "tinted-kitty": { + "flake": false, + "locked": { + "lastModified": 1716423189, + "narHash": "sha256-2xF3sH7UIwegn+2gKzMpFi3pk5DlIlM18+vj17Uf82U=", + "owner": "tinted-theming", + "repo": "tinted-kitty", + "rev": "eb39e141db14baef052893285df9f266df041ff8", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "tinted-kitty", + "rev": "eb39e141db14baef052893285df9f266df041ff8", + "type": "github" + } + }, + "tinted-schemes": { + "flake": false, + "locked": { + "lastModified": 1742851696, + "narHash": "sha256-sR4K+OVFKeUOvNIqcCr5Br7NLxOBEwoAgsIyjsZmb8s=", + "owner": "tinted-theming", + "repo": "schemes", + "rev": "c37771c4ae8ff1667e27ddcf24991ebeb94a4e77", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "schemes", + "type": "github" + } + }, + "tinted-tmux": { + "flake": false, + "locked": { + "lastModified": 1743296873, + "narHash": "sha256-8IQulrb1OBSxMwdKijO9fB70ON//V32dpK9Uioy7FzY=", + "owner": "tinted-theming", + "repo": "tinted-tmux", + "rev": "af5152c8d7546dfb4ff6df94080bf5ff54f64e3a", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "tinted-tmux", + "type": "github" + } + }, + "tinted-zed": { + "flake": false, + "locked": { + "lastModified": 1725758778, + "narHash": "sha256-8P1b6mJWyYcu36WRlSVbuj575QWIFZALZMTg5ID/sM4=", + "owner": "tinted-theming", + "repo": "base16-zed", + "rev": "122c9e5c0e6f27211361a04fae92df97940eccf9", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-zed", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nur", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1733222881, + "narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "49717b5af6f80172275d47a418c9719a31a78b53", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "treefmt-nix_2": { + "inputs": { + "nixpkgs": [ + "stylix", + "nur", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1733222881, + "narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "49717b5af6f80172275d47a418c9719a31a78b53", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "xwayland-satellite-stable": { + "flake": false, + "locked": { + "lastModified": 1739246919, + "narHash": "sha256-/hBM43/Gd0/tW+egrhlWgOIISeJxEs2uAOIYVpfDKeU=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "44590a416d4a3e8220e19e29e0b6efe64a80315d", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "ref": "v0.5.1", + "repo": "xwayland-satellite", + "type": "github" + } + }, + "xwayland-satellite-unstable": { + "flake": false, + "locked": { + "lastModified": 1743346993, + "narHash": "sha256-i7rWd/5BcqLgQEtB5L/6gKN5R5GUJcmm34F+iBivH60=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "45c055696437a08e3989d9b91d9c617b84cc2bc3", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix index d2766fe..935ba7d 100644 --- a/flake.nix +++ b/flake.nix @@ -1,84 +1,205 @@ { - description = "Your new nix config"; + description = "imxyy_soope_'s NixOS (flake) config"; inputs = { # Nixpkgs - nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05"; - # You can access packages and modules from different nixpkgs revs - # at the same time. Here's an working example: - nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; - # Also see the 'unstable-packages' overlay at 'overlays/default.nix'. + nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable-small"; + nixpkgs-stable.url = "github:nixos/nixpkgs/release-24.11"; + nixpkgs-master.url = "github:nixos/nixpkgs/master"; + # nixpkgs.follows = "nixpkgs-stable"; + nixpkgs.follows = "nixpkgs-unstable"; + + # SOPS + sops-nix.url = "github:Mic92/sops-nix"; + sops-nix.inputs.nixpkgs.follows = "nixpkgs"; # Home manager - home-manager.url = "github:nix-community/home-manager/release-23.05"; + home-manager.url = "github:nix-community/home-manager/master"; home-manager.inputs.nixpkgs.follows = "nixpkgs"; - # TODO: Add any other flake you might need - # hardware.url = "github:nixos/nixos-hardware"; + # Impermanence + impermanence.url = "github:nix-community/impermanence"; - # Shameless plug: looking for a way to nixify your themes and make - # everything match nicely? Try nix-colors! - # nix-colors.url = "github:misterio77/nix-colors"; + # NUR + nur.url = "github:nix-community/NUR"; + + # NeoVim nightly + # neovim-nightly.url = "github:nix-community/neovim-nightly-overlay"; + # neovim-nightly.inputs.nixpkgs.follows = "nixpkgs"; + + nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions"; + + # OMZ + omz.url = "github:imxyy1soope1/omz/master"; + omz.inputs.nixpkgs.follows = "nixpkgs"; + + # dwm + dwm.url = "github:imxyy1soope1/dwm/master"; + dwm.inputs.nixpkgs.follows = "nixpkgs"; + + # Niri + niri.url = "github:sodiboo/niri-flake"; + niri.inputs.nixpkgs.follows = "nixpkgs"; + niri.inputs.nixpkgs-stable.follows = "nixpkgs-stable"; + + quickshell.url = "git+https://git.outfoxxed.me/outfoxxed/quickshell"; + quickshell.inputs.nixpkgs.follows = "nixpkgs"; + + darkly.url = "github:Bali10050/Darkly"; + darkly.inputs.nixpkgs.follows = "nixpkgs"; + + stylix.url = "github:danth/stylix"; + stylix.inputs.nixpkgs.follows = "nixpkgs"; + + # go-musicfox + go-musicfox.url = "github:imxyy1soope1/go-musicfox/master"; + go-musicfox.inputs.nixpkgs.follows = "nixpkgs"; + + # NixOS-WSL + nixos-wsl.url = "github:nix-community/NixOS-WSL"; + nixos-wsl.inputs.nixpkgs.follows = "nixpkgs"; + + fenix.url = "github:nix-community/fenix"; + fenix.inputs.nixpkgs.follows = "nixpkgs"; }; - outputs = { - self, - nixpkgs, - home-manager, - ... - } @ inputs: let - inherit (self) outputs; - # Supported systems for your flake packages, shell, etc. - systems = [ - "aarch64-linux" - "i686-linux" - "x86_64-linux" - "aarch64-darwin" - "x86_64-darwin" - ]; - # This is a function that generates an attribute by calling a function you - # pass to it, with each system as an argument - forAllSystems = nixpkgs.lib.genAttrs systems; - in { - # Your custom packages - # Accessible through 'nix build', 'nix shell', etc - packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system}); - # Formatter for your nix files, available through 'nix fmt' - # Other options beside 'alejandra' include 'nixpkgs-fmt' - formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.alejandra); + outputs = + { + self, + nixpkgs, + nixos-wsl, + ... + }@inputs: + let + inherit (self) outputs; + variables = import ./variables.nix; + forAllSystems = nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed; + forAllHosts = + gen: + nixpkgs.lib.attrsets.mergeAttrsList ( + builtins.map ( + { hostname, ... }@host: + { + ${hostname} = gen host; + } + ) variables.hosts + ); + in + { + packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system}); + formatter = forAllSystems ( + system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + pkgs.writeShellApplication { + name = "nixfmt-wrapper"; - # Your custom packages and modifications, exported as overlays - overlays = import ./overlays {inherit inputs;}; - # Reusable nixos modules you might want to export - # These are usually stuff you would upstream into nixpkgs - nixosModules = import ./modules/nixos; - # Reusable home-manager modules you might want to export - # These are usually stuff you would upstream into home-manager - homeManagerModules = import ./modules/home-manager; + runtimeInputs = [ + pkgs.fd + pkgs.nixfmt-rfc-style + ]; - # NixOS configuration entrypoint - # Available through 'nixos-rebuild --flake .#your-hostname' - nixosConfigurations = { - imxyy-nix = nixpkgs.lib.nixosSystem { - specialArgs = {inherit inputs outputs;}; - modules = [ - # > Our main nixos configuration file < - ./nixos/configuration.nix - ]; - }; + text = '' + fd "$@" -t f -e nix -x nixfmt '{}' + ''; + } + ); + + overlays = import ./overlays { inherit inputs; }; + + # Available through 'nixos-rebuild --flake .#{hostname}' + nixosConfigurations = forAllHosts ( + { hostname, system }: + let + lib = import ./lib/stdlib-extended.nix ( + nixpkgs.lib.extend ( + final: prev: { + inherit (inputs.home-manager.lib) hm; + } + ) + ); + overlays = builtins.attrValues self.overlays ++ [ + inputs.go-musicfox.overlays.default + inputs.omz.overlays.default + inputs.dwm.overlays.default + inputs.niri.overlays.niri + # inputs.neovim-nightly.overlays.default + inputs.fenix.overlays.default + inputs.nix-vscode-extensions.overlays.default + (final: prev: { + darkly-qt5 = inputs.darkly.packages.${final.system}.darkly-qt5; + darkly-qt6 = inputs.darkly.packages.${final.system}.darkly-qt6; + }) + (final: prev: { + quickshell = inputs.quickshell.packages.${final.system}.default.override { + withJemalloc = true; + withQtSvg = true; + withWayland = true; + withPipewire = false; + withPam = false; + withX11 = false; + withHyprland = false; + }; + }) + ]; + pkgs = import nixpkgs { + inherit system overlays; + config.allowUnfree = true; + }; + specialArgs = { + inherit (variables) + username + userdesc + userfullname + useremail + ; + + inherit + inputs + outputs + nixos-wsl + system + hostname + ; + + sopsRoot = ./secrets; + }; + in + lib.nixosSystem { + inherit specialArgs; + modules = [ + ./modules + ./config/base.nix + ./config/hosts/${hostname} + { + nixpkgs = { + inherit pkgs; + }; + } + + inputs.sops-nix.nixosModules.sops + inputs.impermanence.nixosModules.impermanence + inputs.home-manager.nixosModules.default + { + home-manager = { + sharedModules = [ + inputs.sops-nix.homeManagerModules.sops + inputs.impermanence.nixosModules.home-manager.impermanence + inputs.stylix.homeManagerModules.stylix + inputs.niri.homeModules.niri + ( + { lib, ... }: + { + nixpkgs.overlays = lib.mkForce null; + } + ) + ]; + useGlobalPkgs = true; + }; + } + ]; + } + ); }; - - # Standalone home-manager configuration entrypoint - # Available through 'home-manager --flake .#your-username@your-hostname' - homeConfigurations = { - "imxyy@imxyy-nix" = home-manager.lib.homeManagerConfiguration { - pkgs = nixpkgs.legacyPackages.x86_64-linux; # Home-manager requires 'pkgs' instance - extraSpecialArgs = {inherit inputs outputs;}; - modules = [ - # > Our main home-manager configuration file < - ./home-manager/home.nix - ]; - }; - }; - }; } diff --git a/home-manager/home.nix b/home-manager/home.nix deleted file mode 100644 index 19c8813..0000000 --- a/home-manager/home.nix +++ /dev/null @@ -1,68 +0,0 @@ -# This is your home-manager configuration file -# Use this to configure your home environment (it replaces ~/.config/nixpkgs/home.nix) -{ - inputs, - outputs, - lib, - config, - pkgs, - ... -}: { - # You can import other home-manager modules here - imports = [ - # If you want to use modules your own flake exports (from modules/home-manager): - # outputs.homeManagerModules.example - - # Or modules exported from other flakes (such as nix-colors): - # inputs.nix-colors.homeManagerModules.default - - # You can also split up your configuration and import pieces of it here: - # ./nvim.nix - ]; - - nixpkgs = { - # You can add overlays here - overlays = [ - # Add overlays your own flake exports (from overlays and pkgs dir): - outputs.overlays.additions - outputs.overlays.modifications - outputs.overlays.unstable-packages - - # You can also add overlays exported from other flakes: - # neovim-nightly-overlay.overlays.default - - # Or define it inline, for example: - # (final: prev: { - # hi = final.hello.overrideAttrs (oldAttrs: { - # patches = [ ./change-hello-to-hi.patch ]; - # }); - # }) - ]; - # Configure your nixpkgs instance - config = { - # Disable if you don't want unfree packages - allowUnfree = true; - # Workaround for https://github.com/nix-community/home-manager/issues/2942 - allowUnfreePredicate = _: true; - }; - }; - - home = { - username = "imxyy"; - homeDirectory = "/home/imxyy"; - }; - - # Add stuff for your user as you see fit: - # programs.neovim.enable = true; - # home.packages = with pkgs; [ steam ]; - - # Enable home-manager and git - programs.home-manager.enable = true; - programs.git.enable = true; - - # Nicely reload system units when changing configs - systemd.user.startServices = "sd-switch"; - - # https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion - home.stateVersion = "23.11"; -} diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 0000000..e6f5203 --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,102 @@ +{ lib }: + +{ + makeSwitch = + { + default ? false, + config, + optionPath, + optionName, + config', + }: + let + cfg = lib.getAttrFromPath optionPath config.my; + in + { + options.my = lib.setAttrByPath (optionPath) { + enable = (lib.mkEnableOption optionName) // { + inherit default; + }; + }; + + config = lib.mkIf cfg.enable config'; + }; + + makeHomePackageConfig = + { + config, + pkgs, + packageName, + packagePath, + optionPath, + extraConfig ? { }, + }: + lib.my.makeSwitch { + inherit config optionPath; + optionName = packageName; + config' = lib.mkMerge [ + { + my.home.home.packages = [ (lib.getAttrFromPath packagePath pkgs) ]; + } + extraConfig + ]; + }; + + makeHomeProgramConfig = + { + config, + programName, + optionPath, + extraConfig ? { }, + }: + lib.my.makeSwitch { + inherit config optionPath; + optionName = programName; + + config' = lib.mkMerge [ + { + my.home.programs = lib.setAttrByPath [ programName "enable" ] true; + } + extraConfig + ]; + }; + + makeNixosPackageConfig = + { + config, + pkgs, + packageName, + packagePath, + optionPath, + extraConfig ? { }, + }: + lib.my.makeSwitch { + inherit config optionPath; + optionName = packageName; + config' = lib.mkMerge [ + { + environment.systemPackages = [ (lib.getAttrFromPath packagePath pkgs) ]; + } + extraConfig + ]; + }; + + makeNixosProgramConfig = + { + config, + programName, + optionPath, + extraConfig ? { }, + }: + lib.my.makeSwitch { + inherit config optionPath; + optionName = programName; + + config' = lib.mkMerge [ + { + programs = lib.setAttrByPath [ programName "enable" ] true; + } + extraConfig + ]; + }; +} diff --git a/lib/stdlib-extended.nix b/lib/stdlib-extended.nix new file mode 100644 index 0000000..3730146 --- /dev/null +++ b/lib/stdlib-extended.nix @@ -0,0 +1,13 @@ +# Just a convenience function that returns the given Nixpkgs standard +# library extended with the imxyy library. + +stdlib: + +let + mkMyLib = import ./.; +in +stdlib.extend ( + self: super: { + my = mkMyLib { lib = self; }; + } +) diff --git a/modules/cmd/all.nix b/modules/cmd/all.nix new file mode 100644 index 0000000..1c7be6c --- /dev/null +++ b/modules/cmd/all.nix @@ -0,0 +1,17 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all command line tools"; + optionPath = [ + "cmd" + "all" + ]; + config' = { + my.cmd = { + media.all.enable = true; + misc.enable = true; + monitor.all.enable = true; + shell.all.enable = true; + }; + }; +} diff --git a/modules/cmd/default.nix b/modules/cmd/default.nix new file mode 100644 index 0000000..4ece4f1 --- /dev/null +++ b/modules/cmd/default.nix @@ -0,0 +1,10 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./media + ./misc + ./monitor + ./shell + ]; +} diff --git a/modules/cmd/media/all.nix b/modules/cmd/media/all.nix new file mode 100644 index 0000000..003dde6 --- /dev/null +++ b/modules/cmd/media/all.nix @@ -0,0 +1,18 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all command line media tools"; + optionPath = [ + "cmd" + "media" + "all" + ]; + config' = { + my.cmd.media = { + cava.enable = true; + go-musicfox.enable = true; + mpd.enable = true; + ffmpeg.enable = true; + }; + }; +} diff --git a/modules/cmd/media/cava/config/config b/modules/cmd/media/cava/config/config new file mode 100644 index 0000000..ebf957a --- /dev/null +++ b/modules/cmd/media/cava/config/config @@ -0,0 +1,167 @@ +## Configuration file for CAVA. Default values are commented out. Use either ';' or '#' for commenting. + + +[general] + +# Smoothing mode. Can be 'normal', 'scientific' or 'waves'. +mode = normal + +# Accepts only non-negative values. +framerate = 60 + +# 'autosens' will attempt to decrease sensitivity if the bars peak. 1 = on, 0 = off +# 'overshoot' allows bars to overshoot (in % of terminal height) without initiating autosens. +; autosens = 1 +; overshoot = 20 + +# Manual sensitivity in %. Autosens must be turned off for this to take effect. +# 200 means double height. Accepts only non-negative values. +; sensitivity = 100 + +# The number of bars (0-200). 0 sets it to auto (fill up console). +# Bars' width and space between bars in number of characters. +bars = 0 +bar_width = 5 +bar_spacing = 1 + +# Lower and higher cutoff frequencies for lowest and highest bars +# the bandwidth of the visualizer. +# Note: there is a minimum total bandwidth of 43Mhz x number of bars. +# Cava will automatically increase the higher cutoff if a too low band is specified. +; lower_cutoff_freq = 50 +; higher_cutoff_freq = 10000 + + + +[input] + +# Audio capturing method. Possible methods are: 'pulse', 'alsa' or 'fifo'. +# Defaults to 'pulse', 'alsa' or 'fifo', in that order, dependent on what support cava was built with. +# +# All input methods uses the same config variable 'source' +# to define where it should get the audio. +# +# For pulseaudio 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink +# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them). +# +# For alsa 'source' will be the capture device. +# For fifo 'source' will be the path to fifo-file. +method = pulse +source = auto + +; method = alsa +; source = hw:Loopback,1 + +; method = fifo +; source = /tmp/mpd.fifo + + + +[output] + +# Ouput method. Can be 'ncurses', 'noncurses' or 'raw'. +# 'noncurses' is for systems that does not suport ncurses. +# 'raw' is a 16 bit data stream of the bar heights that can be used to send to other applications. +# 'raw' defaults to 200 bars, which can be adjusted in the 'bars' option above. +method = ncurses + +# Visual styles. Can be 'stereo' or 'mono'. +# 'stereo' mirrors both channels with low frequencies in center. +# 'mono' averages both channels and outputs left to right lowest to highest frequencies. +style = mono + +# Raw output target. A fifo will be created if target does not exist. +; raw_target = /dev/stdout + +# Raw data format. Can be 'binary' or 'ascii'. +; data_format = binary + +# Binary bit format, can be '8bit' (0-255) or '16bit' (0-65530). +; bit_format = 16bit + +# Ascii max value. In 'ascii' mode range will run from 0 to value specified here +; ascii_max_range = 1000 + +# Ascii delimiters. In ascii format each bar and frame is separated by a delimiters. +# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)). +; bar_delimiter = 59 +; frame_delimiter = 10 + + + +# [color] + +# # Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow. +# # Or defined by hex code '#xxxxxx' (hex code must be within ''). User defined colors requires a +# # terminal that can change color definitions such as Gnome-terminal or rxvt. +# ; background = black +# ; foreground = cyan + +# # Gradient mode, only hex defined colors are supported, background must also be defined in hex +# # or remain commented out. 1 = on, 0 = off. Warning: for certain terminal emulators cava will +# # not able to restore color definitions on exit, simply restart your terminal to restore colors. +# gradient = 1 +# gradient_color_1 = '#0099ff' +# gradient_color_2 = '#ff3399' + + + +[smoothing] + +# Multiplier for the integral smoothing calculations. Takes values from 0-0.99. +# Higher values means smoother, but less precise. Set to 0 to disable. +; integral = 0.7 + +# Disables or enables the so-called "Monstercat smoothing". Set to 0 to disable. +; monstercat = 1 +; waves = 1 + +# Set gravity multiplier for "drop off". Higher values means bars will drop faster. +# Accepts only non-negative values. 0.5 means half gravity, 2 means double. Set to 0 to disable "drop off". +; gravity = 2 + + +# In bar height, bars that would have been lower that this will not be drawn. +; ignore = 0 + + +[eq] + +# This one is tricky. You can have as much keys as you want. +# Remember to uncomment more then one key! More keys = more precision. +# Look at readme.md on github for further explanations and examples. +#; 1 = 1 # bass +#; 2 = 1 +#; 3 = 1 # midtone +#; 4 = 1 +#; 5 = 1 # treble +1=1 +2=1 +3=2 +4=1 +5=1 + +[color] + +#background = '#191724' +gradient = 1 +gradient_count = 6 +gradient_color_1 = '#31748f' +gradient_color_2 = '#9ccfd8' +gradient_color_3 = '#c4a7e7' +gradient_color_4 = '#ebbcba' +gradient_color_5 = '#f6c177' +gradient_color_6 = '#eb6f92' + +[color] + +gradient = 1 + +gradient_color_1 = '#94e2d5' +gradient_color_2 = '#89dceb' +gradient_color_3 = '#74c7ec' +gradient_color_4 = '#89b4fa' +gradient_color_5 = '#cba6f7' +gradient_color_6 = '#f5c2e7' +gradient_color_7 = '#eba0ac' +gradient_color_8 = '#f38ba8' diff --git a/modules/cmd/media/cava/config/config-applet b/modules/cmd/media/cava/config/config-applet new file mode 100644 index 0000000..5c60010 --- /dev/null +++ b/modules/cmd/media/cava/config/config-applet @@ -0,0 +1,167 @@ +## Configuration file for CAVA. Default values are commented out. Use either ';' or '#' for commenting. + + +[general] + +# Smoothing mode. Can be 'normal', 'scientific' or 'waves'. +mode = normal + +# Accepts only non-negative values. +framerate = 60 + +# 'autosens' will attempt to decrease sensitivity if the bars peak. 1 = on, 0 = off +# 'overshoot' allows bars to overshoot (in % of terminal height) without initiating autosens. +; autosens = 1 +; overshoot = 20 + +# Manual sensitivity in %. Autosens must be turned off for this to take effect. +# 200 means double height. Accepts only non-negative values. +; sensitivity = 100 + +# The number of bars (0-200). 0 sets it to auto (fill up console). +# Bars' width and space between bars in number of characters. +bars = 0 +bar_width = 2 +bar_spacing = 1 + +# Lower and higher cutoff frequencies for lowest and highest bars +# the bandwidth of the visualizer. +# Note: there is a minimum total bandwidth of 43Mhz x number of bars. +# Cava will automatically increase the higher cutoff if a too low band is specified. +; lower_cutoff_freq = 50 +; higher_cutoff_freq = 10000 + + + +[input] + +# Audio capturing method. Possible methods are: 'pulse', 'alsa' or 'fifo'. +# Defaults to 'pulse', 'alsa' or 'fifo', in that order, dependent on what support cava was built with. +# +# All input methods uses the same config variable 'source' +# to define where it should get the audio. +# +# For pulseaudio 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink +# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them). +# +# For alsa 'source' will be the capture device. +# For fifo 'source' will be the path to fifo-file. +method = pulse +source = auto + +; method = alsa +; source = hw:Loopback,1 + +; method = fifo +; source = /tmp/mpd.fifo + + + +[output] + +# Ouput method. Can be 'ncurses', 'noncurses' or 'raw'. +# 'noncurses' is for systems that does not suport ncurses. +# 'raw' is a 16 bit data stream of the bar heights that can be used to send to other applications. +# 'raw' defaults to 200 bars, which can be adjusted in the 'bars' option above. +method = ncurses + +# Visual styles. Can be 'stereo' or 'mono'. +# 'stereo' mirrors both channels with low frequencies in center. +# 'mono' averages both channels and outputs left to right lowest to highest frequencies. +style = mono + +# Raw output target. A fifo will be created if target does not exist. +; raw_target = /dev/stdout + +# Raw data format. Can be 'binary' or 'ascii'. +; data_format = binary + +# Binary bit format, can be '8bit' (0-255) or '16bit' (0-65530). +; bit_format = 16bit + +# Ascii max value. In 'ascii' mode range will run from 0 to value specified here +; ascii_max_range = 1000 + +# Ascii delimiters. In ascii format each bar and frame is separated by a delimiters. +# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)). +; bar_delimiter = 59 +; frame_delimiter = 10 + + + +# [color] + +# # Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow. +# # Or defined by hex code '#xxxxxx' (hex code must be within ''). User defined colors requires a +# # terminal that can change color definitions such as Gnome-terminal or rxvt. +# ; background = black +# ; foreground = cyan + +# # Gradient mode, only hex defined colors are supported, background must also be defined in hex +# # or remain commented out. 1 = on, 0 = off. Warning: for certain terminal emulators cava will +# # not able to restore color definitions on exit, simply restart your terminal to restore colors. +# gradient = 1 +# gradient_color_1 = '#0099ff' +# gradient_color_2 = '#ff3399' + + + +[smoothing] + +# Multiplier for the integral smoothing calculations. Takes values from 0-0.99. +# Higher values means smoother, but less precise. Set to 0 to disable. +; integral = 0.7 + +# Disables or enables the so-called "Monstercat smoothing". Set to 0 to disable. +; monstercat = 1 +; waves = 1 + +# Set gravity multiplier for "drop off". Higher values means bars will drop faster. +# Accepts only non-negative values. 0.5 means half gravity, 2 means double. Set to 0 to disable "drop off". +; gravity = 1 + + +# In bar height, bars that would have been lower that this will not be drawn. +; ignore = 0 + + +[eq] + +# This one is tricky. You can have as much keys as you want. +# Remember to uncomment more then one key! More keys = more precision. +# Look at readme.md on github for further explanations and examples. +#; 1 = 1 # bass +#; 2 = 1 +#; 3 = 1 # midtone +#; 4 = 1 +#; 5 = 1 # treble +1=1 +2=1 +3=2 +4=1 +5=1 + +[color] + +#background = '#191724' +gradient = 1 +gradient_count = 6 +gradient_color_1 = '#31748f' +gradient_color_2 = '#9ccfd8' +gradient_color_3 = '#c4a7e7' +gradient_color_4 = '#ebbcba' +gradient_color_5 = '#f6c177' +gradient_color_6 = '#eb6f92' + +[color] + +gradient = 1 + +gradient_color_1 = '#94e2d5' +gradient_color_2 = '#89dceb' +gradient_color_3 = '#74c7ec' +gradient_color_4 = '#89b4fa' +gradient_color_5 = '#cba6f7' +gradient_color_6 = '#f5c2e7' +gradient_color_7 = '#eba0ac' +gradient_color_8 = '#f38ba8' diff --git a/modules/cmd/media/cava/config/shaders/bar_spectrum.frag b/modules/cmd/media/cava/config/shaders/bar_spectrum.frag new file mode 100644 index 0000000..b078913 --- /dev/null +++ b/modules/cmd/media/cava/config/shaders/bar_spectrum.frag @@ -0,0 +1,79 @@ +#version 330 + +in vec2 fragCoord; +out vec4 fragColor; + +// bar values. defaults to left channels first (low to high), then right (high to low). +uniform float bars[512]; + +uniform int bars_count; // number of bars (left + right) (configurable) +uniform int bar_width; // bar width (configurable), not used here +uniform int bar_spacing; // space bewteen bars (configurable) + +uniform vec3 u_resolution; // window resolution + +//colors, configurable in cava config file (r,g,b) (0.0 - 1.0) +uniform vec3 bg_color; // background color +uniform vec3 fg_color; // foreground color + +uniform int gradient_count; +uniform vec3 gradient_colors[8]; // gradient colors + +vec3 normalize_C(float y,vec3 col_1, vec3 col_2, float y_min, float y_max) +{ + //create color based on fraction of this color and next color + float yr = (y - y_min) / (y_max - y_min); + return col_1 * (1.0 - yr) + col_2 * yr; +} + +void main() +{ + // find which bar to use based on where we are on the x axis + float x = u_resolution.x * fragCoord.x; + int bar = int(bars_count * fragCoord.x); + + //calculate a bar size + float bar_size = u_resolution.x / bars_count; + + //the y coordinate and bar values are the same + float y = bars[bar]; + + // make sure there is a thin line at bottom + if (y * u_resolution.y < 1.0) + { + y = 1.0 / u_resolution.y; + } + + //draw the bar up to current height + if (y > fragCoord.y) + { + //make some space between bars basen on settings + if (x > (bar + 1) * (bar_size) - bar_spacing) + { + fragColor = vec4(bg_color,1.0); + } + else + { + if (gradient_count == 0) + { + fragColor = vec4(fg_color,1.0); + } + else + { + //find which color in the configured gradient we are at + int color = int((gradient_count - 1) * fragCoord.y); + + //find where on y this and next color is supposed to be + float y_min = color / (gradient_count - 1.0); + float y_max = (color + 1.0) / (gradient_count - 1.0); + + //make color + fragColor = vec4(normalize_C(fragCoord.y, gradient_colors[color], gradient_colors[color + 1], y_min, y_max), 1.0); + } + } + } + else + { + fragColor = vec4(bg_color,1.0); + } +} \ No newline at end of file diff --git a/modules/cmd/media/cava/config/shaders/normalized_bars.frag b/modules/cmd/media/cava/config/shaders/normalized_bars.frag new file mode 100644 index 0000000..81a27e2 --- /dev/null +++ b/modules/cmd/media/cava/config/shaders/normalized_bars.frag @@ -0,0 +1,38 @@ +#version 330 + +in vec2 fragCoord; +out vec4 fragColor; + +// bar values. defaults to left channels first (low to high), then right (high to low). +uniform float bars[512]; + +uniform int bars_count; // number of bars (left + right) (configurable) + +uniform vec3 u_resolution; // window resolution, not used here + +//colors, configurable in cava config file +uniform vec3 bg_color; // background color(r,g,b) (0.0 - 1.0), not used here +uniform vec3 fg_color; // foreground color, not used here + +float normalize_C(float x, float x_min, float x_max, float r_min, float r_max ) +{ + float xr; + xr = (r_max-r_min) * (x - x_min) / (x_max - x_min) + r_min; + return xr; +} + +void main() +{ + // find which bar to use based on where we are on the x axis + int bar = int(bars_count * fragCoord.x); + + // create a normal along the y axis based on the bar height + float x = normalize_C(fragCoord.y, 1.0, 0.0, 0.0, bars[bar]); + + // set color + fragColor.r=fg_color.x*x; + fragColor.g=fg_color.y*x; + fragColor.b=fg_color.z*x; + fragColor.a=1.0; + +} diff --git a/modules/cmd/media/cava/config/shaders/northern_lights.frag b/modules/cmd/media/cava/config/shaders/northern_lights.frag new file mode 100644 index 0000000..ecd859a --- /dev/null +++ b/modules/cmd/media/cava/config/shaders/northern_lights.frag @@ -0,0 +1,34 @@ +#version 330 + +in vec2 fragCoord; +out vec4 fragColor; + +// bar values. defaults to left channels first (low to high), then right (high to low). +uniform float bars[512]; + +uniform int bars_count; // number of bars (left + right) (configurable) + +uniform vec3 u_resolution; // window resolution, not used here + +//colors, configurable in cava config file +uniform vec3 bg_color; // background color(r,g,b) (0.0 - 1.0), not used here +uniform vec3 fg_color; // foreground color, not used here + +void main() +{ + // find which bar to use based on where we are on the x axis + int bar = int(bars_count * fragCoord.x); + + float bar_y = 1.0 - abs((fragCoord.y - 0.5)) * 2.0; + float y = (bars[bar]) * bar_y; + + float bar_x = (fragCoord.x - float(bar) / float(bars_count)) * bars_count; + float bar_r = 1.0 - abs((bar_x - 0.5)) * 2; + + bar_r = bar_r * bar_r * 2; + + // set color + fragColor.r = fg_color.x * y * bar_r; + fragColor.g = fg_color.y * y * bar_r; + fragColor.b = fg_color.z * y * bar_r; +} diff --git a/modules/cmd/media/cava/config/shaders/pass_through.vert b/modules/cmd/media/cava/config/shaders/pass_through.vert new file mode 100644 index 0000000..a4f20e5 --- /dev/null +++ b/modules/cmd/media/cava/config/shaders/pass_through.vert @@ -0,0 +1,14 @@ +#version 330 + + +// Input vertex data, different for all executions of this shader. +layout(location = 0) in vec3 vertexPosition_modelspace; + +// Output data ; will be interpolated for each fragment. +out vec2 fragCoord; + +void main() +{ + gl_Position = vec4(vertexPosition_modelspace,1); + fragCoord = (vertexPosition_modelspace.xy+vec2(1,1))/2.0; +} diff --git a/modules/cmd/media/cava/default.nix b/modules/cmd/media/cava/default.nix new file mode 100644 index 0000000..03b2e77 --- /dev/null +++ b/modules/cmd/media/cava/default.nix @@ -0,0 +1,22 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "cava"; + packagePath = [ "cava" ]; + optionPath = [ + "cmd" + "media" + "cava" + ]; + extraConfig = { + my.home.xdg.configFile."cava" = { + source = ./config; + recursive = true; + }; + }; +} diff --git a/modules/cmd/media/default.nix b/modules/cmd/media/default.nix new file mode 100644 index 0000000..e96d605 --- /dev/null +++ b/modules/cmd/media/default.nix @@ -0,0 +1,10 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./ffmpeg.nix + ./mpd + ./cava + ./go-musicfox + ]; +} diff --git a/modules/cmd/media/ffmpeg.nix b/modules/cmd/media/ffmpeg.nix new file mode 100644 index 0000000..f496661 --- /dev/null +++ b/modules/cmd/media/ffmpeg.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "ffmpeg"; + packagePath = [ "ffmpeg" ]; + optionPath = [ + "cmd" + "media" + "ffmpeg" + ]; +} diff --git a/modules/cmd/media/go-musicfox/default.nix b/modules/cmd/media/go-musicfox/default.nix new file mode 100644 index 0000000..81dc2dd --- /dev/null +++ b/modules/cmd/media/go-musicfox/default.nix @@ -0,0 +1,28 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "go-musicfox"; + optionPath = [ + "cmd" + "media" + "go-musicfox" + ]; + config' = { + my = { + home = { + home.packages = with pkgs; [ + playerctl + go-musicfox + ]; + xdg.configFile."go-musicfox/go-musicfox.ini".source = ./go-musicfox.ini; + }; + + cmd.media.mpd.enable = true; + }; + }; +} diff --git a/modules/cmd/media/go-musicfox/go-musicfox.ini b/modules/cmd/media/go-musicfox/go-musicfox.ini new file mode 100644 index 0000000..dbe81c1 --- /dev/null +++ b/modules/cmd/media/go-musicfox/go-musicfox.ini @@ -0,0 +1,97 @@ +# 启动页配置 +[startup] +# 是否显示启动页 +show=false +# 启动页进度条是否有回弹效果 +progressOutBounce=true +# 启动页时长 +loadingSeconds=2 +# 启动页欢迎语 +welcome=musicfox +# 启动时自动签到 +signin=false + +# 进度条配置 +[progress] +# 进度条已加载字符 +fullChar=# +# 进度条未加载字符 +emptyChar= + +# 主页面配置 +[main] +# 是否显示标题 +showTitle=true +# 加载中提示 +loadingText=[加载中...] +# 歌曲音质,可选项:standard, exhigh, lossless, hires, jyeffect(高清环绕声), sky(沉浸环绕声), jymaster(超清母带) 进行音质判断 +songLevel=hires +# 主题颜色 +# 随机 +# primaryColor=random +# 经典网易云音乐红 +#primaryColor="#ea403f" +primaryColor="#6186D9" +# 是否显示歌词 +showLyric=true +# 歌词偏移 ms +lyricOffset=0 +# 显示歌词翻译 +showLyricTrans=true +# 是否显示通知信息 +showNotify=false +# 开启pprof, --pprof时会开启 +pprofPort=9876 +# altScreen显示模式 +altScreen=true +# 双列显示,开启务必使用等宽字体 +doubleColumn=true +# 下载目录,默认为$HOME/.go-musicfox/download +downloadDir=/home/imxyy/Music/go-musicfox +# 缓存目录,默认为${MUSICFOX_ROOT}/cache +cacheDir=/home/imxyy/Music/go-musicfox/.cache +# 缓存大小(以MB为单位),0为不使用缓存,-1为不限制,默认为0 +cacheLimit=-1 +# 是否显示歌单下所有歌曲,默认不开启,仅获取歌单前1000首,开启后可能会占用更多内存(大量歌曲数据)和带宽(会同时发送多个请求获取歌单下歌曲数据) +showAllSongsOfPlaylist=false +# 动态显示menu行数 +dynamicMenuRows=true +enableMouseEvent = false + +[autoplay] +# 是否开启自动播放,默认不开启 +autoPlay=true +# 自动播放歌单,dailyReco,like,no(保持上次退出时的设置,无视offset),name:歌单名,默认dailyReco +autoPlayList="no" +# 播放偏移,0为第一首,-1为最后一首,默认为0 +offset=0 +# 播放模式,listLoop, order, singleLoop, random, intelligent(心动), last(上次退出时的模式),default,默认为last +playMode=singleLoop + +[player] +# 播放引擎 beep / mpd(需要安装配置mpd) / osx(Mac才可用) +# 不填Mac默认使用osx,其他系统默认使用beep(推荐的配置) +engine=mpd +# beep使用的mp3解码器,可选:go-mp3, minimp3 (minimp3更少的CPU占用,但是稳定性不如go-mp3) +#beepMp3Decoder=go-mp3 + +# mpd配置 +mpdBin=mpd +# !!!注意!!! 一定要在配置文件中设置pid_file,否则在退出时不会kill掉mpd进程 +mpdConfigFile=/home/imxyy/.config/mpd/mpd.conf +mpdNetwork=tcp +mpdAddr=127.0.0.1:6600 + +[unm] +# UNM开关 +switch=true +# UNM源: kuwo,kugou,migu,qq +sources=kuwo,kugou +# UNM搜索其他平台限制 0-3 +searchLimit=0 +# 解除会员限制 +enableLocalVip=true +# 解除音质限制 +unlockSoundEffects=true +# QQ音乐cookie文件 +qqCookieFile= diff --git a/modules/cmd/media/mpd/default.nix b/modules/cmd/media/mpd/default.nix new file mode 100644 index 0000000..e3337a4 --- /dev/null +++ b/modules/cmd/media/mpd/default.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "mpd"; + optionPath = [ + "cmd" + "media" + "mpd" + ]; + config' = { + my.home = { + home.packages = with pkgs; [ + mpd + mpc-cli + ]; + services.mpris-proxy.enable = true; + xdg.configFile."mpd/mpd.conf".source = ./mpd.conf; + }; + }; +} diff --git a/modules/cmd/media/mpd/mpd.conf b/modules/cmd/media/mpd/mpd.conf new file mode 100644 index 0000000..2a81a51 --- /dev/null +++ b/modules/cmd/media/mpd/mpd.conf @@ -0,0 +1,30 @@ +bind_to_address "127.0.0.1" +port "6600" +music_directory "/home/imxyy/Music/go-musicfox/.cache" +pid_file "/home/imxyy/.config/mpd/mpd.pid" +db_file "/home/imxyy/.config/mpd/mpd.db" + +input { + plugin "file" + enabled "yes" +} + +input { + plugin "curl" + enabled "yes" +} + +decoder { + plugin "ffmpeg" + enabled "yes" +} + +audio_output { + type "pipewire" + name "pipewire" +} + +audio_output { + type "pulse" + name "pulseaudio" +} diff --git a/modules/cmd/misc/default.nix b/modules/cmd/misc/default.nix new file mode 100644 index 0000000..9f502f4 --- /dev/null +++ b/modules/cmd/misc/default.nix @@ -0,0 +1,88 @@ +{ + config, + lib, + pkgs, + userfullname, + useremail, + ... +}: +lib.my.makeSwitch { + inherit config; + default = true; + optionName = "misc command line tools"; + optionPath = [ + "cmd" + "misc" + ]; + config' = { + environment.systemPackages = with pkgs; [ + vim + wget + git + + file + gnused + gnutar + + zip + unzip + xz + p7zip + rar + unrar + + pciutils + usbutils + + lsof + + nmap + traceroute + tcping-go + dnsutils + + killall + ]; + + programs.zsh.enable = true; + programs.dconf.enable = true; + + my.home = { + programs.home-manager.enable = true; + programs.git = { + enable = true; + userName = "${userfullname}"; + userEmail = "${useremail}"; + extraConfig = { + pull.rebase = true; + push.autoSetupRemote = true; + }; + }; + + home.packages = with pkgs; [ + lsd + fd + neofetch + fzf + bat + ripgrep + + aria2 + socat + + nix-output-monitor + + tmux + + trash-cli + + cht-sh + + dooit + + # translate-shell + ]; + xdg.configFile."tmux/tmux.conf".source = ./tmux.conf; + }; + }; +} diff --git a/modules/cmd/misc/tmux.conf b/modules/cmd/misc/tmux.conf new file mode 100644 index 0000000..b866b43 --- /dev/null +++ b/modules/cmd/misc/tmux.conf @@ -0,0 +1,9 @@ +set-option -g mouse on + +set -g @plugin 'tmux-plugins/tpm' +set -g @plugin 'tmux-plugins/tmux-sensible' + +set -g @plugin "janoamaral/tokyo-night-tmux#legacy" + +# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) +run '~/.config/tmux/plugins/tpm/tpm' diff --git a/modules/cmd/monitor/all.nix b/modules/cmd/monitor/all.nix new file mode 100644 index 0000000..4c94258 --- /dev/null +++ b/modules/cmd/monitor/all.nix @@ -0,0 +1,15 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all command line monitor tools"; + optionPath = [ + "cmd" + "monitor" + "all" + ]; + config' = { + my.cmd.monitor = { + btop.enable = true; + }; + }; +} diff --git a/modules/cmd/monitor/btop/config/btop.conf b/modules/cmd/monitor/btop/config/btop.conf new file mode 100644 index 0000000..c64f59f --- /dev/null +++ b/modules/cmd/monitor/btop/config/btop.conf @@ -0,0 +1,212 @@ +#? Config file for btop v. 1.2.13 + +#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes. +#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes" +color_theme = "nord.theme" + +#* If the theme set background should be shown, set to False if you want terminal background transparency. +theme_background = False + +#* Sets if 24-bit truecolor should be used, will convert 24-bit colors to 256 color (6x6x6 color cube) if false. +truecolor = True + +#* Set to true to force tty mode regardless if a real tty has been detected or not. +#* Will force 16-color mode and TTY theme, set all graph symbols to "tty" and swap out other non tty friendly symbols. +force_tty = False + +#* Define presets for the layout of the boxes. Preset 0 is always all boxes shown with default settings. Max 9 presets. +#* Format: "box_name:P:G,box_name:P:G" P=(0 or 1) for alternate positions, G=graph symbol to use for box. +#* Use whitespace " " as separator between different presets. +#* Example: "cpu:0:default,mem:0:tty,proc:1:default cpu:0:braille,proc:0:tty" +presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty" + +#* Set to True to enable "h,j,k,l,g,G" keys for directional control in lists. +#* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift. +vim_keys = False + +#* Rounded corners on boxes, is ignored if TTY mode is ON. +rounded_corners = True + +#* Default symbols to use for graph creation, "braille", "block" or "tty". +#* "braille" offers the highest resolution but might not be included in all fonts. +#* "block" has half the resolution of braille but uses more common characters. +#* "tty" uses only 3 different symbols but will work with most fonts and should work in a real TTY. +#* Note that "tty" only has half the horizontal resolution of the other two, so will show a shorter historical view. +graph_symbol = "braille" + +# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". +graph_symbol_cpu = "default" + +# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". +graph_symbol_mem = "default" + +# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". +graph_symbol_net = "default" + +# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty". +graph_symbol_proc = "default" + +#* Manually set which boxes to show. Available values are "cpu mem net proc", separate values with whitespace. +shown_boxes = "cpu mem net proc" + +#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs. +update_ms = 200 + +#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu direct", +#* "cpu lazy" sorts top process over time (easier to follow), "cpu direct" updates top process directly. +proc_sorting = "memory" + +#* Reverse sorting order, True or False. +proc_reversed = False + +#* Show processes as a tree. +proc_tree = True + +#* Use the cpu graph colors in the process list. +proc_colors = True + +#* Use a darkening gradient in the process list. +proc_gradient = False + +#* If process cpu usage should be of the core it's running on or usage of the total available cpu power. +proc_per_core = False + +#* Show process memory as bytes instead of percent. +proc_mem_bytes = True + +#* Show cpu graph for each process. +proc_cpu_graphs = True + +#* Use /proc/[pid]/smaps for memory information in the process info box (very slow but more accurate) +proc_info_smaps = False + +#* Show proc box on left side of screen instead of right. +proc_left = False + +#* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop). +proc_filter_kernel = True + +#* Sets the CPU stat shown in upper half of the CPU graph, "total" is always available. +#* Select from a list of detected attributes from the options menu. +cpu_graph_upper = "total" + +#* Sets the CPU stat shown in lower half of the CPU graph, "total" is always available. +#* Select from a list of detected attributes from the options menu. +cpu_graph_lower = "total" + +#* Toggles if the lower CPU graph should be inverted. +cpu_invert_lower = False + +#* Set to True to completely disable the lower CPU graph. +cpu_single_graph = True + +#* Show cpu box at bottom of screen instead of top. +cpu_bottom = False + +#* Shows the system uptime in the CPU box. +show_uptime = True + +#* Show cpu temperature. +check_temp = True + +#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors. +cpu_sensor = "Auto" + +#* Show temperatures for cpu cores also if check_temp is True and sensors has been found. +show_coretemp = True + +#* Set a custom mapping between core and coretemp, can be needed on certain cpus to get correct temperature for correct core. +#* Use lm-sensors or similar to see which cores are reporting temperatures on your machine. +#* Format "x:y" x=core with wrong temp, y=core with correct temp, use space as separator between multiple entries. +#* Example: "4:0 5:1 6:3" +cpu_core_map = "" + +#* Which temperature scale to use, available values: "celsius", "fahrenheit", "kelvin" and "rankine". +temp_scale = "celsius" + +#* Use base 10 for bits/bytes sizes, KB = 1000 instead of KiB = 1024. +base_10_sizes = False + +#* Show CPU frequency. +show_cpu_freq = True + +#* Draw a clock at top of screen, formatting according to strftime, empty string to disable. +#* Special formatting: /host = hostname | /user = username | /uptime = system uptime +clock_format = "%X" + +#* Update main ui in background when menus are showing, set this to false if the menus is flickering too much for comfort. +background_update = True + +#* Custom cpu model name, empty string to disable. +custom_cpu_name = "" + +#* Optional filter for shown disks, should be full path of a mountpoint, separate multiple values with whitespace " ". +#* Begin line with "exclude=" to change to exclude filter, otherwise defaults to "most include" filter. Example: disks_filter="exclude=/boot /home/user". +disks_filter = "" + +#* Show graphs instead of meters for memory values. +mem_graphs = True + +#* Show mem box below net box instead of above. +mem_below_net = False + +#* Count ZFS ARC in cached and available memory. +zfs_arc_cached = True + +#* If swap memory should be shown in memory box. +show_swap = False + +#* Show swap as a disk, ignores show_swap value above, inserts itself after first disk. +swap_disk = True + +#* If mem box should be split to also show disks info. +show_disks = False + +#* Filter out non physical disks. Set this to False to include network disks, RAM disks and similar. +only_physical = True + +#* Read disks list from /etc/fstab. This also disables only_physical. +use_fstab = False + +#* Setting this to True will hide all datasets, and only show ZFS pools. (IO stats will be calculated per-pool) +zfs_hide_datasets = False + +#* Set to true to show available disk space for privileged users. +disk_free_priv = False + +#* Toggles if io activity % (disk busy time) should be shown in regular disk usage view. +show_io_stat = False + +#* Toggles io mode for disks, showing big graphs for disk read/write speeds. +io_mode = True + +#* Set to True to show combined read/write io graphs in io mode. +io_graph_combined = False + +#* Set the top speed for the io graphs in MiB/s (100 by default), use format "mountpoint:speed" separate disks with whitespace " ". +#* Example: "/mnt/media:100 /:20 /boot:1". +io_graph_speeds = "" + +#* Set fixed values for network graphs in Mebibits. Is only used if net_auto is also set to False. +net_download = 100 + +net_upload = 100 + +#* Use network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest. +net_auto = False + +#* Sync the auto scaling for download and upload to whichever currently has the highest scale. +net_sync = True + +#* Starts with the Network Interface specified here. +net_iface = "eth0" + +#* Show battery stats in top right if battery is present. +show_battery = False + +#* Which battery to use if multiple are present. "Auto" for auto detection. +selected_battery = "Auto" + +#* Set loglevel for "~/.config/btop/btop.log" levels are: "ERROR" "WARNING" "INFO" "DEBUG". +#* The level set includes all lower levels, i.e. "DEBUG" will show all logging info. +log_level = "WARNING" diff --git a/modules/cmd/monitor/btop/config/themes/nord.theme b/modules/cmd/monitor/btop/config/themes/nord.theme new file mode 100644 index 0000000..07c43c2 --- /dev/null +++ b/modules/cmd/monitor/btop/config/themes/nord.theme @@ -0,0 +1,89 @@ +#Bashtop theme with nord palette (https://www.nordtheme.com) +#by Justin Zobel + +# Colors should be in 6 or 2 character hexadecimal or single spaced rgb decimal: "#RRGGBB", "#BW" or "0-255 0-255 0-255" +# example for white: "#ffffff", "#ff" or "255 255 255". + +# All graphs and meters can be gradients +# For single color graphs leave "mid" and "end" variable empty. +# Use "start" and "end" variables for two color gradient +# Use "start", "mid" and "end" for three color gradient + +# Main background, empty for terminal default, need to be empty if you want transparent background +theme[main_bg]="#2E3440" + +# Main text color +theme[main_fg]="#D8DEE9" + +# Title color for boxes +theme[title]="#8FBCBB" + +# Higlight color for keyboard shortcuts +theme[hi_fg]="#5E81AC" + +# Background color of selected item in processes box +theme[selected_bg]="#4C566A" + +# Foreground color of selected item in processes box +theme[selected_fg]="#ECEFF4" + +# Color of inactive/disabled text +theme[inactive_fg]="#4C566A" + +# Misc colors for processes box including mini cpu graphs, details memory graph and details status text +theme[proc_misc]="#5E81AC" + +# Cpu box outline color +theme[cpu_box]="#4C566A" + +# Memory/disks box outline color +theme[mem_box]="#4C566A" + +# Net up/down box outline color +theme[net_box]="#4C566A" + +# Processes box outline color +theme[proc_box]="#4C566A" + +# Box divider line and small boxes line color +theme[div_line]="#4C566A" + +# Temperature graph colors +theme[temp_start]="#81A1C1" +theme[temp_mid]="#88C0D0" +theme[temp_end]="#ECEFF4" + +# CPU graph colors +theme[cpu_start]="#81A1C1" +theme[cpu_mid]="#88C0D0" +theme[cpu_end]="#ECEFF4" + +# Mem/Disk free meter +theme[free_start]="#81A1C1" +theme[free_mid]="#88C0D0" +theme[free_end]="#ECEFF4" + +# Mem/Disk cached meter +theme[cached_start]="#81A1C1" +theme[cached_mid]="#88C0D0" +theme[cached_end]="#ECEFF4" + +# Mem/Disk available meter +theme[available_start]="#81A1C1" +theme[available_mid]="#88C0D0" +theme[available_end]="#ECEFF4" + +# Mem/Disk used meter +theme[used_start]="#81A1C1" +theme[used_mid]="#88C0D0" +theme[used_end]="#ECEFF4" + +# Download graph colors +theme[download_start]="#81A1C1" +theme[download_mid]="#88C0D0" +theme[download_end]="#ECEFF4" + +# Upload graph colors +theme[upload_start]="#81A1C1" +theme[upload_mid]="#88C0D0" +theme[upload_end]="#ECEFF4" diff --git a/modules/cmd/monitor/btop/default.nix b/modules/cmd/monitor/btop/default.nix new file mode 100644 index 0000000..fdd3b48 --- /dev/null +++ b/modules/cmd/monitor/btop/default.nix @@ -0,0 +1,22 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "btop"; + packagePath = [ "btop" ]; + optionPath = [ + "cmd" + "monitor" + "btop" + ]; + extraConfig = { + my.home.xdg.configFile."btop" = { + source = ./config; + recursive = true; + }; + }; +} diff --git a/modules/cmd/monitor/default.nix b/modules/cmd/monitor/default.nix new file mode 100644 index 0000000..53bf3d9 --- /dev/null +++ b/modules/cmd/monitor/default.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./btop + ]; +} diff --git a/modules/cmd/shell/all.nix b/modules/cmd/shell/all.nix new file mode 100644 index 0000000..4a38baa --- /dev/null +++ b/modules/cmd/shell/all.nix @@ -0,0 +1,15 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all shells"; + optionPath = [ + "cmd" + "shell" + "all" + ]; + config' = { + my.cmd.shell = { + zsh.enable = true; + }; + }; +} diff --git a/modules/cmd/shell/default.nix b/modules/cmd/shell/default.nix new file mode 100644 index 0000000..1242d58 --- /dev/null +++ b/modules/cmd/shell/default.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./zsh.nix + ]; +} diff --git a/modules/cmd/shell/zsh.nix b/modules/cmd/shell/zsh.nix new file mode 100644 index 0000000..54a71bc --- /dev/null +++ b/modules/cmd/shell/zsh.nix @@ -0,0 +1,49 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + default = true; + optionName = "default zsh settings"; + optionPath = [ + "cmd" + "shell" + "zsh" + ]; + config' = { + my.home = + let + stateHome = config.my.home.xdg.stateHome; + in + { + home.packages = [ pkgs.omz ]; + programs.zsh = { + enable = true; + dotDir = ".config/zsh"; + history = { + path = "${stateHome}/zsh_history"; + ignorePatterns = [ + "la" + ]; + }; + initExtra = '' + source ${pkgs.omz}/share/omz/omz.zsh + ''; + sessionVariables = { + _ZL_DATA = "${stateHome}/zlua"; + _FZF_HISTORY = "${stateHome}/fzf_history"; + }; + shellAliases = { + ls = "lsd"; + svim = "sudoedit"; + nf = "neofetch"; + tmux = "tmux -T RGB,focus,overline,mouse,clipboard,usstyle"; + pastart = "pasuspender true"; + }; + }; + }; + }; +} diff --git a/modules/coding/all.nix b/modules/coding/all.nix new file mode 100644 index 0000000..7b86eb4 --- /dev/null +++ b/modules/coding/all.nix @@ -0,0 +1,16 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all coding tools"; + optionPath = [ + "coding" + "all" + ]; + config' = { + my.coding = { + editor.all.enable = true; + langs.all.enable = true; + misc.enable = true; + }; + }; +} diff --git a/modules/coding/default.nix b/modules/coding/default.nix new file mode 100644 index 0000000..db172ec --- /dev/null +++ b/modules/coding/default.nix @@ -0,0 +1,9 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./misc.nix + ./langs + ./editor + ]; +} diff --git a/modules/coding/editor/all.nix b/modules/coding/editor/all.nix new file mode 100644 index 0000000..815ffaf --- /dev/null +++ b/modules/coding/editor/all.nix @@ -0,0 +1,16 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all coding editors"; + optionPath = [ + "coding" + "editor" + "all" + ]; + config' = { + my.coding.editor = { + neovim.enable = true; + vscode.enable = true; + }; + }; +} diff --git a/modules/coding/editor/default.nix b/modules/coding/editor/default.nix new file mode 100644 index 0000000..548c5a1 --- /dev/null +++ b/modules/coding/editor/default.nix @@ -0,0 +1,8 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./neovim + ./vscode + ]; +} diff --git a/modules/coding/editor/neovim/default.nix b/modules/coding/editor/neovim/default.nix new file mode 100644 index 0000000..e56d8c2 --- /dev/null +++ b/modules/coding/editor/neovim/default.nix @@ -0,0 +1,61 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomeProgramConfig { + inherit config; + programName = "neovim"; + optionPath = [ + "coding" + "editor" + "neovim" + ]; + extraConfig = { + my.home = { + xdg.configFile."nvim/init.lua".source = ./nvim/init.lua; + xdg.configFile."nvim/lua" = { + source = ./nvim/lua; + recursive = true; + }; + programs.neovim = { + package = pkgs.neovim-unwrapped.overrideAttrs { + treesitter-parsers = { }; + }; + enable = true; + defaultEditor = true; + viAlias = true; + vimAlias = true; + vimdiffAlias = true; + extraPackages = with pkgs; [ + gcc + gnumake + + pyright + + clang-tools + + rust-analyzer + pest-ide-tools + + nil + + gotools + gopls + + stylua + lua-language-server + + nodePackages.vscode-langservers-extracted + nodePackages.typescript-language-server + vue-language-server + typescript + nodejs + + ripgrep + ]; + }; + }; + }; +} diff --git a/modules/coding/editor/neovim/nvim/init.lua b/modules/coding/editor/neovim/nvim/init.lua new file mode 100644 index 0000000..1a94d64 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/init.lua @@ -0,0 +1,9 @@ +require("core.options") +require("core.keymaps") + +require("langs.langs-setup") + +require("plugins.plugins-setup") + +require("core.autostart") + diff --git a/modules/coding/editor/neovim/nvim/lua/core/autostart.lua b/modules/coding/editor/neovim/nvim/lua/core/autostart.lua new file mode 100644 index 0000000..179133c --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/core/autostart.lua @@ -0,0 +1,7 @@ +-- Open tree when in config dir +local configdir = vim.fn.system("echo $HOME/.config") +configdir = string.sub(configdir, 1, string.len(configdir) - 1) +if string.find(vim.fn.system("pwd"), configdir) ~= nil then + vim.cmd("NvimTreeOpen") + vim.cmd("NvimTmuxNavigateRight") +end diff --git a/modules/coding/editor/neovim/nvim/lua/core/globals.lua b/modules/coding/editor/neovim/nvim/lua/core/globals.lua new file mode 100644 index 0000000..80fe78a --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/core/globals.lua @@ -0,0 +1,113 @@ +G = {} + +G.keymap_opt = { noremap = true, silent = true } + +function G.close_empty_buffer() + local flag = false + local cleaned = true + local empties = {} + for _, b in ipairs(vim.api.nvim_list_bufs()) do + local info = vim.fn.getbufinfo(b)[1] + if info.loaded == 1 and info.listed == 1 and info.name ~= "" then + flag = true + elseif info.loaded == 1 and info.name == "" and info.changed == 0 then + if flag and not cleaned then + for e in table do + G.buf_kill("bd", e, false) + end + cleaned = true + elseif cleaned then + G.buf_kill("bd", b, false) + else + table.insert(empties, b) + end + end + end + if not flag and #empties == 0 then + vim.cmd("enew") + end +end + +function G.switch_input_method(req) + local input_status = tonumber(vim.fn.system("fcitx5-remote")) + if input_status ~= req then + vim.fn.system("fcitx5-remote -t") + end + return input_status +end + + +function G.buf_kill(kill_command, bufnr, force) + kill_command = kill_command or "bd" + + local bo = vim.bo + local api = vim.api + local fmt = string.format + local fn = vim.fn + + if bufnr == 0 or bufnr == nil then + bufnr = api.nvim_get_current_buf() + end + + local bufname = api.nvim_buf_get_name(bufnr) + + if not force then + local choice + if bo[bufnr].modified then + choice = fn.confirm(fmt([[Save changes to "%s"?]], bufname), "&Yes\n&No\n&Cancel") + if choice == 1 then + vim.api.nvim_buf_call(bufnr, function() + vim.cmd("w") + end) + elseif choice == 2 then + force = true + else return + end + elseif api.nvim_buf_get_option(bufnr, "buftype") == "terminal" then + choice = fn.confirm(fmt([[Close "%s"?]], bufname), "&Yes\n&No\n&Cancel") + if choice == 1 then + force = true + else + return + end + end + end + + -- Get list of windows IDs with the buffer to close + local windows = vim.tbl_filter(function(win) + return api.nvim_win_get_buf(win) == bufnr + end, api.nvim_list_wins()) + + if force then + kill_command = kill_command .. "!" + end + + -- Get list of active buffers + local buffers = vim.tbl_filter(function(buf) + return api.nvim_buf_is_valid(buf) and bo[buf].buflisted + end, api.nvim_list_bufs()) + + -- If there is only one buffer (which has to be the current one), vim will + -- create a new buffer on :bd. + -- For more than one buffer, pick the previous buffer (wrapping around if necessary) + if #buffers > 1 and #windows > 0 then + for i, v in ipairs(buffers) do + if v == bufnr then + local prev_buf_idx = i == 1 and #buffers or (i - 1) + local prev_buffer = buffers[prev_buf_idx] + for _, win in ipairs(windows) do + api.nvim_win_set_buf(win, prev_buffer) + end + end + end + end + + -- Check if buffer still exists, to ensure the target buffer wasn't killed + -- due to options like bufhidden=wipe. + if api.nvim_buf_is_valid(bufnr) and bo[bufnr].buflisted then + vim.cmd(string.format("%s %d", kill_command, bufnr)) + end + return true +end + +return G diff --git a/modules/coding/editor/neovim/nvim/lua/core/keymaps.lua b/modules/coding/editor/neovim/nvim/lua/core/keymaps.lua new file mode 100644 index 0000000..261b3df --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/core/keymaps.lua @@ -0,0 +1,71 @@ +vim.g.mapleader = " " + +local keymap = vim.keymap +local globals = require("core.globals") +local opt = globals.keymap_opt +local buf_kill = globals.buf_kill + +keymap.set("v", "", ":m '<-2gv=gv", opt) +keymap.set("v", "", ":m '>+1gv=gv", opt) + +keymap.set("n", "nh", ":nohl", opt) + +keymap.set("n", "sv", "v", opt) +keymap.set("n", "sh", "s", opt) + +keymap.set("i", "", "v", opt) +keymap.set("i", "", "v", opt) +keymap.set("n", "", "v", opt) +keymap.set("n", "", "v", opt) +keymap.set("v", "", "", opt) +keymap.set("v", "", "", opt) + +keymap.set("i", "", "v", opt) +keymap.set("i", "", "v", opt) +keymap.set("n", "", "v", opt) +keymap.set("n", "", "v", opt) +keymap.set("v", "", "", opt) +keymap.set("v", "", "", opt) + +keymap.set("v", ".", ">gv", opt) +keymap.set("v", ",", "", "9k", opt) +keymap.set({ "n", "v" }, "", "9j", opt) +keymap.set("i", "", "", opt) +keymap.set("i", "", "", opt) + +keymap.set("n", "ww", ":w", opt) +keymap.set("n", "so", ":so", opt) +keymap.set("n", "qq", ":q", opt) +keymap.set("n", "qa", ":qa", opt) +keymap.set("n", "c", function () buf_kill("bd", nil, false) end, opt) + +keymap.set("n", "", ":resize +5", opt) +keymap.set("n", "", ":resize -5", opt) +keymap.set("n", "", ":vert resize +5", opt) +keymap.set("n", "", ":vert resize -5", opt) + +-- buffer +keymap.set("n", "H", ":BufferLineCyclePrev", opt) +keymap.set("n", "L", ":BufferLineCycleNext", opt) +keymap.set("n", "", ":BufferLineMovePrev", opt) +keymap.set("n", "", ":BufferLineMoveNext", opt) + +-- reload config +keymap.set("n", "rc", ":so ~/.config/nvim/init.lua", opt) +keymap.set("n", "rp", ":so ~/.config/nvim/lua/plugins/plugins-setup.lua", opt) + +-- Workspaces +keymap.set("n", "wo", ":Telescope workspaces", opt) +keymap.set("n", "wa", ":WorkspacesAdd", opt) +keymap.set("n", "wr", ":WorkspacesRemove", opt) + +-- Neovide config +if vim.g.neovide then + keymap.set("v", "", "\"+y", opt) + keymap.set("n", "", "\"+P", opt) + keymap.set("i", "", "l\"+Pli", opt) + keymap.set("c", "", "+", opt) +end + diff --git a/modules/coding/editor/neovim/nvim/lua/core/options.lua b/modules/coding/editor/neovim/nvim/lua/core/options.lua new file mode 100644 index 0000000..426da2f --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/core/options.lua @@ -0,0 +1,140 @@ +local opt = vim.opt + +-- Tab width setting +opt.tabstop = 4 +opt.shiftwidth = 4 +opt.softtabstop = 4 +opt.expandtab = true +opt.autoindent = true + +-- Linenumber setting +opt.number = true +opt.relativenumber = true +opt.wrap = false +opt.cursorline = true + +opt.mouse:append("a") +opt.clipboard:append("unnamedplus") +opt.splitright = true +opt.splitbelow = true +opt.ignorecase = true +opt.smartcase = true +opt.termguicolors = true +opt.signcolumn = "yes" +opt.colorcolumn = "110" +opt.scrolloff = 8 +opt.sidescrolloff = 8 + +opt.updatetime = 500 +opt.timeoutlen = 500 + +opt.completeopt = "" + +opt.autoread = true +vim.g.autoread = true + +vim.g.loaded_ruby_provider = 0 + +-- Hightlight on yank +local highlight_group = vim.api.nvim_create_augroup('YankHighlight', { clear = true }) +vim.api.nvim_create_autocmd('TextYankPost', { + callback = function() + vim.highlight.on_yank() + end, + group = highlight_group, + pattern = "*", +}) + +-- Remember last position +vim.cmd([[ + autocmd BufReadPost * + \ if line("'\"") > 0 && line("'\"") <= line("$") | + \ exe "normal! g`\"" | + \ endif +]]) + +-- Automaticly switch input method +Last_input_method = 1 +vim.api.nvim_create_augroup("AutoInputMethod", {}) +vim.api.nvim_create_autocmd("InsertLeave", { + pattern = "*", + desc = "Automaticly switch input method", + callback = function() + Last_input_method = require("core.globals").switch_input_method(1) + end, + group = "AutoInputMethod" +}) +vim.api.nvim_create_autocmd("CmdlineLeave", { + pattern = "*", + desc = "Automaticly switch input method", + callback = function() + require("core.globals").switch_input_method(1) + end, + group = "AutoInputMethod" +}) +vim.api.nvim_create_autocmd("InsertEnter", { + pattern = "*", + desc = "Automaticly switch input method", + callback = function() + require("core.globals").switch_input_method(Last_input_method) + end, + group = "AutoInputMethod" +}) + +vim.api.nvim_create_autocmd("FileType", { + pattern = { "lua" }, + desc = "fix gf functionality inside .lua files", + callback = function() + ---@diagnostic disable: assign-type-mismatch + -- credit: https://github.com/sam4llis/nvim-lua-gf + vim.opt_local.include = [[\v<((do|load)file|require|reload)[^''"]*[''"]\zs[^''"]+]] + vim.opt_local.includeexpr = "substitute(v:fname,'\\.','/','g')" + vim.opt_local.suffixesadd:prepend ".lua" + vim.opt_local.suffixesadd:prepend "init.lua" + + for _, path in pairs(vim.api.nvim_list_runtime_paths()) do + vim.opt_local.path:append(path .. "/lua") + end + end, +}) + +-- fix https://github.com/neovim/neovim/issues/21856 +vim.api.nvim_create_autocmd({ "VimLeave" }, { + callback = function() + vim.fn.jobstart("", { detach = true }) + end, +}) + +-- MkDir +vim.api.nvim_create_user_command("MakeDirectory", function() + ---@diagnostic disable-next-line: missing-parameter + local path = vim.fn.expand("%") + local dir = vim.fn.fnamemodify(path, ":p:h") + if vim.fn.isdirectory(dir) == 0 then + vim.fn.mkdir(dir, "p") + else + vim.notify("Directory already exists", vim.log.levels.WARN, { title = "Nvim" }) + end +end, { desc = "Create directory if it doesn't exist" }) + +-- Neovide config +if vim.g.neovide then + local global = vim.g + vim.o.guifont = "monospace:h14" + global.neovide_padding_top = 0 + global.neovide_padding_bottom = 0 + global.neovide_padding_right = 0 + global.neovide_padding_left = 0 + global.neovide_hide_mouse_when_typing = true + global.neovide_cursor_animation_length = 0.05 + global.neovide_cursor_trail_size = 0.15 + global.neovide_confirm_quit = true +end + +vim.api.nvim_create_autocmd({ "VimEnter" }, { + callback = function() + -- A dumb way to clear annoying NeoVim startup screen + vim.cmd("normal ia") + vim.cmd("normal u") + end, +}) diff --git a/modules/coding/editor/neovim/nvim/lua/langs/go.lua b/modules/coding/editor/neovim/nvim/lua/langs/go.lua new file mode 100644 index 0000000..471d2a3 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/langs/go.lua @@ -0,0 +1,13 @@ +vim.api.nvim_create_augroup("Go", {}) +vim.api.nvim_create_autocmd("BufWritePre", { + pattern = { "*.go" }, + desc = "auto format Go files", + callback = function() + vim.lsp.buf.format() + -- vim.fn.system("go fmt " .. vim.fn.expand("%:p")) + -- vim.fn.system("goimports -w " .. vim.fn.expand("%:p")) + -- vim.cmd("edit") + end, + group = "Go", +}) + diff --git a/modules/coding/editor/neovim/nvim/lua/langs/langs-setup.lua b/modules/coding/editor/neovim/nvim/lua/langs/langs-setup.lua new file mode 100644 index 0000000..0ccecf8 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/langs/langs-setup.lua @@ -0,0 +1,5 @@ +require("langs.go") +-- require("langs.rust") +require("langs.lualang") +require("langs.nix") +require("langs.markdown") diff --git a/modules/coding/editor/neovim/nvim/lua/langs/lualang.lua b/modules/coding/editor/neovim/nvim/lua/langs/lualang.lua new file mode 100644 index 0000000..cdce079 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/langs/lualang.lua @@ -0,0 +1,35 @@ +vim.api.nvim_create_augroup("Lua", {}) + +local old = {} +vim.api.nvim_create_autocmd("BufEnter", { + pattern = { "*.lua" }, + desc = "auto lua file indent", + callback = function() + local opt = vim.opt + -- Tab width setting + old.tabstop = opt.tabstop + old.shiftwidth = opt.shiftwidth + old.softtabstop = opt.softtabstop + old.expandtab = opt.expandtab + opt.tabstop = 2 + opt.shiftwidth = 2 + opt.softtabstop = 2 + opt.expandtab = true + opt.autoindent = true + end, + group = "Lua", +}) +vim.api.nvim_create_autocmd("BufLeave", { + pattern = { "*.lua" }, + desc = "auto lua file indent", + callback = function() + local opt = vim.opt + -- Tab width setting + opt.tabstop = old.tabstop + opt.shiftwidth = old.shiftwidth + opt.softtabstop = old.softtabstop + opt.expandtab = old.expandtab + end, + group = "Lua", +}) + diff --git a/modules/coding/editor/neovim/nvim/lua/langs/markdown.lua b/modules/coding/editor/neovim/nvim/lua/langs/markdown.lua new file mode 100644 index 0000000..de722b9 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/langs/markdown.lua @@ -0,0 +1,35 @@ +vim.api.nvim_create_augroup("Markdown", {}) + +local old = {} +vim.api.nvim_create_autocmd("BufEnter", { + pattern = { "*.md" }, + desc = "auto md file indent", + callback = function() + local opt = vim.opt + -- Tab width setting + old.tabstop = opt.tabstop + old.shiftwidth = opt.shiftwidth + old.softtabstop = opt.softtabstop + old.expandtab = opt.expandtab + opt.tabstop = 2 + opt.shiftwidth = 2 + opt.softtabstop = 2 + opt.expandtab = true + opt.autoindent = true + end, + group = "Markdown", +}) +vim.api.nvim_create_autocmd("BufLeave", { + pattern = { "*.md" }, + desc = "auto markdown file indent", + callback = function() + local opt = vim.opt + -- Tab width setting + opt.tabstop = old.tabstop + opt.shiftwidth = old.shiftwidth + opt.softtabstop = old.softtabstop + opt.expandtab = old.expandtab + end, + group = "Markdown", +}) + diff --git a/modules/coding/editor/neovim/nvim/lua/langs/nix.lua b/modules/coding/editor/neovim/nvim/lua/langs/nix.lua new file mode 100644 index 0000000..ea0990c --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/langs/nix.lua @@ -0,0 +1,35 @@ +vim.api.nvim_create_augroup("Nix", {}) + +local old = {} +vim.api.nvim_create_autocmd("BufEnter", { + pattern = { "*.nix" }, + desc = "auto nix file indent", + callback = function() + local opt = vim.opt + -- Tab width setting + old.tabstop = opt.tabstop + old.shiftwidth = opt.shiftwidth + old.softtabstop = opt.softtabstop + old.expandtab = opt.expandtab + opt.tabstop = 2 + opt.shiftwidth = 2 + opt.softtabstop = 2 + opt.expandtab = true + opt.autoindent = true + end, + group = "Nix", +}) +vim.api.nvim_create_autocmd("BufLeave", { + pattern = { "*.nix" }, + desc = "auto nix file indent", + callback = function() + local opt = vim.opt + -- Tab width setting + opt.tabstop = old.tabstop + opt.shiftwidth = old.shiftwidth + opt.softtabstop = old.softtabstop + opt.expandtab = old.expandtab + end, + group = "Nix", +}) + diff --git a/modules/coding/editor/neovim/nvim/lua/langs/rust.lua b/modules/coding/editor/neovim/nvim/lua/langs/rust.lua new file mode 100644 index 0000000..8a6456f --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/langs/rust.lua @@ -0,0 +1,11 @@ +vim.api.nvim_create_augroup("Rust", {}) +vim.api.nvim_create_autocmd("BufWritePost", { + pattern = { "*.rs" }, + desc = "auto format Rust files", + callback = function() + vim.fn.system("rustfmt " .. vim.fn.expand("%:p")) + vim.cmd("edit") + end, + group = "Rust", +}) + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/autopairs.lua b/modules/coding/editor/neovim/nvim/lua/plugins/autopairs.lua new file mode 100644 index 0000000..fc29859 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/autopairs.lua @@ -0,0 +1,26 @@ +M = { + check_ts = true, + ts_config = { + lua = { "string", "source" }, + javascript = { "string", "template_string" }, + }, + fast_wrap = { + map = '', + chars = { '{', '[', '(', '"', "'" }, + pattern = [=[[%'%"%)%>%]%)%}%,]]=], + end_key = '$', + keys = 'qwertyuiopzxcvbnmasdfghjkl', + check_comma = true, + highlight = 'Search', + highlight_grey='Comment' + }, +} + +local cmp_autopairs = require("nvim-autopairs.completion.cmp") +local ok, cmp = pcall(require, "cmp") +if ok then + cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done({ map_char = { tex = "" } })) +end + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/bufferline.lua b/modules/coding/editor/neovim/nvim/lua/plugins/bufferline.lua new file mode 100644 index 0000000..831b660 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/bufferline.lua @@ -0,0 +1,31 @@ +local buf_kill = require("core.globals").buf_kill + +M = { + highlights = { + buffer_selected = { + bold = true + } + }, + options = { + diagnostics = "nvim_lsp", + offsets = { + { + filetype = "NvimTree", + text = "File Explorer", + highlight = "Directory", + text_align = "center" + }, + }, + close_command = function (bufnr) + buf_kill("bd", bufnr, false) + end, + right_mouse_command = function (bufnr) + buf_kill("bd", bufnr, true) + end + } +} + +vim.opt.termguicolors = true + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/cmp/cmp.lua b/modules/coding/editor/neovim/nvim/lua/plugins/cmp/cmp.lua new file mode 100644 index 0000000..ffbc7f4 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/cmp/cmp.lua @@ -0,0 +1,68 @@ +local cmp = require("cmp") + +M = { + window = { + completion = { + border = 'rounded', + scrollbar = '║', + }, + documentation = { + border = 'rounded', + scrollbar = '║', + }, + }, + formatting = { + format = require('lspkind').cmp_format({ + mode = "symbol", + maxwidth = 50, + ellipsis_char = '...', + symbol_map = { Codeium = "", } + }) + }, + snippet = { + expand = function(args) + require("luasnip").lsp_expand(args.body) + end, + }, + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + [""] = cmp.mapping.abort(), + [""] = cmp.mapping.confirm({ select = true }), + [""] = cmp.mapping(function (fallback) + if cmp.visible() then + cmp.select_prev_item() + else + fallback() + end + end, { + "i", + "s" + }), + [""] = cmp.mapping(function (fallback) + if cmp.visible() then + cmp.select_next_item() + else + fallback() + end + end, { + "i", + "s" + }), + }), + sources = cmp.config.sources({ + { name = "nvim_lsp" }, + { name = "luasnip" }, + -- { name = "codeium" }, + { name = "path" }, + }, { + { name = "buffer" }, + }) + +} + +vim.o.wildmenu = true +vim.o.pumheight = 10 + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/cmp/luasnip.lua b/modules/coding/editor/neovim/nvim/lua/plugins/cmp/luasnip.lua new file mode 100644 index 0000000..622bae4 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/cmp/luasnip.lua @@ -0,0 +1,34 @@ +M = { + sources = { + friendly_snippets = true + }, + history = true, + updateevents = { "TextChanged", "TextChangedI" } +} + +-- vscode format +require("luasnip.loaders.from_vscode").lazy_load() +require("luasnip.loaders.from_vscode").lazy_load { paths = vim.g.vscode_snippets_path or "" } + +-- snipmate format +require("luasnip.loaders.from_snipmate").load() +require("luasnip.loaders.from_snipmate").lazy_load { paths = vim.g.snipmate_snippets_path or "" } + +-- lua format +require("luasnip.loaders.from_lua").load() +require("luasnip.loaders.from_lua").lazy_load { paths = vim.g.lua_snippets_path or "" } + +local luasnip = require("luasnip") +vim.api.nvim_create_autocmd("InsertLeave", { + callback = function() + if + luasnip.session.current_nodes[vim.api.nvim_get_current_buf()] + and not luasnip.session.jump_active + then + luasnip.unlink_current() + end + end, +}) + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/comment.lua b/modules/coding/editor/neovim/nvim/lua/plugins/comment.lua new file mode 100644 index 0000000..fbb6c5c --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/comment.lua @@ -0,0 +1,4 @@ +M = {} + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/floaterm.lua b/modules/coding/editor/neovim/nvim/lua/plugins/floaterm.lua new file mode 100644 index 0000000..87fa352 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/floaterm.lua @@ -0,0 +1,4 @@ +local keymap = vim.keymap +local opt = require("core.globals").keymap_opt + +keymap.set("n", "tt", ":FloatermNew", opt) diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/gitsigns.lua b/modules/coding/editor/neovim/nvim/lua/plugins/gitsigns.lua new file mode 100644 index 0000000..c9da38e --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/gitsigns.lua @@ -0,0 +1,19 @@ +M = { + signs = { + add = { text = '▎', color = "green" }, + change = { text = '▎', color = "blue" }, + delete = { text = '_' }, + topdelete = { text = '‾' }, + changedelete = { text = '~' }, + }, + current_line_blame = true, + current_line_blame_opts = { + virt_text = true, + virt_text_pos = 'eol', + delay = 0, + ignore_whitespace = false, + }, +} + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/indent-blankline.lua b/modules/coding/editor/neovim/nvim/lua/plugins/indent-blankline.lua new file mode 100644 index 0000000..32bdbde --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/indent-blankline.lua @@ -0,0 +1,15 @@ +M = { + enabled = true, + indent = { + tab_char = "▎" + }, + scope = { + enabled = true, + show_start = false, + } +} + +vim.opt.list = true + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/lsp/fidget.lua b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/fidget.lua new file mode 100644 index 0000000..fbb6c5c --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/fidget.lua @@ -0,0 +1,4 @@ +M = {} + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/lsp/lspconfig.lua b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/lspconfig.lua new file mode 100644 index 0000000..8fedd8e --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/lspconfig.lua @@ -0,0 +1,88 @@ +local servers = { + "lua_ls", + "pyright", + "gopls", + "clangd", + "rust_analyzer", + "ts_ls", + "jsonls", + "cssls", + "nil_ls", + "html", +} + +local extra_config = { + lua_ls = { + settings = { + Lua = { + workspace = { + library = { + vim.api.nvim_get_runtime_file("", true), + "${3rd}/luv/library", + "${3rd}/luassert/library", + } + }, + diagnostics = { + globals = { + "vim" + } + }, + completion = { + callSnippet = "Replace" + } + } + }, + }, + rust_analyzer = { + settings = { + rust_analyzer = { + check = { + command = "clippy" + }, + formatting = { + command = { "rustfmt" }, + }, + } + }, + }, +} + +local on_attach = function(client, bufnr) + vim.api.nvim_create_autocmd("CursorHold", { + buffer = bufnr, + callback = function() + local opts = { + focusable = false, + close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" }, + border = "rounded", + source = "always", + prefix = " ", + scope = "line", + } + vim.diagnostic.open_float(nil, opts) + end, + }) +end +local capabilities = require("cmp_nvim_lsp").default_capabilities() +capabilities = vim.lsp.protocol.make_client_capabilities() +capabilities.textDocument.foldingRange = { + dynamicRegistration = false, + lineFoldingOnly = true, +} +local lspconfig = require("lspconfig") +for _, server in ipairs(servers) do + local extra = extra_config[server] or {} + local config = { + on_attach = on_attach, + capabilities = capabilities + } + for k, v in pairs(extra) do + config[k] = v + end + lspconfig[server].setup(config) +end + +vim.diagnostic.config({ + virtual_lines = true +}) + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/lsp/mason-lspconfig.lua b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/mason-lspconfig.lua new file mode 100644 index 0000000..60fc320 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/mason-lspconfig.lua @@ -0,0 +1,7 @@ +M = { + -- ensure_installed = require("plugins.lsp.servers") + ensure_installed = {} +} + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/lsp/mason.lua b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/mason.lua new file mode 100644 index 0000000..fe68018 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/mason.lua @@ -0,0 +1,12 @@ +M = { + ui = { + icons = { + package_installed = "✓", + package_pending = "➜", + package_uninstalled = "✗" + } + } +} + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/lsp/others.lua b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/others.lua new file mode 100644 index 0000000..31d18f5 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/others.lua @@ -0,0 +1,29 @@ +-- Keymaps +local opt = require("core.globals").keymap_opt + +vim.keymap.set("n", "K", vim.lsp.buf.hover, opt) +vim.keymap.set("n", "lR", vim.lsp.buf.rename, opt) + +vim.diagnostic.config({ + virtual_text = { spacing = 4, prefix = "●" }, + signs = true, + underline = true, + update_in_insert = true, + severity_sort = true, +}) + +local signs = { Error = " ", Warn = " ", Hint = " ", Info = " " } +for type, icon in pairs(signs) do + local hl = "DiagnosticSign" .. type + vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl }) +end + +vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { + border = "single", +}) +--[[ vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, { + border = "single", + focusable = false, + relative = "cursor", +}) ]] + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/lsp/outline.lua b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/outline.lua new file mode 100644 index 0000000..1e0ee6e --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/outline.lua @@ -0,0 +1,6 @@ +M = {} + +vim.keymap.set("n", "o", "Outline", +{ desc = "Toggle Outline" }) + +return M diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/lsp/servers.lua b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/servers.lua new file mode 100644 index 0000000..e3378d3 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/servers.lua @@ -0,0 +1,15 @@ +M = { + "lua_ls", + "pyright", + "gopls", + "clangd", + "rust_analyzer", + "ts_ls", + "jsonls", + "cssls", + "nil_ls", + "html", +} + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/lsp/signature.lua b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/signature.lua new file mode 100644 index 0000000..4212231 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/lsp/signature.lua @@ -0,0 +1,16 @@ +M = { + bind = true, -- This is mandatory, otherwise border config won't get registered. + handler_opts = { + border = "rounded" + }, + hint_prefix = "^ ", + toggle_key = "", +} + +vim.keymap.set({ 'n' }, 'k', require('lsp_signature').toggle_float_win, + { silent = true, noremap = true, desc = 'toggle signature' }) + +vim.keymap.set({ 'n' }, 'K', vim.lsp.buf.signature_help, + { silent = true, noremap = true, desc = 'toggle signature' }) + +return M diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/lualine.lua b/modules/coding/editor/neovim/nvim/lua/plugins/lualine.lua new file mode 100644 index 0000000..abba20e --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/lualine.lua @@ -0,0 +1,28 @@ +M = { + options = { + theme = "tokyonight" + }, + sections = { + lualine_y = { + 'encoding', 'fileformat', 'filetype', + }, + lualine_x = { + { + require("noice").api.status.message.get_hl, + cond = require("noice").api.status.message.has, + }, + { + require("noice").api.status.command.get, + cond = require("noice").api.status.command.has, + color = { fg = "#ff9e64" }, + }, + { + require("noice").api.status.search.get, + cond = require("noice").api.status.search.has, + color = { fg = "#ff9e64" }, + }, + }, + }, +} + +return M diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/markdown-preview.lua b/modules/coding/editor/neovim/nvim/lua/plugins/markdown-preview.lua new file mode 100644 index 0000000..bb20239 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/markdown-preview.lua @@ -0,0 +1,31 @@ +M = {} + +vim.api.nvim_create_augroup("MarkdownPreviewAuto", {}) + +vim.api.nvim_create_user_command("MarkdownPreviewAutoEnable", function() + vim.api.nvim_create_autocmd("BufEnter", { + group = "MarkdownPreviewAuto", + pattern = { "*.md" }, + desc = "Auto enable MarkdownPreview", + callback = function() + vim.cmd("MarkdownPreview") + end, + }) + vim.api.nvim_create_autocmd("BufLeave", { + group = "MarkdownPreviewAuto", + pattern = { "*.md" }, + desc = "Auto disable MarkdownPreview", + callback = function() + vim.cmd("MarkdownPreviewStop") + end, + }) +end, { desc = "Auto enable MarkdownPreview" }) + +vim.api.nvim_create_user_command("MarkdownPreviewAutoDisable", + function() + vim.api.nvim_clear_autocmds({ group = "MarkdownPreviewAuto" }) + end, {} +) + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/neodev.lua b/modules/coding/editor/neovim/nvim/lua/plugins/neodev.lua new file mode 100644 index 0000000..fbb6c5c --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/neodev.lua @@ -0,0 +1,4 @@ +M = {} + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/nvim-tree.lua b/modules/coding/editor/neovim/nvim/lua/plugins/nvim-tree.lua new file mode 100644 index 0000000..e24c106 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/nvim-tree.lua @@ -0,0 +1,21 @@ +M = { + sync_root_with_cwd = true, + diagnostics = { + enable = false, + debounce_delay = 50, + show_on_dirs = true + }, + filters = { + git_ignored = false + } +} + +vim.g.loaded_netrw = 1 +vim.g.loaded_netrwPlugin = 1 + +local opt = require("core.globals").keymap_opt +vim.keymap.set("n", "e", ":NvimTreeToggle", opt) +vim.keymap.set("n", "te", ":NvimTreeFocus", opt) + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/plugins-setup.lua b/modules/coding/editor/neovim/nvim/lua/plugins/plugins-setup.lua new file mode 100644 index 0000000..1b2cc36 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/plugins-setup.lua @@ -0,0 +1,302 @@ +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not vim.loop.fs_stat(lazypath) then + vim.fn.system({ + "git", + "clone", + "--filter=blob:none", + "https://github.com/folke/lazy.nvim.git", + lazypath + }) +end +vim.opt.rtp:prepend(lazypath) +package.path = package.path .. ";" .. vim.fn.stdpath("config") .. "/lua/" + +local plugins = { + { + "folke/tokyonight.nvim", + lazy = false, + priority = 1000, + config = function() + vim.cmd.colorscheme("tokyonight-storm") + end + }, + { + "nvim-lualine/lualine.nvim", + lazy = false, + dependencies = { { "nvim-tree/nvim-web-devicons", lazy = true } }, + config = function() + require("lualine").setup(require("plugins.lualine")) + end + }, + { + "nvim-tree/nvim-tree.lua", + lazy = false, + dependencies = { { "nvim-tree/nvim-web-devicons", lazy = true } }, + config = function() + require("nvim-tree").setup(require("plugins.nvim-tree")) + end + }, + { + "nvim-treesitter/nvim-treesitter", + lazy = false, + event = "VeryLazy", + dependencies = { + "nvim-treesitter/nvim-treesitter-textobjects", + "nushell/tree-sitter-nu" + }, + config = function() + require("nvim-treesitter.configs").setup(require("plugins.treesitter")) + end, + build = ":TSUpdate" + }, + { + url = "https://gitlab.com/HiPhish/rainbow-delimiters.nvim", + lazy = false, + event = "VeryLazy", + config = function() + require("plugins.rainbow-delimiters") + end + }, + { + "lukas-reineke/indent-blankline.nvim", + lazy = false, + event = "VeryLazy", + config = function() + require("ibl").setup(require("plugins.indent-blankline")) + end + }, + { + "neovim/nvim-lspconfig", + dependencies = { "hrsh7th/cmp-nvim-lsp" }, + lazy = false, + config = function() + require("plugins.lsp.lspconfig") + require("plugins.lsp.others") + end + }, + { + "folke/trouble.nvim", + dependencies = { "nvim-tree/nvim-web-devicons" }, + cmd = "Trouble", + keys = { + { + "xx", + "Trouble diagnostics toggle", + desc = "Diagnostics (Trouble)", + }, + { + "xX", + "Trouble diagnostics toggle filter.buf=0", + desc = "Buffer Diagnostics (Trouble)", + }, + { + "cs", + "Trouble symbols toggle focus=false", + desc = "Symbols (Trouble)", + }, + { + "cl", + "Trouble lsp toggle focus=false win.position=right", + desc = "LSP Definitions / references / ... (Trouble)", + }, + { + "xL", + "Trouble loclist toggle", + desc = "Location List (Trouble)", + }, + { + "xQ", + "Trouble qflist toggle", + desc = "Quickfix List (Trouble)", + }, + }, + opts = {} + }, + { + "MysticalDevil/inlay-hints.nvim", + event = "LspAttach", + dependencies = { "neovim/nvim-lspconfig" }, + config = function() + require("inlay-hints").setup() + end + }, + { + "hedyhli/outline.nvim", + event = "LspAttach", + config = function() + require("outline").setup(require("plugins.lsp.outline")) + end, + }, + { + "L3MON4D3/LuaSnip", + lazy = false, + dependencies = { { "rafamadriz/friendly-snippets", lazy = true } }, + build = "make install_jsregexp", + config = function() + require("luasnip").setup(require("plugins.cmp.luasnip")) + end + }, + { + "hrsh7th/nvim-cmp", + dependencies = { + "hrsh7th/cmp-nvim-lsp", + "L3MON4D3/LuaSnip", + "saadparwaiz1/cmp_luasnip", + "rafamadriz/friendly-snippets", + "hrsh7th/cmp-path", + "onsails/lspkind.nvim" + }, + lazy = false, + config = function() + require("cmp").setup(require("plugins.cmp.cmp")) + end + }, + { + "numToStr/Comment.nvim", + lazy = false, + event = "VeryLazy", + config = function() + require("Comment").setup(require("plugins.comment")) + end + }, + { + "windwp/nvim-autopairs", + lazy = false, + event = "VeryLazy", + dependencies = { "hrsh7th/nvim-cmp" }, + config = function() + require("nvim-autopairs").setup(require("plugins.autopairs")) + end + }, + { + "akinsho/bufferline.nvim", + lazy = false, + config = function() + require("bufferline").setup(require("plugins.bufferline")) + end + }, + { + "lewis6991/gitsigns.nvim", + lazy = false, + event = "VeryLazy", + config = function() + require("gitsigns").setup(require("plugins.gitsigns")) + end + }, + { + "nvim-telescope/telescope.nvim", + tag = "0.1.2", + dependencies = { "nvim-lua/plenary.nvim", "BurntSushi/ripgrep" }, + config = function() + require("telescope").setup(require("plugins.telescope")) + end + }, + { + "alexghergh/nvim-tmux-navigation", + lazy = false, + event = "VeryLazy", + config = function() + require("nvim-tmux-navigation").setup(require("plugins.tmuxnav")) + end + }, + { + "natecraddock/sessions.nvim", + lazy = false, + event = "VeryLazy", + config = function() + require("sessions").setup(require("plugins.sessions")) + end + }, + { + "natecraddock/workspaces.nvim", + lazy = false, + event = "VeryLazy", + dependencies = { "nvim-telescope/telescope.nvim", "natecraddock/sessions.nvim" }, + config = function() + require("workspaces").setup(require("plugins.workspaces")) + require("telescope").load_extension("workspaces") + end + }, + --[[ { + "iamcco/markdown-preview.nvim", + cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop", "MarkdownPreviewAutoEnable", "MarkdownPreviewAutoDisable" }, + ft = { "markdown" }, + build = function() + vim.fn["mkdp#util#install"]() + end, + config = function() + require("plugins.markdown-preview") + end + }, ]] + --[[ { + "dhruvasagar/vim-table-mode", + lazy = true, + event = "BufEnter *.md", + config = function() + require("plugins.table-mode") + end + }, ]] + { + "lukas-reineke/headlines.nvim", + dependencies = "nvim-treesitter/nvim-treesitter", + config = true, -- or `opts = {}` + }, + { + "folke/noice.nvim", + lazy = false, + event = "VeryLazy", + dependencies = { + "MunifTanjim/nui.nvim", + "rcarriga/nvim-notify", + }, + opts = { + override = { + ["vim.lsp.util.convert_input_to_markdown_lines"] = true, + ["vim.lsp.util.stylize_markdown"] = true, + ["cmp.entry.get_documentation"] = true, + } + } + }, + { + "voldikss/vim-floaterm", + lazy = false, + event = "VeryLazy", + config = function() + require("plugins.floaterm") + end + }, + { + "folke/todo-comments.nvim", + lazy = false, + event = "VeryLazy", + opts = {}, + }, + { + "ojroques/nvim-osc52", + event = "BufEnter", + config = function() + require("osc52").setup({ + tmux_passthrough = true + }) + local function copy() + if vim.v.event.operator == "y" and vim.v.event.regname == "+" then + require("osc52").copy_register("+") + end + end + vim.api.nvim_create_autocmd("TextYankPost", {callback = copy}) + end + }, + { + "pest-parser/pest.vim", + event = "VeryLazy", + opts = {} + } +} + +local opts = { + rocks = { + enabled = false + } +} + +require("lazy").setup(plugins, opts) diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/rainbow-delimiters.lua b/modules/coding/editor/neovim/nvim/lua/plugins/rainbow-delimiters.lua new file mode 100644 index 0000000..dd801bf --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/rainbow-delimiters.lua @@ -0,0 +1,21 @@ +local rainbow_delimiters = require("rainbow-delimiters") +vim.g.rainbow_delimiters = { + strategy = { + [''] = rainbow_delimiters.strategy['global'], + vim = rainbow_delimiters.strategy['local'], + }, + query = { + [''] = 'rainbow-delimiters', + lua = 'rainbow-blocks', + }, + highlight = { + 'RainbowDelimiterRed', + 'RainbowDelimiterYellow', + 'RainbowDelimiterBlue', + 'RainbowDelimiterOrange', + 'RainbowDelimiterGreen', + 'RainbowDelimiterViolet', + 'RainbowDelimiterCyan', + }, +} + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/sessions.lua b/modules/coding/editor/neovim/nvim/lua/plugins/sessions.lua new file mode 100644 index 0000000..356b30e --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/sessions.lua @@ -0,0 +1,10 @@ +M = { + events = { "VimLeavePre" }, + indent = { + tab_char = "▏" + }, + session_filepath = vim.fn.stdpath("data") .. "/session", +} + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/table-mode.lua b/modules/coding/editor/neovim/nvim/lua/plugins/table-mode.lua new file mode 100644 index 0000000..889cd16 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/table-mode.lua @@ -0,0 +1,34 @@ +M = {} + +vim.g.table_mode_corner = "|" + +vim.api.nvim_create_augroup("TableModeAuto", {}) + +vim.api.nvim_create_user_command("TableModeAutoEnable", function() + vim.api.nvim_clear_autocmds({ group = "TableModeAuto" }) + vim.api.nvim_create_autocmd("BufEnter", { + group = "TableModeAuto", + pattern = { "*.md" }, + desc = "Auto enable TableMode", + callback = function() + vim.cmd("TableModeEnable") + end, + }) + vim.api.nvim_create_autocmd("BufWrite", { + group = "TableModeAuto", + pattern = { "*.md" }, + desc = "Auto enable TableMode", + callback = function() + vim.cmd("TableModeRealign") + end, + }) +end, { desc = "Auto enable TableMode" }) + +vim.api.nvim_create_user_command("TableModeAutoDisable", + function() + vim.api.nvim_clear_autocmds({ group = "TableModeAuto" }) + end, {} +) + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/telescope.lua b/modules/coding/editor/neovim/nvim/lua/plugins/telescope.lua new file mode 100644 index 0000000..07c3291 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/telescope.lua @@ -0,0 +1,45 @@ +M = { + defaults = { + winblend = 50, + path_display = { + "smart", + shorten = 3 + } + }, + pickers = { + lsp_definitions = { + theme = "cursor", + layout_config = { width = 0.6, height = 0.3}, + }, + lsp_references = { + theme = "cursor", + layout_config = { width = 0.6, height = 0.3 }, + }, + current_buffer_fuzzy_find = { + theme = "dropdown", + layout_config = { height = 0.7, width = 0.55, preview_cutoff = 0 ,prompt_position = "top" } + }, + lsp_document_symbols = { + theme = "ivy", + layout_config = { height = 0.25 } + } + }, +} + +local opt = require("core.globals").keymap_opt +local keymap = vim.keymap +local builtin = require('telescope.builtin') + +keymap.set('n', 'ff', builtin.find_files, opt) +keymap.set('n', 'gf', builtin.git_files, opt) +keymap.set('n', 'fg', builtin.live_grep, opt) +keymap.set('n', 'fb', builtin.buffers, opt) +keymap.set('n', 'fh', builtin.help_tags, opt) +-- keymap.set('n', 'lD', builtin.diagnostics, opt) +keymap.set('n', 'ld', builtin.lsp_definitions, opt) +keymap.set('n', 'lr', builtin.lsp_references, opt) +keymap.set('n', 'ls', builtin.lsp_document_symbols, opt) +keymap.set('n', '/', builtin.current_buffer_fuzzy_find, opt) + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/tmuxnav.lua b/modules/coding/editor/neovim/nvim/lua/plugins/tmuxnav.lua new file mode 100644 index 0000000..ae03443 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/tmuxnav.lua @@ -0,0 +1,14 @@ +M = {} + +local tmuxnav = require("nvim-tmux-navigation") +local keymap = vim.keymap + +keymap.set("n", "", tmuxnav.NvimTmuxNavigateLeft) +keymap.set("n", "", tmuxnav.NvimTmuxNavigateDown) +keymap.set("n", "", tmuxnav.NvimTmuxNavigateUp) +keymap.set("n", "", tmuxnav.NvimTmuxNavigateRight) +keymap.set("n", "", tmuxnav.NvimTmuxNavigateLastActive) +keymap.set("n", "", tmuxnav.NvimTmuxNavigateNext) + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/treesitter.lua b/modules/coding/editor/neovim/nvim/lua/plugins/treesitter.lua new file mode 100644 index 0000000..8820a90 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/treesitter.lua @@ -0,0 +1,20 @@ +M = { + auto_install = true, + parser_install_dir = "$HOME/.local/share/nvim/lazy/nvim-treesitter", + sync_install = true, + modules = {}, + ignore_install = {}, + + highlight = { enable = true }, + indent = { enable = true } +} + +vim.filetype.add({ + pattern = { + [".*/hypr/.*%.conf"] = "hyprlang", + [".*%.hl"] = "hyprlang" + }, +}) + +return M + diff --git a/modules/coding/editor/neovim/nvim/lua/plugins/workspaces.lua b/modules/coding/editor/neovim/nvim/lua/plugins/workspaces.lua new file mode 100644 index 0000000..8794f35 --- /dev/null +++ b/modules/coding/editor/neovim/nvim/lua/plugins/workspaces.lua @@ -0,0 +1,14 @@ +M = { + hooks = { + open = function () + require("core.globals").close_empty_buffer() + vim.cmd("enew") + vim.cmd("bufdo bd") + require("sessions").load(nil, { silent = true }) + vim.cmd("NvimTreeFocus") + end + }, +} + +return M + diff --git a/modules/coding/editor/vscode/default.nix b/modules/coding/editor/vscode/default.nix new file mode 100644 index 0000000..7c0daf6 --- /dev/null +++ b/modules/coding/editor/vscode/default.nix @@ -0,0 +1,30 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomeProgramConfig { + inherit config; + programName = "neovim"; + optionPath = [ + "coding" + "editor" + "vscode" + ]; + extraConfig = { + my.home = { + programs.vscode = { + enable = true; + package = pkgs.vscodium; + profiles.default = { + extensions = with pkgs.open-vsx; [ + eamodio.gitlens + rust-lang.rust-analyzer + dbaeumer.vscode-eslint + ]; + }; + }; + }; + }; +} diff --git a/modules/coding/github-cli-comp b/modules/coding/github-cli-comp new file mode 100644 index 0000000..41cf353 --- /dev/null +++ b/modules/coding/github-cli-comp @@ -0,0 +1,205 @@ +#compdef gh + +# zsh completion for gh -*- shell-script -*- + +__gh_debug() +{ + local file="$BASH_COMP_DEBUG_FILE" + if [[ -n ${file} ]]; then + echo "$*" >> "${file}" + fi +} + +_gh() +{ + local shellCompDirectiveError=1 + local shellCompDirectiveNoSpace=2 + local shellCompDirectiveNoFileComp=4 + local shellCompDirectiveFilterFileExt=8 + local shellCompDirectiveFilterDirs=16 + + local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace + local -a completions + + __gh_debug "\n========= starting completion logic ==========" + __gh_debug "CURRENT: ${CURRENT}, words[*]: ${words[*]}" + + # The user could have moved the cursor backwards on the command-line. + # We need to trigger completion from the $CURRENT location, so we need + # to truncate the command-line ($words) up to the $CURRENT location. + # (We cannot use $CURSOR as its value does not work when a command is an alias.) + words=("${=words[1,CURRENT]}") + __gh_debug "Truncated words[*]: ${words[*]}," + + lastParam=${words[-1]} + lastChar=${lastParam[-1]} + __gh_debug "lastParam: ${lastParam}, lastChar: ${lastChar}" + + # For zsh, when completing a flag with an = (e.g., gh -n=) + # completions must be prefixed with the flag + setopt local_options BASH_REMATCH + if [[ "${lastParam}" =~ '-.*=' ]]; then + # We are dealing with a flag with an = + flagPrefix="-P ${BASH_REMATCH}" + fi + + # Prepare the command to obtain completions + requestComp="${words[1]} __complete ${words[2,-1]}" + if [ "${lastChar}" = "" ]; then + # If the last parameter is complete (there is a space following it) + # We add an extra empty parameter so we can indicate this to the go completion code. + __gh_debug "Adding extra empty parameter" + requestComp="${requestComp} \"\"" + fi + + __gh_debug "About to call: eval ${requestComp}" + + # Use eval to handle any environment variables and such + out=$(eval ${requestComp} 2>/dev/null) + __gh_debug "completion output: ${out}" + + # Extract the directive integer following a : from the last line + local lastLine + while IFS='\n' read -r line; do + lastLine=${line} + done < <(printf "%s\n" "${out[@]}") + __gh_debug "last line: ${lastLine}" + + if [ "${lastLine[1]}" = : ]; then + directive=${lastLine[2,-1]} + # Remove the directive including the : and the newline + local suffix + (( suffix=${#lastLine}+2)) + out=${out[1,-$suffix]} + else + # There is no directive specified. Leave $out as is. + __gh_debug "No directive found. Setting do default" + directive=0 + fi + + __gh_debug "directive: ${directive}" + __gh_debug "completions: ${out}" + __gh_debug "flagPrefix: ${flagPrefix}" + + if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then + __gh_debug "Completion received error. Ignoring completions." + return + fi + + local activeHelpMarker="_activeHelp_ " + local endIndex=${#activeHelpMarker} + local startIndex=$((${#activeHelpMarker}+1)) + local hasActiveHelp=0 + while IFS='\n' read -r comp; do + # Check if this is an activeHelp statement (i.e., prefixed with $activeHelpMarker) + if [ "${comp[1,$endIndex]}" = "$activeHelpMarker" ];then + __gh_debug "ActiveHelp found: $comp" + comp="${comp[$startIndex,-1]}" + if [ -n "$comp" ]; then + compadd -x "${comp}" + __gh_debug "ActiveHelp will need delimiter" + hasActiveHelp=1 + fi + + continue + fi + + if [ -n "$comp" ]; then + # If requested, completions are returned with a description. + # The description is preceded by a TAB character. + # For zsh's _describe, we need to use a : instead of a TAB. + # We first need to escape any : as part of the completion itself. + comp=${comp//:/\\:} + + local tab="$(printf '\t')" + comp=${comp//$tab/:} + + __gh_debug "Adding completion: ${comp}" + completions+=${comp} + lastComp=$comp + fi + done < <(printf "%s\n" "${out[@]}") + + # Add a delimiter after the activeHelp statements, but only if: + # - there are completions following the activeHelp statements, or + # - file completion will be performed (so there will be choices after the activeHelp) + if [ $hasActiveHelp -eq 1 ]; then + if [ ${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then + __gh_debug "Adding activeHelp delimiter" + compadd -x "--" + hasActiveHelp=0 + fi + fi + + if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then + __gh_debug "Activating nospace." + noSpace="-S ''" + fi + + if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then + # File extension filtering + local filteringCmd + filteringCmd='_files' + for filter in ${completions[@]}; do + if [ ${filter[1]} != '*' ]; then + # zsh requires a glob pattern to do file filtering + filter="\*.$filter" + fi + filteringCmd+=" -g $filter" + done + filteringCmd+=" ${flagPrefix}" + + __gh_debug "File filtering command: $filteringCmd" + _arguments '*:filename:'"$filteringCmd" + elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then + # File completion for directories only + local subdir + subdir="${completions[1]}" + if [ -n "$subdir" ]; then + __gh_debug "Listing directories in $subdir" + pushd "${subdir}" >/dev/null 2>&1 + else + __gh_debug "Listing directories in ." + fi + + local result + _arguments '*:dirname:_files -/'" ${flagPrefix}" + result=$? + if [ -n "$subdir" ]; then + popd >/dev/null 2>&1 + fi + return $result + else + __gh_debug "Calling _describe" + if eval _describe "completions" completions $flagPrefix $noSpace; then + __gh_debug "_describe found some completions" + + # Return the success of having called _describe + return 0 + else + __gh_debug "_describe did not find completions." + __gh_debug "Checking if we should do file completion." + if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then + __gh_debug "deactivating file completion" + + # We must return an error code here to let zsh know that there were no + # completions found by _describe; this is what will trigger other + # matching algorithms to attempt to find completions. + # For example zsh can match letters in the middle of words. + return 1 + else + # Perform file completion + __gh_debug "Activating file completion" + + # We must return the result of this command, so it must be the + # last command, or else we must store its result to return it. + _arguments '*:filename:_files'" ${flagPrefix}" + fi + fi + fi +} + +# don't run the completion function when being source-ed or eval-ed +if [ "$funcstack[1]" = "_gh" ]; then + _gh +fi diff --git a/modules/coding/langs/all.nix b/modules/coding/langs/all.nix new file mode 100644 index 0000000..67f85f8 --- /dev/null +++ b/modules/coding/langs/all.nix @@ -0,0 +1,20 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all coding langs"; + optionPath = [ + "coding" + "langs" + "all" + ]; + config' = { + my.coding.langs = { + c.enable = true; + go.enable = true; + js.enable = true; + python.enable = true; + rust.enable = true; + lua.enable = true; + }; + }; +} diff --git a/modules/coding/langs/c.nix b/modules/coding/langs/c.nix new file mode 100644 index 0000000..26c7dc9 --- /dev/null +++ b/modules/coding/langs/c.nix @@ -0,0 +1,22 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "c"; + optionPath = [ + "coding" + "langs" + "c" + ]; + config' = { + my.home.home.packages = with pkgs; [ + gcc + clang-tools + cmake + ]; + }; +} diff --git a/modules/coding/langs/default.nix b/modules/coding/langs/default.nix new file mode 100644 index 0000000..faba363 --- /dev/null +++ b/modules/coding/langs/default.nix @@ -0,0 +1,12 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./c.nix + ./go.nix + ./js.nix + ./rust.nix + ./python.nix + ./lua.nix + ]; +} diff --git a/modules/coding/langs/go.nix b/modules/coding/langs/go.nix new file mode 100644 index 0000000..3331e85 --- /dev/null +++ b/modules/coding/langs/go.nix @@ -0,0 +1,21 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "go"; + packagePath = [ "go" ]; + optionPath = [ + "coding" + "langs" + "go" + ]; + extraConfig = { + my.persist.homeDirs = [ + "go" + ]; + }; +} diff --git a/modules/coding/langs/js.nix b/modules/coding/langs/js.nix new file mode 100644 index 0000000..7e06d1e --- /dev/null +++ b/modules/coding/langs/js.nix @@ -0,0 +1,33 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "js"; + optionPath = [ + "coding" + "langs" + "js" + ]; + config' = { + my.home = { + home.packages = with pkgs; [ + nodejs + nodePackages.npm + + typescript + ]; + home.file.".npmrc".text = '' + prefix = ''${HOME}/.npm-global + registry = https://registry.npmmirror.com + ''; + }; + my.persist.homeDirs = [ + ".npm" + ".npm-global" + ]; + }; +} diff --git a/modules/coding/langs/lua.nix b/modules/coding/langs/lua.nix new file mode 100644 index 0000000..e75fac1 --- /dev/null +++ b/modules/coding/langs/lua.nix @@ -0,0 +1,20 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "lua"; + optionPath = [ + "coding" + "langs" + "lua" + ]; + config' = { + my.home.home.packages = with pkgs; [ + luajit + ]; + }; +} diff --git a/modules/coding/langs/python.nix b/modules/coding/langs/python.nix new file mode 100644 index 0000000..c2b2467 --- /dev/null +++ b/modules/coding/langs/python.nix @@ -0,0 +1,21 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "python3"; + packagePath = [ "python3" ]; + optionPath = [ + "coding" + "langs" + "python" + ]; + extraConfig = { + my.home.home.packages = with pkgs; [ + uv + ]; + }; +} diff --git a/modules/coding/langs/rust.nix b/modules/coding/langs/rust.nix new file mode 100644 index 0000000..c65e1e3 --- /dev/null +++ b/modules/coding/langs/rust.nix @@ -0,0 +1,42 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "rust"; + optionPath = [ + "coding" + "langs" + "rust" + ]; + config' = { + my.home = { + home.packages = with pkgs; [ + (fenix.stable.withComponents [ + "cargo" + "clippy" + "rust-src" + "rustc" + "rustfmt" + ]) + evcxr # rust repl + ]; + home.file.".cargo/config.toml".text = '' + [source.crates-io] + replace-with = 'rsproxy-sparse' + + [source.rsproxy-sparse] + registry = "sparse+https://rsproxy.cn/index/" + + [net] + git-fetch-with-cli = true + ''; + }; + my.persist.homeDirs = [ + ".cargo" + ]; + }; +} diff --git a/modules/coding/misc.nix b/modules/coding/misc.nix new file mode 100644 index 0000000..c4e0ffb --- /dev/null +++ b/modules/coding/misc.nix @@ -0,0 +1,29 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "misc"; + optionPath = [ + "coding" + "misc" + ]; + config' = { + my.home = { + home.packages = with pkgs; [ + gnumake + github-cli # gh + ]; + programs.zsh.initExtraFirst = '' + source ${./github-cli-comp} + ''; + programs.direnv.enable = true; + }; + my.persist.homeDirs = [ + ".local/share/direnv" + ]; + }; +} diff --git a/modules/default.nix b/modules/default.nix new file mode 100644 index 0000000..b89ec06 --- /dev/null +++ b/modules/default.nix @@ -0,0 +1,24 @@ +{ + lib, + username, + ... +}: +{ + imports = [ + ./cmd + ./coding + ./virt + ./desktop + ./i18n + ./nix.nix + ./sops.nix + ./gpg.nix + ./time.nix + ./user.nix + ./xdg.nix + ./persist.nix + ./getty-autologin.nix + + (lib.mkAliasOptionModule [ "my" "home" ] [ "home-manager" "users" username ]) + ]; +} diff --git a/modules/desktop/all.nix b/modules/desktop/all.nix new file mode 100644 index 0000000..27228f3 --- /dev/null +++ b/modules/desktop/all.nix @@ -0,0 +1,22 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all desktop things"; + optionPath = [ + "desktop" + "all" + ]; + config' = { + my.desktop = { + browser.all.enable = true; + gaming.all.enable = true; + media.all.enable = true; + notify.all.enable = true; + screencast.all.enable = true; + terminal.all.enable = true; + wm.all.enable = true; + style.enable = true; + quickshell.enable = true; + }; + }; +} diff --git a/modules/desktop/browser/all.nix b/modules/desktop/browser/all.nix new file mode 100644 index 0000000..642207b --- /dev/null +++ b/modules/desktop/browser/all.nix @@ -0,0 +1,17 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all desktop browsers"; + optionPath = [ + "desktop" + "browser" + "all" + ]; + config' = { + my.desktop.browser = { + firefox.enable = true; + librewolf.enable = true; + chromium.enable = true; + }; + }; +} diff --git a/modules/desktop/browser/chromium.nix b/modules/desktop/browser/chromium.nix new file mode 100644 index 0000000..dda3a5a --- /dev/null +++ b/modules/desktop/browser/chromium.nix @@ -0,0 +1,54 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomeProgramConfig { + inherit config; + programName = "chromium"; + optionPath = [ + "desktop" + "browser" + "chromium" + ]; + extraConfig = { + my.home.programs.chromium = { + package = pkgs.ungoogled-chromium; + extensions = [ + { + id = "jokpcbcafcbkjgcbjdcbadhfhimkafab"; # BitWarden + } + { + id = "ipgcaebkhediiaeinmmaneoehfjpjkle"; # Dark Reader + } + { + id = "leehfofbonhkmfimcelojmjnccdfemhl"; # New Tab + } + { + id = "padekgcemlokbadohgkifijomclgjgif"; # SwitchyOmega + } + { + id = "bgnkhhnnamicmpeenaelnjfhikgbkllg"; # AdGuard + } + { + id = "ocaahdebbfolfmndjeplogmgcagdmblk"; # Web Store + } + { + id = "pinabllndpmfdcknifcfcmdgdngjcfii"; # Firefox Dark Theme + } + { + id = "bpoadfkcbjbfhfodiogcnhhhpibjhbnh"; # Immersive Translate + } + { + id = "fnaicdffflnofjppbagibeoednhnbjhg"; # Floccus Bookmarks Sync + } + ]; + commandLineArgs = [ + "--ozone-platform=wayland" + "--enable-wayland-ime" + "--wayland-text-input-version=3" + ]; + }; + }; +} diff --git a/modules/desktop/browser/default.nix b/modules/desktop/browser/default.nix new file mode 100644 index 0000000..268b87b --- /dev/null +++ b/modules/desktop/browser/default.nix @@ -0,0 +1,9 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./firefox.nix + ./librewolf.nix + ./chromium.nix + ]; +} diff --git a/modules/desktop/browser/firefox.nix b/modules/desktop/browser/firefox.nix new file mode 100644 index 0000000..776f043 --- /dev/null +++ b/modules/desktop/browser/firefox.nix @@ -0,0 +1,15 @@ +{ config, lib, ... }: +lib.my.makeHomeProgramConfig { + inherit config; + programName = "firefox"; + optionPath = [ + "desktop" + "browser" + "firefox" + ]; + extraConfig = { + my.persist.homeDirs = [ + ".mozilla" + ]; + }; +} diff --git a/modules/desktop/browser/librewolf.nix b/modules/desktop/browser/librewolf.nix new file mode 100644 index 0000000..4d176d7 --- /dev/null +++ b/modules/desktop/browser/librewolf.nix @@ -0,0 +1,15 @@ +{ config, lib, ... }: +lib.my.makeHomeProgramConfig { + inherit config; + programName = "librewolf"; + optionPath = [ + "desktop" + "browser" + "librewolf" + ]; + extraConfig = { + my.persist.homeDirs = [ + ".librewolf" + ]; + }; +} diff --git a/modules/desktop/default.nix b/modules/desktop/default.nix new file mode 100644 index 0000000..8ef2c5f --- /dev/null +++ b/modules/desktop/default.nix @@ -0,0 +1,15 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./browser + ./gaming + ./media + ./notify + ./screencast + ./terminal + ./wm + ./style + ./quickshell + ]; +} diff --git a/modules/desktop/gaming/all.nix b/modules/desktop/gaming/all.nix new file mode 100644 index 0000000..59497e0 --- /dev/null +++ b/modules/desktop/gaming/all.nix @@ -0,0 +1,16 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all desktop gaming things"; + optionPath = [ + "desktop" + "gaming" + "all" + ]; + config' = { + my.desktop.gaming = { + minecraft.enable = true; + steam.enable = true; + }; + }; +} diff --git a/modules/desktop/gaming/default.nix b/modules/desktop/gaming/default.nix new file mode 100644 index 0000000..e0c4c9c --- /dev/null +++ b/modules/desktop/gaming/default.nix @@ -0,0 +1,8 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./minecraft.nix + ./steam.nix + ]; +} diff --git a/modules/desktop/gaming/minecraft.nix b/modules/desktop/gaming/minecraft.nix new file mode 100644 index 0000000..283527f --- /dev/null +++ b/modules/desktop/gaming/minecraft.nix @@ -0,0 +1,27 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "minecraft"; + optionPath = [ + "desktop" + "gaming" + "minecraft" + ]; + config' = { + my.home.home.packages = with pkgs; [ + hmcl + + openjdk21 + ]; + + my.persist.homeDirs = [ + ".minecraft" + ".local/share/hmcl" + ]; + }; +} diff --git a/modules/desktop/gaming/steam.nix b/modules/desktop/gaming/steam.nix new file mode 100644 index 0000000..28e938b --- /dev/null +++ b/modules/desktop/gaming/steam.nix @@ -0,0 +1,24 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "steam"; + optionPath = [ + "desktop" + "gaming" + "steam" + ]; + config' = { + programs.steam = { + enable = true; + package = pkgs.steam; + extraPackages = with pkgs; [ + gamescope + ]; + }; + }; +} diff --git a/modules/desktop/media/all.nix b/modules/desktop/media/all.nix new file mode 100644 index 0000000..be3d811 --- /dev/null +++ b/modules/desktop/media/all.nix @@ -0,0 +1,20 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all desktop media things"; + optionPath = [ + "desktop" + "media" + "all" + ]; + config' = { + my.desktop.media = { + mpv.enable = true; + shotwell.enable = true; + thunderbird.enable = true; + vlc.enable = true; + spotify.enable = true; + spotube.enable = true; + }; + }; +} diff --git a/modules/desktop/media/default.nix b/modules/desktop/media/default.nix new file mode 100644 index 0000000..5f62eb6 --- /dev/null +++ b/modules/desktop/media/default.nix @@ -0,0 +1,12 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./mpv.nix + ./shotwell.nix + ./thunderbird.nix + ./vlc.nix + ./spotify.nix + ./spotube.nix + ]; +} diff --git a/modules/desktop/media/mpv.nix b/modules/desktop/media/mpv.nix new file mode 100644 index 0000000..fca479c --- /dev/null +++ b/modules/desktop/media/mpv.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "mpv"; + packagePath = [ "mpv" ]; + optionPath = [ + "desktop" + "media" + "mpv" + ]; +} diff --git a/modules/desktop/media/shotwell.nix b/modules/desktop/media/shotwell.nix new file mode 100644 index 0000000..5eac01b --- /dev/null +++ b/modules/desktop/media/shotwell.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "shotwell"; + packagePath = [ "shotwell" ]; + optionPath = [ + "desktop" + "media" + "shotwell" + ]; +} diff --git a/modules/desktop/media/spotify.nix b/modules/desktop/media/spotify.nix new file mode 100644 index 0000000..d6b57d5 --- /dev/null +++ b/modules/desktop/media/spotify.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "spotify"; + packagePath = [ "spotify" ]; + optionPath = [ + "desktop" + "media" + "spotify" + ]; +} diff --git a/modules/desktop/media/spotube.nix b/modules/desktop/media/spotube.nix new file mode 100644 index 0000000..c418857 --- /dev/null +++ b/modules/desktop/media/spotube.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "spotube"; + packagePath = [ "spotube" ]; + optionPath = [ + "desktop" + "media" + "spotube" + ]; +} diff --git a/modules/desktop/media/thunderbird.nix b/modules/desktop/media/thunderbird.nix new file mode 100644 index 0000000..4d0c496 --- /dev/null +++ b/modules/desktop/media/thunderbird.nix @@ -0,0 +1,21 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "thunderbird"; + packagePath = [ "thunderbird" ]; + optionPath = [ + "desktop" + "media" + "thunderbird" + ]; + extraConfig = { + my.persist.homeDirs = [ + ".thunderbird" + ]; + }; +} diff --git a/modules/desktop/media/vlc.nix b/modules/desktop/media/vlc.nix new file mode 100644 index 0000000..958a2b4 --- /dev/null +++ b/modules/desktop/media/vlc.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "vlc"; + packagePath = [ "vlc" ]; + optionPath = [ + "desktop" + "media" + "vlc" + ]; +} diff --git a/modules/desktop/notify/all.nix b/modules/desktop/notify/all.nix new file mode 100644 index 0000000..78eea79 --- /dev/null +++ b/modules/desktop/notify/all.nix @@ -0,0 +1,16 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all desktop notify tools"; + optionPath = [ + "desktop" + "notify" + "all" + ]; + config' = { + my.desktop.notify = { + dunst.enable = true; + swaync.enable = true; + }; + }; +} diff --git a/modules/desktop/notify/default.nix b/modules/desktop/notify/default.nix new file mode 100644 index 0000000..a978a92 --- /dev/null +++ b/modules/desktop/notify/default.nix @@ -0,0 +1,8 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./dunst + ./swaync + ]; +} diff --git a/modules/desktop/notify/dunst/default.nix b/modules/desktop/notify/dunst/default.nix new file mode 100644 index 0000000..8a40fd6 --- /dev/null +++ b/modules/desktop/notify/dunst/default.nix @@ -0,0 +1,19 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "dunst"; + packagePath = [ "dunst" ]; + optionPath = [ + "desktop" + "notify" + "dunst" + ]; + extraConfig = { + my.home.xdg.configFile."dunst/dunstrc".source = ./dunstrc; + }; +} diff --git a/modules/desktop/notify/dunst/dunstrc b/modules/desktop/notify/dunst/dunstrc new file mode 100644 index 0000000..715870e --- /dev/null +++ b/modules/desktop/notify/dunst/dunstrc @@ -0,0 +1,459 @@ +# See dunst(5) for all configuration options + +[global] + ### Display ### + + # Which monitor should the notifications be displayed on. + monitor = 0 + + # Display notification on focused monitor. Possible modes are: + # mouse: follow mouse pointer + # keyboard: follow window with keyboard focus + # none: don't follow anything + # + # "keyboard" needs a window manager that exports the + # _NET_ACTIVE_WINDOW property. + # This should be the case for almost all modern window managers. + # + # If this option is set to mouse or keyboard, the monitor option + # will be ignored. + follow = mouse + + ### Geometry ### + + # dynamic width from 0 to 300 + # width = (0, 300) + # constant width of 300 + width = 300 + + # The maximum height of a single notification, excluding the frame. + height = 300 + + # Position the notification in the top right corner + origin = top-right + + # Offset from the origin + offset = 5x15 + + # Scale factor. It is auto-detected if value is 0. + scale = 0 + + # Maximum number of notification (0 means no limit) + notification_limit = 20 + + ### Progress bar ### + + # Turn on the progess bar. It appears when a progress hint is passed with + # for example dunstify -h int:value:12 + progress_bar = true + + # Set the progress bar height. This includes the frame, so make sure + # it's at least twice as big as the frame width. + progress_bar_height = 10 + + # Set the frame width of the progress bar + progress_bar_frame_width = 1 + + # Set the minimum width for the progress bar + progress_bar_min_width = 150 + + # Set the maximum width for the progress bar + progress_bar_max_width = 300 + + # Corner radius for the progress bar. 0 disables rounded corners. + progress_bar_corner_radius = 2 + + # Corner radius for the icon image. + icon_corner_radius = 0 + + # Show how many messages are currently hidden (because of + # notification_limit). + indicate_hidden = yes + + # The transparency of the window. Range: [0; 100]. + # This option will only work if a compositing window manager is + # present (e.g. xcompmgr, compiz, etc.). (X11 only) + transparency = 0 + + # Draw a line of "separator_height" pixel height between two + # notifications. + # Set to 0 to disable. + # If gap_size is greater than 0, this setting will be ignored. + separator_height = 2 + + # Padding between text and separator. + padding = 8 + + # Horizontal padding. + horizontal_padding = 8 + + # Padding between text and icon. + text_icon_padding = 0 + + # Defines width in pixels of frame around the notification window. + # Set to 0 to disable. + frame_width = 3 + + # Defines color of the frame around the notification window. + frame_color = "#2A2C36" + + # Size of gap to display between notifications - requires a compositor. + # If value is greater than 0, separator_height will be ignored and a border + # of size frame_width will be drawn around each notification instead. + # Click events on gaps do not currently propagate to applications below. + gap_size = 4 + + # Define a color for the separator. + # possible values are: + # * auto: dunst tries to find a color fitting to the background; + # * foreground: use the same color as the foreground; + # * frame: use the same color as the frame; + # * anything else will be interpreted as a X color. + separator_color = frame + + # Sort messages by urgency. + sort = yes + + # Don't remove messages, if the user is idle (no mouse or keyboard input) + # for longer than idle_threshold seconds. + # Set to 0 to disable. + # A client can set the 'transient' hint to bypass this. See the rules + # section for how to disable this if necessary + # idle_threshold = 120 + + ### Text ### + + font = JetBrains Mono 11 + + # The spacing between lines. If the height is smaller than the + # font height, it will get raised to the font height. + line_height = 0 + + # Possible values are: + # full: Allow a small subset of html markup in notifications: + # bold + # italic + # strikethrough + # underline + # + # For a complete reference see + # . + # + # strip: This setting is provided for compatibility with some broken + # clients that send markup even though it's not enabled on the + # server. Dunst will try to strip the markup but the parsing is + # simplistic so using this option outside of matching rules for + # specific applications *IS GREATLY DISCOURAGED*. + # + # no: Disable markup parsing, incoming notifications will be treated as + # plain text. Dunst will not advertise that it has the body-markup + # capability if this is set as a global setting. + # + # It's important to note that markup inside the format option will be parsed + # regardless of what this is set to. + markup = full + + # The format of the message. Possible variables are: + # %a appname + # %s summary + # %b body + # %i iconname (including its path) + # %I iconname (without its path) + # %p progress value if set ([ 0%] to [100%]) or nothing + # %n progress value if set without any extra characters + # %% Literal % + # Markup is allowed + format = "%s\n%b" + + # Alignment of message text. + # Possible values are "left", "center" and "right". + alignment = left + + # Vertical alignment of message text and icon. + # Possible values are "top", "center" and "bottom". + vertical_alignment = center + + # Show age of message if message is older than show_age_threshold + # seconds. + # Set to -1 to disable. + show_age_threshold = 60 + + # Specify where to make an ellipsis in long lines. + # Possible values are "start", "middle" and "end". + ellipsize = middle + + # Ignore newlines '\n' in notifications. + ignore_newline = no + + # Stack together notifications with the same content + stack_duplicates = true + + # Hide the count of stacked notifications with the same content + hide_duplicate_count = false + + # Display indicators for URLs (U) and actions (A). + show_indicators = false + + ### Icons ### + + # Recursive icon lookup. You can set a single theme, instead of having to + # define all lookup paths. + enable_recursive_icon_lookup = true + + # Set icon theme (only used for recursive icon lookup) + icon_theme = Win11, breeze + # You can also set multiple icon themes, with the leftmost one being used first. + # icon_theme = "Adwaita, breeze" + + # Align icons left/right/top/off + icon_position = left + + # Scale small icons up to this size, set to 0 to disable. Helpful + # for e.g. small files or high-dpi screens. In case of conflict, + # max_icon_size takes precedence over this. + min_icon_size = 32 + + # Scale larger icons down to this size, set to 0 to disable + max_icon_size = 32 + + # Paths to default icons (only neccesary when not using recursive icon lookup) + icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/ + + ### History ### + + # Should a notification popped up from history be sticky or timeout + # as if it would normally do. + sticky_history = yes + + # Maximum amount of notifications kept in history + history_length = 20 + + ### Misc/Advanced ### + + # dmenu path. + dmenu = /usr/bin/dmenu -p dunst: + + # Browser for opening urls in context menu. + browser = /usr/bin/microsoft-edge-stable + + # Always run rule-defined scripts, even if the notification is suppressed + always_run_script = true + + # Define the title of the windows spawned by dunst + title = Dunst + + # Define the class of the windows spawned by dunst + class = Dunst + + # Define the corner radius of the notification window + # in pixel size. If the radius is 0, you have no rounded + # corners. + # The radius will be automatically lowered if it exceeds half of the + # notification height to avoid clipping text and/or icons. + corner_radius = 10 + + # Ignore the dbus closeNotification message. + # Useful to enforce the timeout set by dunst configuration. Without this + # parameter, an application may close the notification sent before the + # user defined timeout. + ignore_dbusclose = false + + ### Wayland ### + # These settings are Wayland-specific. They have no effect when using X11 + + # Uncomment this if you want to let notications appear under fullscreen + # applications (default: overlay) + layer = top + + # Set this to true to use X11 output on Wayland. + force_xwayland = false + + ### Legacy + + # Use the Xinerama extension instead of RandR for multi-monitor support. + # This setting is provided for compatibility with older nVidia drivers that + # do not support RandR and using it on systems that support RandR is highly + # discouraged. + # + # By enabling this setting dunst will not be able to detect when a monitor + # is connected or disconnected which might break follow mode if the screen + # layout changes. + force_xinerama = false + + ### mouse + + # Defines list of actions for each mouse event + # Possible values are: + # * none: Don't do anything. + # * do_action: Invoke the action determined by the action_name rule. If there is no + # such action, open the context menu. + # * open_url: If the notification has exactly one url, open it. If there are multiple + # ones, open the context menu. + # * close_current: Close current notification. + # * close_all: Close all notifications. + # * context: Open context menu for the notification. + # * context_all: Open context menu for all notifications. + # These values can be strung together for each mouse event, and + # will be executed in sequence. + mouse_left_click = do_action, close_current + mouse_middle_click = close_all + mouse_right_click = close_current + +# Experimental features that may or may not work correctly. Do not expect them +# to have a consistent behaviour across releases. +[experimental] + # Calculate the dpi to use on a per-monitor basis. + # If this setting is enabled the Xft.dpi value will be ignored and instead + # dunst will attempt to calculate an appropriate dpi value for each monitor + # using the resolution and physical size. This might be useful in setups + # where there are multiple screens with very different dpi values. + per_monitor_dpi = false + + +[urgency_low] + # IMPORTANT: colors have to be defined in quotation marks. + # Otherwise the "#" and following would be interpreted as a comment. + background = "#1E1E2E" + foreground = "#888888" + timeout = 10 + # Icon for notifications with low urgency, uncomment to enable + #default_icon = /path/to/icon + +[urgency_normal] + background = "#1E1E2E" + foreground = "#ffffff" + timeout = 10 + # Icon for notifications with normal urgency, uncomment to enable + default_icon = /home/imxyy/Pictures/icon/notice.png + +[urgency_critical] + background = "#1E1E2E" + foreground = "#CB2027" + #frame_color = "#94393E" + timeout = 0 + # Icon for notifications with critical urgency, uncomment to enable + default_icon = /home/imxyy/Pictures/icon/critical.png + +# Every section that isn't one of the above is interpreted as a rules to +# override settings for certain messages. +# +# Messages can be matched by +# appname (discouraged, see desktop_entry) +# body +# category +# desktop_entry +# icon +# match_transient +# msg_urgency +# stack_tag +# summary +# +# and you can override the +# background +# foreground +# format +# frame_color +# fullscreen +# new_icon +# set_stack_tag +# set_transient +# set_category +# timeout +# urgency +# icon_position +# skip_display +# history_ignore +# action_name +# word_wrap +# ellipsize +# alignment +# hide_text +# +# Shell-like globbing will get expanded. +# +# Instead of the appname filter, it's recommended to use the desktop_entry filter. +# GLib based applications export their desktop-entry name. In comparison to the appname, +# the desktop-entry won't get localized. +# +# SCRIPTING +# You can specify a script that gets run when the rule matches by +# setting the "script" option. +# The script will be called as follows: +# script appname summary body icon urgency +# where urgency can be "LOW", "NORMAL" or "CRITICAL". +# +# NOTE: It might be helpful to run dunst -print in a terminal in order +# to find fitting options for rules. + +# Disable the transient hint so that idle_threshold cannot be bypassed from the +# client +#[transient_disable] +# match_transient = yes +# set_transient = no +# +# Make the handling of transient notifications more strict by making them not +# be placed in history. +#[transient_history_ignore] +# match_transient = yes +# history_ignore = yes + +# fullscreen values +# show: show the notifications, regardless if there is a fullscreen window opened +# delay: displays the new notification, if there is no fullscreen window active +# If the notification is already drawn, it won't get undrawn. +# pushback: same as delay, but when switching into fullscreen, the notification will get +# withdrawn from screen again and will get delayed like a new notification +#[fullscreen_delay_everything] +# fullscreen = delay +#[fullscreen_show_critical] +# msg_urgency = critical +# fullscreen = show + +#[espeak] +# summary = "*" +# script = dunst_espeak.sh + +#[script-test] +# summary = "*script*" +# script = dunst_test.sh + +#[ignore] +# # This notification will not be displayed +# summary = "foobar" +# skip_display = true + +#[history-ignore] +# # This notification will not be saved in history +# summary = "foobar" +# history_ignore = yes + +#[skip-display] +# # This notification will not be displayed, but will be included in the history +# summary = "foobar" +# skip_display = yes + +#[signed_on] +# appname = Pidgin +# summary = "*signed on*" +# urgency = low +# +#[signed_off] +# appname = Pidgin +# summary = *signed off* +# urgency = low +# +#[says] +# appname = Pidgin +# summary = *says* +# urgency = critical +# +#[twitter] +# appname = Pidgin +# summary = *twitter.com* +# urgency = normal +# +#[stack-volumes] +# appname = "some_volume_notifiers" +# set_stack_tag = "volume" +# +# vim: ft=cfg diff --git a/modules/desktop/notify/swaync/config/config.json b/modules/desktop/notify/swaync/config/config.json new file mode 100644 index 0000000..8bf2251 --- /dev/null +++ b/modules/desktop/notify/swaync/config/config.json @@ -0,0 +1,62 @@ +{ + "$schema": "/etc/xdg/swaync/configSchema.json", + "positionX": "right", + "positionY": "top", + "control-center-positionX": "none", + "control-center-positionY": "none", + "control-center-margin-top": 8, + "control-center-margin-bottom": 8, + "control-center-margin-right": 8, + "control-center-margin-left": 8, + "control-center-height": 600, + "control-center-width": 400, + "fit-to-screen": false, + "layer": "top", + "control-center-layer": "top", + "cssPriority": "user", + "notification-icon-size": 40, + "notification-body-image-height": 100, + "notification-body-image-width": 200, + "notification-inline-replies": true, + "notification-2fa-action": false, + "timeout": 10, + "timeout-low": 5, + "timeout-critical": 0, + "notification-window-width": 317, + "keyboard-shortcuts": true, + "image-visibility": "when-available", + "transition-time": 200, + "hide-on-clear": false, + "hide-on-action": false, + "script-fail-notify": true, + "widgets": [ + "inhibitors", + "title", + "dnd", + "mpris", + "notifications" + ], + "widget-config": { + "inhibitors": { + "text": "Inhibitors", + "button-text": "Clear All", + "clear-all-button": true + }, + "title": { + "text": "Notifications", + "clear-all-button": true, + "button-text": "Clear All" + }, + "dnd": { + "text": "Do Not Disturb" + }, + "label": { + "max-lines": 5, + "text": "Label Text" + }, + "mpris": { + "image-size": 96, + "image-radius": 12 + } + } +} diff --git a/modules/desktop/notify/swaync/config/style.css b/modules/desktop/notify/swaync/config/style.css new file mode 100644 index 0000000..1e20bba --- /dev/null +++ b/modules/desktop/notify/swaync/config/style.css @@ -0,0 +1,410 @@ +/* + * vim: ft=less + */ + +@define-color cc-bg rgba(42, 44, 54, 0.5); + +@define-color noti-border-color rgba(255, 255, 255, 0.15); +@define-color noti-bg rgba(42, 44, 54, 0.6); +@define-color noti-bg-hover rgba(52, 54, 64, 0.6); +@define-color noti-bg-focus rgba(55, 57, 67, 0.4); +@define-color noti-close-bg rgba(255, 255, 255, 0.1); +@define-color noti-close-bg-hover rgba(255, 255, 255, 0.15); + +@define-color text-color rgba(255, 255, 255, 0.6); +@define-color text-color-low rgba(136, 136, 136, 0.6); + +@define-color mpris-album-art-overlay rgba(52, 54, 64, 0.6); +@define-color mpris-button-hover rgba(55, 57, 67, 0.4); + +@define-color bg-selected rgb(0, 128, 255); + +* { + font-family: monospace; +} + +.low { + color: @text-color-low; +} + +.normal { + color: @text-color; +} + +.critical { + color: red; +} + + +.testing { + background-color: red; +} + +.notification-row { + all: unset; + font-size: 11px; + transition: all 200ms ease; + outline: none; + margin-bottom: 4px; + border-radius: 12px; +} + +.notification-row:hover { + background: transparent; +} + +.control-center .notification-row:focus, +.control-center .notification-row:hover { + opacity: 1; + background: transparent; +} + +.notification-row:focus .notification, +.notification-row:hover .notification { + /* box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.5); */ + /* box-shadow: 0px 0px 0px 3px @bg-selected; */ + box-shadow: none; +} + +.control-center .notification { + box-shadow: none; +} + +.control-center .notification-row { + opacity: 0.5; +} + +.notification { + background: @noti-bg; + transition: all 200ms ease; + border-radius: 12px; + margin: 6px 6px; + box-shadow: none; + padding: 0; +} + +.notification-content { + background: transparent; + padding: 6px; + border-radius: 12px; +} + +.close-button { + background: @noti-close-bg; + color: @text-color; + text-shadow: none; + padding: 0; + border-radius: 100%; + margin-top: 10px; + margin-right: 10px; + box-shadow: none; + border: none; + min-width: 24px; + min-height: 24px; +} + +.close-button:hover { + box-shadow: none; + background: @noti-close-bg-hover; + transition: all 0.15s ease-in-out; + border: none; +} + +.notification-default-action, +.notification-action { + padding: 4px; + margin: 0; + box-shadow: none; + background: @noti-bg; + border: 0px; + color: white; + transition: all 200ms ease; +} + +.notification-default-action:hover, +.notification-action:hover { + -gtk-icon-effect: none; + background: @noti-bg-hover; +} + +.notification-default-action { + border-radius: 12px; +} + +/* When alternative actions are visible */ +.notification-default-action:not(:only-child) { + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; +} + +.notification-action { + border-radius: 0px; + border-top: none; + border-right: none; +} + +/* add bottom border radius to eliminate clipping */ +.notification-action:first-child { + border-bottom-left-radius: 12px; +} + +.notification-action:last-child { + border-bottom-right-radius: 12px; + border-right: 1px solid @noti-border-color; +} + +.image {} + +.body-image { + margin-top: 6px; + background-color: white; + border-radius: 12px; +} + +.summary { + font-size: 16px; + font-weight: bold; + background: transparent; + color: @text-color; + text-shadow: none; +} + +.time { + font-size: 16px; + font-weight: bold; + background: transparent; + color: @text-color; + text-shadow: none; + margin-right: 18px; +} + +.body { + font-size: 15px; + font-weight: normal; + background: transparent; + color: @text-color; + text-shadow: none; +} + +.control-center { + background: @cc-bg; + border-radius: 12px; + background-clip: border-box; + padding: 4px; + box-shadow: none; +} + +.control-center-list { + background: transparent; +} + +.control-center-list-placeholder { + opacity: 0.5; +} + +.floating-notifications { + background: transparent; +} + +/* Window behind control center and on all other monitors */ +.blank-window { + background: transparent; +} + +/*** Widgets ***/ + +/* Title widget */ +.widget-title { + margin: 8px; + font-size: 1.5rem; + font-weight: bold; + color: @text-color; +} + +.widget-title>button { + font-size: initial; + color: @text-color; + text-shadow: none; + background: @noti-bg; + border: 0px; + box-shadow: none; + border-radius: 12px; +} + +.widget-title>button:hover { + background: @noti-bg-hover; +} + +/* DND widget */ +.widget-dnd { + margin: 8px; + font-size: 1.1rem; + color: @text-color; +} + +.widget-dnd>switch { + font-size: initial; + border-radius: 12px; + background: @noti-bg; + border: 0px; + box-shadow: none; +} + +.widget-dnd>switch:checked { + background: @text-color-low; +} + +.widget-dnd>switch slider { + background: @noti-bg-hover; + border-radius: 12px; +} + +/* Label widget */ +.widget-label { + margin: 8px; +} + +.widget-label>label { + font-size: 1.1rem; +} + +/* Mpris widget */ +.widget-mpris { + color: @text-color +} + +.widget-mpris-player { + padding: 16px; + margin: 16px; + background-color: @mpris-album-art-overlay; + border-radius: 12px; + box-shadow: none; +} + +.widget-mpris-album-art { + border-radius: 12px; + box-shadow: none; +} + +.widget-mpris-player button { + /* The media player buttons (play, pause, next, etc...) */ + color: @text-color; + /*background-color: @mpris-button-hover;*/ +} + +.widget-mpris-player button:disabled { + /* The media player buttons (play, pause, next, etc...) */ + color: @text-color-low; + /*background-color: @mpris-button-hover;*/ +} + +.widget-mpris-player button:hover { + /* The media player buttons (play, pause, next, etc...) */ + background-color: @mpris-button-hover; + /*background-color: @mpris-button-hover;*/ +} + +.widget-mpris>box>button { + color: @text-color; +} + +.widget-mpris>box>button:disabled { + color: @text-color-low; +} + +.widget-mpris-title { + font-weight: bold; + font-size: 1.25rem; +} + +.widget-mpris-subtitle { + font-size: 1.1rem; +} + +/* Buttons widget */ +.widget-buttons-grid { + padding: 8px; + margin: 8px; + border-radius: 12px; + border: 0px; + background-color: @noti-bg; +} + +.widget-buttons-grid>flowbox>flowboxchild>button { + color: @text-color; + background: @noti-bg; + border: 0px; + border-radius: 12px; +} + +.widget-buttons-grid>flowbox>flowboxchild>button:hover { + background: @noti-bg-hover; +} + +/* Menubar widget */ +.widget-menubar>box>.menu-button-bar>button { + border: none; + background: transparent; + background: red; +} + +/* .AnyName { Name defined in config after # + * background-color: @noti-bg; + * padding: 8px; + * margin: 8px; + * border-radius: 12px; + * } + * + * .AnyName>button { + * background: transparent; + * border: none; + * } + * + * .AnyName>button:hover { + * background-color: @noti-bg-hover; + * } + */ + +.topbar-buttons>button { + /* Name defined in config after # */ + border: none; + background: transparent; + background: blue; +} + +/* Volume widget */ + +.widget-volume { + background-color: @noti-bg; + padding: 8px; + margin: 8px; + border-radius: 12px; +} + +/* Backlight widget */ +.widget-backlight { + background-color: @noti-bg; + padding: 8px; + margin: 8px; + border-radius: 12px; +} + +/* Title widget */ +.widget-inhibitors { + margin: 8px; + font-size: 1.5rem; +} + +.widget-inhibitors>button { + font-size: initial; + color: white; + text-shadow: none; + background: @noti-bg; + border: 1px solid @noti-border-color; + box-shadow: none; + border-radius: 12px; +} + +.widget-inhibitors>button:hover { + background: @noti-bg-hover; +} diff --git a/modules/desktop/notify/swaync/default.nix b/modules/desktop/notify/swaync/default.nix new file mode 100644 index 0000000..36f8ca1 --- /dev/null +++ b/modules/desktop/notify/swaync/default.nix @@ -0,0 +1,29 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "swaync"; + packagePath = [ "swaynotificationcenter" ]; + optionPath = [ + "desktop" + "notify" + "swaync" + ]; + extraConfig = { + my.home = { + programs.niri.settings.binds."Mod+End".action.spawn = [ + "swaync-client" + "-t" + "-sw" + ]; + xdg.configFile."swaync" = { + source = ./config; + recursive = true; + }; + }; + }; +} diff --git a/modules/desktop/quickshell/config/components/bar/Battery.qml b/modules/desktop/quickshell/config/components/bar/Battery.qml new file mode 100644 index 0000000..bc5e32f --- /dev/null +++ b/modules/desktop/quickshell/config/components/bar/Battery.qml @@ -0,0 +1,48 @@ +import Quickshell +import Quickshell.Services.UPower +import QtQuick +import QtQuick.Layouts +import org.kde.kirigami + +Rectangle { + id: bat + + Layout.preferredWidth: batIcon.width + Layout.fillHeight: true + color: 'transparent' + + readonly property var battery: UPower.displayDevice + readonly property int percentage: Math.round(battery.percentage * 100) + property var size: height * 0.4 + + visible: battery.isLaptopBattery + + Icon { + id: batIcon + anchors.centerIn: parent + + implicitHeight: bat.size + implicitWidth: bat.size + + // This recolors the entire svg, instead of only classless components. + // Hopefully in the future classes can be selected for recoloring. + isMask: true + color: 'white' + + source: { + const nearestTen = Math.round(bat.percentage / 10) * 10; + const number = nearestTen.toString().padStart(2, "0"); + let charging; + + if (bat.battery.state == UPowerDeviceState.Charging) { + charging = "-charging"; + } else if (bat.battery.state.toString() == UPowerDeviceState.FullyCharged) { + charging = "-charged"; + } else { + charging = ""; + } + + return Quickshell.iconPath(`battery-level-${number}${charging}-symbolic`); + } + } +} diff --git a/modules/desktop/quickshell/config/components/bar/Clock.qml b/modules/desktop/quickshell/config/components/bar/Clock.qml new file mode 100644 index 0000000..8256b8a --- /dev/null +++ b/modules/desktop/quickshell/config/components/bar/Clock.qml @@ -0,0 +1,16 @@ +import QtQuick +import QtQuick.Layouts +import "../../utils" + +Rectangle { + Layout.fillHeight: true + color: "transparent" + implicitWidth: clockText.width + + Text { + id: clockText + text: Time.time + color: Colors.fg + anchors.centerIn: parent + } +} diff --git a/modules/desktop/quickshell/config/components/bar/Mpris.qml b/modules/desktop/quickshell/config/components/bar/Mpris.qml new file mode 100644 index 0000000..d4d1529 --- /dev/null +++ b/modules/desktop/quickshell/config/components/bar/Mpris.qml @@ -0,0 +1,14 @@ +import QtQuick +import QtQuick.Layouts + +Rectangle { + Layout.fillHeight: true + color: "salmon" + implicitWidth: mprisText.width + + Text { + id: mprisText + text: "Mpris" + anchors.centerIn: parent + } +} diff --git a/modules/desktop/quickshell/config/components/bar/Resources.qml b/modules/desktop/quickshell/config/components/bar/Resources.qml new file mode 100644 index 0000000..d1b2bbb --- /dev/null +++ b/modules/desktop/quickshell/config/components/bar/Resources.qml @@ -0,0 +1,54 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import "../../utils" + +Rectangle { + id: resources + + Layout.fillHeight: true + color: "transparent" + implicitWidth: rowLayout.width + + property int valueSize: 8 + property int textSize: 6 + + property string valueColor: "white" + property string textColor: "lightgray" + + RowLayout { + id: rowLayout + anchors.centerIn: parent + + ColumnLayout { + id: cpuColumn + Label { + color: textColor + font.pointSize: textSize + text: "CPU" + Layout.alignment: Qt.AlignCenter + } + Label { + color: valueColor + font.pointSize: valueSize + text: Resources.cpu_percent + "%" + Layout.alignment: Qt.AlignCenter + } + } + + ColumnLayout { + Label { + color: textColor + font.pointSize: textSize + text: "MEM" + Layout.alignment: Qt.AlignCenter + } + Label { + color: valueColor + font.pointSize: valueSize + text: Resources.mem_percent + "%" + Layout.alignment: Qt.AlignCenter + } + } + } +} diff --git a/modules/desktop/quickshell/config/components/bar/Text.qml b/modules/desktop/quickshell/config/components/bar/Text.qml new file mode 100644 index 0000000..90e0758 --- /dev/null +++ b/modules/desktop/quickshell/config/components/bar/Text.qml @@ -0,0 +1,5 @@ +import QtQuick + +Text { + renderType: Text.NativeRendering +} diff --git a/modules/desktop/quickshell/config/components/bar/Tray.qml b/modules/desktop/quickshell/config/components/bar/Tray.qml new file mode 100644 index 0000000..475c83b --- /dev/null +++ b/modules/desktop/quickshell/config/components/bar/Tray.qml @@ -0,0 +1,14 @@ +import QtQuick +import QtQuick.Layouts + +Rectangle { + Layout.fillHeight: true + color: "lightblue" + implicitWidth: trayText.width + + Text { + id: trayText + text: "Tray" + anchors.centerIn: parent + } +} diff --git a/modules/desktop/quickshell/config/components/bar/workspaces/Workspace.qml b/modules/desktop/quickshell/config/components/bar/workspaces/Workspace.qml new file mode 100644 index 0000000..f41e838 --- /dev/null +++ b/modules/desktop/quickshell/config/components/bar/workspaces/Workspace.qml @@ -0,0 +1,26 @@ +import QtQuick +import QtQuick.Layouts + +Rectangle { + id: ws + + property bool hovered: false + + Layout.preferredWidth: parent.height * 0.4 + Layout.preferredHeight: parent.height * 0.4 + Layout.alignment: Qt.AlignHCenter + radius: height / 2 + + MouseArea { + anchors.fill: parent + hoverEnabled: true + + onEntered: () => { + ws.hovered = true; + } + onExited: () => { + ws.hovered = false; + } + onClicked: () => console.log(`workspace ?`) + } +} diff --git a/modules/desktop/quickshell/config/components/bar/workspaces/Workspaces.qml b/modules/desktop/quickshell/config/components/bar/workspaces/Workspaces.qml new file mode 100644 index 0000000..b47f570 --- /dev/null +++ b/modules/desktop/quickshell/config/components/bar/workspaces/Workspaces.qml @@ -0,0 +1,55 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import "../../../utils" +import Quickshell.Hyprland + +Rectangle { + id: workspaces + + color: 'transparent' + + width: workspacesRow.implicitWidth + Layout.fillHeight: true + + RowLayout { + id: workspacesRow + + height: parent.height + implicitWidth: (parent.height * 0.5 + spacing) * 2 - spacing + anchors.centerIn: parent + + spacing: height / 7 + + Repeater { + id: repeater + + model: HyprlandUtils.maxWorkspace + + Workspace { + id: ws + required property int index + property HyprlandWorkspace currWorkspace: Hyprland.workspaces.values.find(e => e.id == index + 1) || null + property bool nonexistent: currWorkspace === null + property bool focused: index + 1 === Hyprland.focusedMonitor.activeWorkspace.id + + Layout.preferredWidth: { + if (focused) { + return parent.height * 0.8; + } else { + return parent.height * 0.4; + } + } + + color: { + if (nonexistent) { + return Colors.bgBlur; + } else { + return Colors.monitorColors[Hyprland.monitors.values.indexOf(Hyprland.workspaces.values.find(e => e.id === index + 1).monitor)]; + } + } + } + } + } +} diff --git a/modules/desktop/quickshell/config/shell.qml b/modules/desktop/quickshell/config/shell.qml new file mode 100644 index 0000000..932a8cb --- /dev/null +++ b/modules/desktop/quickshell/config/shell.qml @@ -0,0 +1,6 @@ +import "./windows" +import Quickshell // for ShellRoot and PanelWindow + +ShellRoot { + Bar {} +} diff --git a/modules/desktop/quickshell/config/utils/Colors.qml b/modules/desktop/quickshell/config/utils/Colors.qml new file mode 100644 index 0000000..1608de8 --- /dev/null +++ b/modules/desktop/quickshell/config/utils/Colors.qml @@ -0,0 +1,9 @@ +import Quickshell +pragma Singleton + +Singleton { + property var bgBar: Qt.rgba(0, 0, 0, 0.21) + property var bgBlur: Qt.rgba(0, 0, 0, 0.3) + property var fg: "white" + property list monitorColors: ["#e06c75", "#e5c07b", "#98c379", "#61afef"] +} diff --git a/modules/desktop/quickshell/config/utils/HyprlandUtils.qml b/modules/desktop/quickshell/config/utils/HyprlandUtils.qml new file mode 100644 index 0000000..6620061 --- /dev/null +++ b/modules/desktop/quickshell/config/utils/HyprlandUtils.qml @@ -0,0 +1,67 @@ +pragma Singleton + +import Quickshell +import Quickshell.Hyprland +import QtQuick + +Singleton { + id: hyprland + + property list workspaces: sortWorkspaces(Hyprland.workspaces.values) + property HyprlandWorkspace focusedWorkspace: Hyprland.focusedMonitor?.activeWorkspace + property int maxWorkspace: findMaxId() + + function sortWorkspaces(ws) { + return [...ws].sort((a, b) => a?.id - b?.id); + } + + function switchWorkspace(w: int): void { + console.log(`workspace: focus ${focusedWorkspace.id} -> ${w}`); + Hyprland.dispatch(`workspace ${w}`); + } + + function findMaxId(): int { + let num = hyprland.workspaces.length; + return hyprland.workspaces[num - 1]?.id; + } + + Connections { + target: Hyprland + function onRawEvent(event) { + // console.log("EVENT NAME", event.name); + // consow.wg("EVENT DATA", event.data); + let eventName = event.name; + + switch (eventName) { + // Both of these are required in order to detect workspace changes + // even when switching monitors. + // case "workspacev2": + // { + // // hyprland.focusedWorkspace = Hyprland.focusedMonitor?.activeWorkspace; + // console.log(`workspace: ${hyprland.focusedWorkspace.id}`); + // console.log(`num workspaces ${hyprland.workspaces.length}`) + // console.log(`num workspaces (real) ${Hyprland.workspaces.values.length}`) + // break; + // } + // case "focusedmonv2": + // { + // // hyprland.focusedWorkspace = Hyprland.focusedMonitor?.activeWorkspace; + // console.log(`workspace: ${hyprland.focusedWorkspace.id}`); + // console.log(`num workspaces ${hyprland.workspaces.length}`) + // console.log(`num workspaces (real) ${Hyprland.workspaces.values.length}`) + // break; + // } + case "createworkspacev2": + { + hyprland.workspaces = hyprland.sortWorkspaces(Hyprland.workspaces.values); + hyprland.maxWorkspace = findMaxId(); + } + case "destroyworkspacev2": + { + hyprland.workspaces = hyprland.sortWorkspaces(Hyprland.workspaces.values); + hyprland.maxWorkspace = findMaxId(); + } + } + } + } +} diff --git a/modules/desktop/quickshell/config/utils/Resources.qml b/modules/desktop/quickshell/config/utils/Resources.qml new file mode 100644 index 0000000..3a19d80 --- /dev/null +++ b/modules/desktop/quickshell/config/utils/Resources.qml @@ -0,0 +1,67 @@ +pragma Singleton + +import Quickshell +import Quickshell.Io +import QtQuick + +Singleton { + property int cpu_percent + property string cpu_freq + property int mem_percent + property string mem_used + + Process { + id: process_cpu_percent + running: true + command: ["sh", "-c", "top -bn1 | rg '%Cpu' | awk '{print 100-$8}'"] + stdout: SplitParser { + onRead: data => cpu_percent = Math.round(data) + } + } + + Process { + id: process_cpu_freq + running: true + command: ["sh", "-c", "lscpu --parse=MHZ"] + stdout: SplitParser { + onRead: data => { + // delete the first 4 lines (comments) + const mhz = data.split("\n").slice(4); + // compute mean frequency + const freq = mhz.reduce((acc, e) => acc + Number(e), 0) / mhz.length; + + cpu_freq = Math.round(freq) + " MHz"; + } + } + } + + Process { + id: process_mem_percent + running: true + command: ["sh", "-c", "free | awk 'NR==2{print $3/$2*100}'"] + stdout: SplitParser { + onRead: data => mem_percent = Math.round(data) + } + } + + Process { + id: process_mem_used + running: true + command: ["sh", "-c", "free --si -h | awk 'NR==2{print $3}'"] + stdout: SplitParser { + onRead: data => mem_used = data + } + } + + Timer { + interval: 2000 + running: true + repeat: true + onTriggered: () => { + process_cpu_percent.running = true + process_cpu_freq.running = true + process_mem_percent.running = true + process_mem_used.running = true + } + } +} diff --git a/modules/desktop/quickshell/config/utils/Time.qml b/modules/desktop/quickshell/config/utils/Time.qml new file mode 100644 index 0000000..f03e134 --- /dev/null +++ b/modules/desktop/quickshell/config/utils/Time.qml @@ -0,0 +1,29 @@ +pragma Singleton + +import Quickshell +import Quickshell.Io +import QtQuick + +Singleton { + property var locale: Qt.locale() + + function createDate(): string { + let date = new Date(); + let hh = date.getHours().toString().padStart(2, 0); + let mm = date.getMinutes().toString().padStart(2, 0) + let weekday = locale.dayName(date.getDay(), Locale.ShortFormat) + let month = locale.monthName(date.getMonth(), Locale.ShortFormat) + let day = date.getDate() + + return `${weekday} ${month} ${day} ${hh}:${mm}` + } + + property var time: createDate() + + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: time = createDate() + } +} diff --git a/modules/desktop/quickshell/config/windows/Bar.qml b/modules/desktop/quickshell/config/windows/Bar.qml new file mode 100644 index 0000000..8bd8137 --- /dev/null +++ b/modules/desktop/quickshell/config/windows/Bar.qml @@ -0,0 +1,79 @@ +//@ pragma NativeTextRendering + +import Quickshell +import QtQuick +import QtQuick.Layouts +import "../utils" +import "../components/bar" +import "../components/bar/workspaces" + +Scope { + PanelWindow { + id: barWindow + screen: Quickshell.screens[0] + + anchors { + top: true + left: true + right: true + } + height: 32 + + color: "transparent" + + Rectangle { + id: bar + anchors.fill: parent + + color: Colors.bgBlur + + // left + // RowLayout { + // id: barLeft + // + // anchors.bottom: parent.bottom + // anchors.left: parent.left + // anchors.top: parent.top + // + // anchors.leftMargin: height / 4 + // anchors.rightMargin: height / 4 + // spacing: height / 4 + // + // Workspaces {} + // } + + // middle + RowLayout { + id: barMiddle + + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + + anchors.leftMargin: height / 4 + anchors.rightMargin: height / 4 + spacing: height / 4 + + Mpris {} + } + + // right + RowLayout { + id: barRight + + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.top: parent.top + + anchors.leftMargin: height / 4 + anchors.rightMargin: height / 4 + spacing: height / 4 + + Tray {} + Resources {} + Battery {} + Clock {} + } + } + } +} diff --git a/modules/desktop/quickshell/default.nix b/modules/desktop/quickshell/default.nix new file mode 100644 index 0000000..96ef609 --- /dev/null +++ b/modules/desktop/quickshell/default.nix @@ -0,0 +1,29 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + default = false; + optionName = "quickshell"; + optionPath = [ + "desktop" + "quickshell" + ]; + config' = { + my.home = { + home.packages = [ pkgs.quickshell ]; + home.sessionVariables.QML2_IMPORT_PATH = lib.concatStringsSep ":" [ + "${pkgs.quickshell}/lib/qt-6/qml" + "${pkgs.kdePackages.qtdeclarative}/lib/qt-6/qml" + "${pkgs.kdePackages.kirigami.unwrapped}/lib/qt-6/qml" + ]; + xdg.configFile."quickshell" = { + source = ./config; + recursive = true; + }; + }; + }; +} diff --git a/modules/desktop/screencast/all.nix b/modules/desktop/screencast/all.nix new file mode 100644 index 0000000..7746a38 --- /dev/null +++ b/modules/desktop/screencast/all.nix @@ -0,0 +1,15 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all screencast tools"; + optionPath = [ + "desktop" + "screencast" + "all" + ]; + config' = { + my.desktop.screencast = { + obs-studio.enable = true; + }; + }; +} diff --git a/modules/desktop/screencast/default.nix b/modules/desktop/screencast/default.nix new file mode 100644 index 0000000..020d617 --- /dev/null +++ b/modules/desktop/screencast/default.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./obs-studio.nix + ]; +} diff --git a/modules/desktop/screencast/obs-studio.nix b/modules/desktop/screencast/obs-studio.nix new file mode 100644 index 0000000..fb06e8a --- /dev/null +++ b/modules/desktop/screencast/obs-studio.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "obs-studio"; + optionPath = [ + "desktop" + "screencast" + "obs-studio" + ]; + config' = { + my.home.home.packages = with pkgs; [ + (pkgs.wrapOBS { + plugins = with pkgs.obs-studio-plugins; [ + wlrobs + obs-backgroundremoval + ]; + }) + ]; + }; +} diff --git a/modules/desktop/style/default.nix b/modules/desktop/style/default.nix new file mode 100644 index 0000000..280d9ae --- /dev/null +++ b/modules/desktop/style/default.nix @@ -0,0 +1,73 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "style"; + optionPath = [ + "desktop" + "style" + ]; + config' = { + my.home = { + stylix = { + enable = true; + autoEnable = false; + base16Scheme = ./tokyonight-storm.yaml; + polarity = "dark"; + cursor = { + package = pkgs.bibata-cursors; + name = "Bibata-Modern-Classic"; + size = 24; + }; + iconTheme = { + enable = true; + package = pkgs.win11-icon-theme; + dark = "Win11"; + light = "Win11"; + }; + targets = { + nixos-icons.enable = false; + gnome-text-editor.enable = false; + }; + }; + + # GTK + gtk = { + enable = true; + theme = { + package = pkgs.mono-gtk-theme; + name = "MonoThemeDark"; + }; + gtk2 = { + configLocation = "${config.my.home.xdg.configHome}/gtk-2.0/gtkrc"; + }; + gtk3 = { + extraConfig = { + gtk-decoration-layout = ":none"; + gtk-application-prefer-dark-theme = 1; + }; + }; + gtk4 = { + extraConfig = { + gtk-decoration-layout = ":none"; + gtk-application-prefer-dark-theme = 1; + }; + }; + }; + + #QT + qt = { + enable = true; + style.package = with pkgs; [ + darkly-qt5 + darkly-qt6 + ]; + platformTheme.name = "qtct"; + }; + }; + }; +} diff --git a/modules/desktop/style/tokyonight-storm.yaml b/modules/desktop/style/tokyonight-storm.yaml new file mode 100644 index 0000000..8932a95 --- /dev/null +++ b/modules/desktop/style/tokyonight-storm.yaml @@ -0,0 +1,21 @@ +system: "base16" +name: "Tokyo Night Storm" +author: "Michaël Ball" +variant: "dark" +palette: + base00: "#24283B" + base01: "#16161E" + base02: "#343A52" + base03: "#444B6A" + base04: "#787C99" + base05: "#A9B1D6" + base06: "#CBCCD1" + base07: "#D5D6DB" + base08: "#C0CAF5" + base09: "#A9B1D6" + base0A: "#0DB9D7" + base0B: "#9ECE6A" + base0C: "#B4F9F8" + base0D: "#2AC3DE" + base0E: "#BB9AF7" + base0F: "#F7768E" diff --git a/modules/desktop/style/wallpaper.png b/modules/desktop/style/wallpaper.png new file mode 100644 index 0000000..8e439ac Binary files /dev/null and b/modules/desktop/style/wallpaper.png differ diff --git a/modules/desktop/terminal/alacritty/default.nix b/modules/desktop/terminal/alacritty/default.nix new file mode 100644 index 0000000..8994a7f --- /dev/null +++ b/modules/desktop/terminal/alacritty/default.nix @@ -0,0 +1,20 @@ +{ config, lib, ... }: +lib.my.makeHomeProgramConfig { + inherit config; + programName = "alacritty"; + optionPath = [ + "desktop" + "terminal" + "alacritty" + ]; + extraConfig = { + my.home.programs.alacritty.settings = { + general.import = [ ./tokyonight-storm.toml ]; + cursor.style = { + shape = "Block"; + blinking = "Never"; + }; + font.size = 14; + }; + }; +} diff --git a/modules/desktop/terminal/alacritty/tokyonight-storm.toml b/modules/desktop/terminal/alacritty/tokyonight-storm.toml new file mode 100644 index 0000000..494252b --- /dev/null +++ b/modules/desktop/terminal/alacritty/tokyonight-storm.toml @@ -0,0 +1,49 @@ +# ----------------------------------------------------------------------------- +# TokyoNight Alacritty Colors +# Theme: Tokyo Night Storm +# Upstream: https://github.com/folke/tokyonight.nvim/raw/main/extras/alacritty/tokyonight_storm.toml +# ----------------------------------------------------------------------------- + +# Default colors +[colors.primary] +background = '#24283b' +foreground = '#c0caf5' + +[colors.cursor] +cursor = '#c0caf5' +text = '#24283b' + +[colors.selection] +text = '#c0caf5' +background = '#2e3c64' + +# Normal colors +[colors.normal] +black = '#1d202f' +red = '#f7768e' +green = '#9ece6a' +yellow = '#e0af68' +blue = '#7aa2f7' +magenta = '#bb9af7' +cyan = '#7dcfff' +white = '#a9b1d6' + +# Bright colors +[colors.bright] +black = '#414868' +red = '#ff899d' +green = '#9fe044' +yellow = '#faba4a' +blue = '#8db0ff' +magenta = '#c7a9ff' +cyan = '#a4daff' +white = '#c0caf5' + +# Indexed Colors +[[colors.indexed_colors]] +index = 16 +color = '#ff9e64' + +[[colors.indexed_colors]] +index = 17 +color = '#db4b4b' diff --git a/modules/desktop/terminal/all.nix b/modules/desktop/terminal/all.nix new file mode 100644 index 0000000..bdc1313 --- /dev/null +++ b/modules/desktop/terminal/all.nix @@ -0,0 +1,18 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + optionName = "all terminals"; + optionPath = [ + "desktop" + "terminal" + "all" + ]; + config' = { + my.desktop.terminal = { + alacritty.enable = true; + foot.enable = true; + kitty.enable = true; + ghostty.enable = true; + }; + }; +} diff --git a/modules/desktop/terminal/default.nix b/modules/desktop/terminal/default.nix new file mode 100644 index 0000000..a5a6886 --- /dev/null +++ b/modules/desktop/terminal/default.nix @@ -0,0 +1,10 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./alacritty + ./foot + ./kitty + ./ghostty + ]; +} diff --git a/modules/desktop/terminal/foot/default.nix b/modules/desktop/terminal/foot/default.nix new file mode 100644 index 0000000..1b41686 --- /dev/null +++ b/modules/desktop/terminal/foot/default.nix @@ -0,0 +1,41 @@ +{ config, lib, ... }: +lib.my.makeHomeProgramConfig { + inherit config; + programName = "foot"; + optionPath = [ + "desktop" + "terminal" + "foot" + ]; + extraConfig = { + my.home.programs.foot = { + server.enable = true; + settings = { + main = { + font = "monospace:size=14"; + initial-window-size-pixels = "800x600"; + }; + colors = { + background = "24283b"; + foreground = "a9b1d6"; + regular0 = "32344a"; + regular1 = "f7768e"; + regular2 = "9ece6a"; + regular3 = "e0af68"; + regular4 = "7aa2f7"; + regular5 = "ad8ee6"; + regular6 = "449dab"; + regular7 = "9699a8"; + bright0 = "444b6a"; + bright1 = "ff7a93"; + bright2 = "b9f27c"; + bright3 = "ff9e64"; + bright4 = "7da6ff"; + bright5 = "bb9af7"; + bright6 = "0db9d7"; + bright7 = "acb0d0"; + }; + }; + }; + }; +} diff --git a/modules/desktop/terminal/ghostty/default.nix b/modules/desktop/terminal/ghostty/default.nix new file mode 100644 index 0000000..c88ed0a --- /dev/null +++ b/modules/desktop/terminal/ghostty/default.nix @@ -0,0 +1,21 @@ +{ config, lib, ... }: +lib.my.makeHomeProgramConfig { + inherit config; + programName = "ghostty"; + optionPath = [ + "desktop" + "terminal" + "ghostty" + ]; + extraConfig = { + my.home.programs.ghostty = { + enableBashIntegration = true; + enableZshIntegration = true; + installBatSyntax = true; + settings = { + font-size = 14; + theme = "${./tokyonight-storm}"; + }; + }; + }; +} diff --git a/modules/desktop/terminal/ghostty/tokyonight-storm b/modules/desktop/terminal/ghostty/tokyonight-storm new file mode 100644 index 0000000..9b38d22 --- /dev/null +++ b/modules/desktop/terminal/ghostty/tokyonight-storm @@ -0,0 +1,22 @@ +palette = 0=#1d202f +palette = 1=#f7768e +palette = 2=#9ece6a +palette = 3=#e0af68 +palette = 4=#7aa2f7 +palette = 5=#bb9af7 +palette = 6=#7dcfff +palette = 7=#a9b1d6 +palette = 8=#414868 +palette = 9=#ff899d +palette = 10=#9fe044 +palette = 11=#faba4a +palette = 12=#8db0ff +palette = 13=#c7a9ff +palette = 14=#a4daff +palette = 15=#c0caf5 + +background = #24283b +foreground = #c0caf5 +cursor-color = #c0caf5 +selection-background = #2e3c64 +selection-foreground = #c0caf5 diff --git a/modules/desktop/terminal/kitty/default.nix b/modules/desktop/terminal/kitty/default.nix new file mode 100644 index 0000000..3a58781 --- /dev/null +++ b/modules/desktop/terminal/kitty/default.nix @@ -0,0 +1,29 @@ +{ config, lib, ... }: +lib.my.makeHomeProgramConfig { + inherit config; + programName = "kitty"; + optionPath = [ + "desktop" + "terminal" + "kitty" + ]; + extraConfig = { + my.home.programs.kitty = { + settings = { + cursor_blink_interval = 0; + remember_window_size = "no"; + initial_window_width = 800; + initial_window_height = 600; + enable_audio_bell = "no"; + term = "xterm-256color"; + }; + font = { + name = "monospace"; + size = 14; + }; + extraConfig = '' + include ${./tokyonight-storm.conf} + ''; + }; + }; +} diff --git a/modules/desktop/terminal/kitty/tokyonight-storm.conf b/modules/desktop/terminal/kitty/tokyonight-storm.conf new file mode 100644 index 0000000..ef68b50 --- /dev/null +++ b/modules/desktop/terminal/kitty/tokyonight-storm.conf @@ -0,0 +1,50 @@ +# vim:ft=kitty + +## name: Tokyo Night Storm +## license: MIT +## author: Folke Lemaitre +## upstream: https://github.com/folke/tokyonight.nvim/raw/main/extras/kitty/tokyonight_storm.conf + + +background #24283b +foreground #c0caf5 +selection_background #2e3c64 +selection_foreground #c0caf5 +url_color #73daca +cursor #c0caf5 +cursor_text_color #24283b + +# Tabs +active_tab_background #7aa2f7 +active_tab_foreground #1f2335 +inactive_tab_background #292e42 +inactive_tab_foreground #545c7e +#tab_bar_background #1d202f + +# Windows +active_border_color #7aa2f7 +inactive_border_color #292e42 + +# normal +color0 #1d202f +color1 #f7768e +color2 #9ece6a +color3 #e0af68 +color4 #7aa2f7 +color5 #bb9af7 +color6 #7dcfff +color7 #a9b1d6 + +# bright +color8 #414868 +color9 #ff899d +color10 #9fe044 +color11 #faba4a +color12 #8db0ff +color13 #c7a9ff +color14 #a4daff +color15 #c0caf5 + +# extended colors +color16 #ff9e64 +color17 #db4b4b diff --git a/modules/desktop/wm/all.nix b/modules/desktop/wm/all.nix new file mode 100644 index 0000000..c88156c --- /dev/null +++ b/modules/desktop/wm/all.nix @@ -0,0 +1,21 @@ +{ + config, + lib, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "all window managers"; + optionPath = [ + "desktop" + "wm" + "all" + ]; + config' = { + my.desktop.wm = { + cage.enable = true; + dwm.enable = true; + niri.enable = true; + }; + }; +} diff --git a/modules/desktop/wm/cage.nix b/modules/desktop/wm/cage.nix new file mode 100644 index 0000000..7c050d3 --- /dev/null +++ b/modules/desktop/wm/cage.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "cage"; + packagePath = [ "cage" ]; + optionPath = [ + "desktop" + "wm" + "cage" + ]; +} diff --git a/modules/desktop/wm/default.nix b/modules/desktop/wm/default.nix new file mode 100644 index 0000000..4527806 --- /dev/null +++ b/modules/desktop/wm/default.nix @@ -0,0 +1,9 @@ +{ ... }: +{ + imports = [ + ./all.nix + ./cage.nix + ./dwm.nix + ./niri + ]; +} diff --git a/modules/desktop/wm/dwm.nix b/modules/desktop/wm/dwm.nix new file mode 100644 index 0000000..cccc4b4 --- /dev/null +++ b/modules/desktop/wm/dwm.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "dwm"; + packagePath = [ "dwm" ]; + optionPath = [ + "desktop" + "wm" + "dwm" + ]; +} diff --git a/modules/desktop/wm/niri/config.nix b/modules/desktop/wm/niri/config.nix new file mode 100644 index 0000000..092fad5 --- /dev/null +++ b/modules/desktop/wm/niri/config.nix @@ -0,0 +1,259 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + my.home.systemd.user.services.swaync.Unit.After = [ "graphical-session.target" ]; + + my.home.programs.niri.settings = { + input = { + focus-follows-mouse = { + enable = true; + max-scroll-amount = "40%"; + }; + workspace-auto-back-and-forth = true; + }; + + layout = { + gaps = 23; + center-focused-column = "never"; + always-center-single-column = true; + focus-ring.enable = false; + border = { + enable = true; + width = 4; + + inactive.color = "#2e2e3eee"; + active.gradient = { + from = "#6186d6ee"; + to = "#cba6f7ee"; + angle = 180; + relative-to = "workspace-view"; + }; + }; + preset-column-widths = [ + { proportion = 0.33333; } + { proportion = 0.4; } + { proportion = 0.5; } + { proportion = 0.6; } + { proportion = 0.66667; } + ]; + default-column-width.proportion = 0.4; + }; + + animations = { + enable = true; + slowdown = 1.5; + workspace-switch.spring = { + damping-ratio = 1.0; + stiffness = 1000; + epsilon = 0.0001; + }; + }; + + prefer-no-csd = true; + hotkey-overlay.skip-at-startup = true; + + window-rules = [ + { + geometry-corner-radius = { + bottom-left = 14.; + bottom-right = 14.; + top-left = 14.; + top-right = 14.; + }; + clip-to-geometry = true; + draw-border-with-background = false; + } + { + matches = [ { app-id = "kitty|foot|Alacritty|ghostty|chromium-browser|wofi"; } ]; + opacity = 0.8; + } + { + matches = [ { app-id = "org.gnome.Nautilus|nemo"; } ]; + opacity = 0.6; + } + ]; + + environment = { + QT_QPA_PLATFORM = "wayland;xcb"; + XDG_SESSION_TYPE = "wayland"; + XDG_CURRENT_DESKTOP = "niri"; + XDG_SESSION_DESKTOP = "niri"; + QT_AUTO_SCREEN_SCALE_FACTOR = "1"; + STEAM_FORCE_DESKTOPUI_SCALING = "1.25"; + DISPLAY = ":0"; + }; + + spawn-at-startup = map (c: { command = c; }) [ + [ + "alacritty" + "--daemon" + ] + [ "${lib.getExe pkgs.xwayland-satellite-unstable}" ] + [ + "${lib.getExe pkgs.swaybg}" + "-i" + (toString ./wallpaper.png) + ] + [ + "${lib.getExe pkgs.wl-clip-persist}" + "--clipboard" + "regular" + ] + [ + "wl-paste" + "--type" + "text" + "--watch" + "cliphist" + "store" + ] + [ + "wl-paste" + "--type" + "image" + "--watch" + "cliphist" + "store" + ] + ]; + + binds = + with config.my.home.lib.niri.actions; + { + "Ctrl+Alt+T".action.spawn = [ + "alacritty" + "msg" + "create-window" + ]; + "Mod+T".action.spawn = [ + "alacritty" + "msg" + "create-window" + ]; + "Mod+Return".action.spawn = [ + "alacritty" + "msg" + "create-window" + ]; + "Mod+G".action.spawn = [ "chromium" ]; + "Mod+E".action.spawn = [ "nemo" ]; + "Mod+R".action.spawn = [ + "sh" + "-c" + "pkill wofi || wofi --color ~/.config/wal/colors" + ]; + "Mod+V".action.spawn = [ + "sh" + "-c" + "pkill ${lib.getExe pkgs.wofi} || ${lib.getExe pkgs.cliphist} list | wofi --dmenu --color ~/.config/wal/colors | cliphist decode | wl-copy" + ]; + + "XF86AudioRaiseVolume" = { + allow-when-locked = true; + action.spawn = [ + "pamixer" + "-i" + "2" + ]; + }; + "XF86AudioLowerVolume" = { + allow-when-locked = true; + action.spawn = [ + "pamixer" + "-d" + "2" + ]; + }; + "XF86AudioMute" = { + allow-when-locked = true; + action.spawn = [ + "playerctl" + "-i" + "firefox,chromium" + "play-pause" + ]; + }; + "Mod+XF86AudioRaiseVolume" = { + allow-when-locked = true; + action.spawn = [ + "playerctl" + "-i" + "firefox,chromium" + "next" + ]; + }; + "Mod+XF86AudioLowerVolume" = { + allow-when-locked = true; + action.spawn = [ + "playerctl" + "-i" + "firefox,chromium" + "previous" + ]; + }; + + "Mod+Q".action = close-window; + + "Mod+Left".action = focus-column-left; + "Mod+Right".action = focus-column-right; + "Mod+Up".action = focus-window-up; + "Mod+Down".action = focus-window-down; + + "Mod+Ctrl+Left".action = move-column-left; + "Mod+Ctrl+Right".action = move-column-right; + "Mod+Ctrl+Up".action = move-window-up; + "Mod+Ctrl+Down".action = move-window-down; + + "Mod+Shift+Left".action = focus-monitor-left; + "Mod+Shift+Right".action = focus-monitor-right; + "Mod+Shift+Up".action = focus-monitor-up; + "Mod+Shift+Down".action = focus-monitor-down; + + "Mod+Shift+Ctrl+Left".action = move-column-to-monitor-left; + "Mod+Shift+Ctrl+Right".action = move-column-to-monitor-right; + "Mod+Shift+Ctrl+Up".action = move-column-to-monitor-up; + "Mod+Shift+Ctrl+Down".action = move-column-to-monitor-down; + + "Mod+Page_Up".action = focus-workspace-up; + "Mod+Page_Down".action = focus-workspace-down; + + "Mod+Ctrl+Page_Up".action = move-column-to-workspace-up; + "Mod+Ctrl+Page_Down".action = move-column-to-workspace-down; + + "Mod+Shift+Page_Up".action = move-workspace-up; + "Mod+Shift+Page_Down".action = move-workspace-down; + + "Mod+Comma".action = consume-window-into-column; + "Mod+Period".action = expel-window-from-column; + + "Mod+L".action = switch-preset-column-width; + "Mod+Shift+L".action = reset-window-height; + "Mod+M".action = maximize-column; + "Mod+Shift+M".action = fullscreen-window; + "Mod+C".action = center-column; + "Mod+F".action = toggle-window-floating; + "Mod+H".action = expand-column-to-available-width; + + "Mod+Minus".action.set-column-width = "-10%"; + "Mod+Equal".action.set-column-width = "+10%"; + "Mod+Shift+Minus".action.set-window-height = "-10%"; + "Mod+Shift+Equal".action.set-window-height = "+10%"; + + "Ctrl+Alt+A".action = screenshot; + # "Print".action = screenshot-screen; + "Alt+Print".action = screenshot-window; + + "Mod+Shift+E".action = quit; + } + // lib.attrsets.mergeAttrsList ( + map (n: { + "Mod+${toString n}".action.focus-workspace = n; + "Mod+Shift+${toString n}".action.move-column-to-workspace = n; + }) (lib.range 0 9) + ); + }; +} diff --git a/modules/desktop/wm/niri/default.nix b/modules/desktop/wm/niri/default.nix new file mode 100644 index 0000000..cb51922 --- /dev/null +++ b/modules/desktop/wm/niri/default.nix @@ -0,0 +1,87 @@ +args@{ + lib, + config, + pkgs, + ... +}: +let + cfg = config.my.desktop.wm.niri; + pkg = pkgs.niri-unstable; +in +{ + options.my.desktop.wm.niri = { + enable = lib.mkEnableOption "Niri"; + }; + + imports = [ + (lib.mkIf cfg.enable (import ./config.nix args)) + ]; + + config = lib.mkIf cfg.enable { + xdg.portal = { + enable = true; + config = { + niri = { + default = [ + "gnome" + "gtk" + ]; + "org.freedesktop.impl.portal.Access" = [ "gtk" ]; + "org.freedesktop.impl.portal.FileChooser" = [ "gtk" ]; + "org.freedesktop.impl.portal.Notification" = [ "gtk" ]; + "org.freedesktop.impl.portal.RemoteDesktop" = [ "gnome" ]; + "org.freedesktop.impl.portal.ScreenCast" = [ "gnome" ]; + "org.freedesktop.impl.portal.Screenshot" = [ "gnome" ]; + "org.freedesktop.impl.portal.Secret" = [ "gnome-keyring" ]; + }; + }; + extraPortals = with pkgs; [ + xdg-desktop-portal-gtk + xdg-desktop-portal-gnome + ]; + }; + programs.uwsm = { + enable = true; + waylandCompositors = { + niri = { + prettyName = "niri"; + comment = "Niri compositor managed by UWSM"; + binPath = pkgs.writeShellScript "niri-session" '' + ${lib.getExe pkg} --session + ''; + }; + }; + }; + programs.niri = { + enable = true; + package = pkg; + }; + my.home = { + home.packages = with pkgs; [ + wlr-randr + wl-clipboard + wl-clip-persist + cliphist + swaynotificationcenter + nemo-with-extensions + ]; + programs.wofi.enable = true; + xdg.configFile."wofi" = { + source = ./wofi; + recursive = true; + }; + xdg.configFile."wal" = { + source = ./wal; + recursive = true; + }; + programs.waybar = { + enable = true; + systemd.enable = true; + }; + xdg.configFile."waybar/config.jsonc".text = builtins.toJSON (import ./waybar/config.nix args); + xdg.configFile."waybar/style.css" = { + source = ./waybar/style.css; + }; + }; + }; +} diff --git a/modules/desktop/wm/niri/wal/colors b/modules/desktop/wm/niri/wal/colors new file mode 100644 index 0000000..d0c6888 --- /dev/null +++ b/modules/desktop/wm/niri/wal/colors @@ -0,0 +1,6 @@ +#1e1e2e +#262636 +#d9e0ee +#89b4fa +#f38ba8 +#cba6f7 diff --git a/modules/desktop/wm/niri/wallpaper.png b/modules/desktop/wm/niri/wallpaper.png new file mode 100644 index 0000000..8e439ac Binary files /dev/null and b/modules/desktop/wm/niri/wallpaper.png differ diff --git a/modules/desktop/wm/niri/waybar/config.nix b/modules/desktop/wm/niri/waybar/config.nix new file mode 100644 index 0000000..596572e --- /dev/null +++ b/modules/desktop/wm/niri/waybar/config.nix @@ -0,0 +1,118 @@ +{ ... }: +{ + layer = "top"; + position = "top"; + mod = "dock"; + exclusive = true; + passthrough = false; + gtk-layer-shell = true; + height = 0; + + modules-left = [ + "clock" + "cpu" + "memory" + "niri/workspaces" + ]; + modules-center = [ + "mpris" + ]; + modules-right = [ + "custom/notification" + "tray" + "pulseaudio" + "pulseaudio#microphone" + ]; + + "niri/workspaces" = { + format = "{value}"; + }; + cpu = { + interval = 1; + format = "󰞱 {}%"; + max-length = 10; + on-click = ""; + }; + memory = { + interval = 10; + format = " {used:0.1f}G"; + max-length = 10; + }; + "custom/notification" = { + tooltip = false; + format = "{icon}"; + format-icons = { + notification = ""; + none = ""; + dnd-notification = ""; + dnd-none = ""; + inhibited-notification = ""; + inhibited-none = ""; + dnd-inhibited-notification = ""; + dnd-inhibited-none = ""; + }; + return-type = "json"; + exec-if = "which swaync-client"; + exec = "swaync-client -swb"; + on-double-click = "swaync-client -t -sw"; + on-click-right = "swaync-client -d -sw"; + escape = true; + }; + tray = { + icon-size = 13; + tooltip = false; + spacing = 10; + }; + mpris = { + player = "musicfox"; + interval = 1; + format = "{status_icon} {artist} - {title}"; + max-length = 60; + status-icons = { + paused = ""; + playing = ""; + stopped = ""; + }; + tooltip = false; + toottip-format = "{status_icon} Musicfox {artist} - {album} - {title}"; + on-scroll-up = "playerctl -p musicfox volume 0.05+"; + on-scroll-down = "playerctl -p musicfox volume 0.05-"; + }; + clock = { + format = " {:%H:%M  %m.%d}"; + tooltip = false; + }; + pulseaudio = { + format = "{icon} {volume}%"; + tooltip = false; + format-muted = "󰟎 Muted"; + on-click = "pamixer -t"; + on-click-middle = "pavucontrol & disown"; + on-scroll-up = "pamixer -i 5"; + on-scroll-down = "pamixer -d 5"; + scroll-step = 5; + format-icons = { + headphone = "󰋋"; + hands-free = "󰋋"; + headset = "󰋋"; + phone = ""; + portable = ""; + car = ""; + default = [ + "" + "" + "" + ]; + }; + }; + "pulseaudio#microphone" = { + format = "{format_source}"; + tooltip = false; + format-source = "󰍬 {volume}%"; + format-source-muted = "󰍭 Muted"; + on-click = "pamixer --default-source -t"; + on-scroll-up = "pamixer --default-source -i 5"; + on-scroll-down = "pamixer --default-source -d 5"; + scroll-step = 5; + }; +} diff --git a/modules/desktop/wm/niri/waybar/style.css b/modules/desktop/wm/niri/waybar/style.css new file mode 100644 index 0000000..f9a49be --- /dev/null +++ b/modules/desktop/wm/niri/waybar/style.css @@ -0,0 +1,247 @@ +* { + border: none; + border-radius: 0; + font-family: monospace; + font-weight: bold; + font-size: 14px; + min-height: 0; +} + +window#waybar { + background: rgba(21, 18, 27, 0); + color: #cdd6f4; +} + +tooltip { + color: #cdd6f4; + font-family: monospace; + background: #1e1e2e; + border-radius: 10px; + border-width: 2px; + border-style: solid; + border-color: #2a2c36; +} + +tooltip label { + color: #cdd6f4; +} + +tooltip.background { + background-clip: padding-box; +} + +tooltip * { + padding: 4px; + background-color: transparent; + color: white; +} + +#workspaces button { + padding: 5px; + color: #313244; + margin-right: 5px; +} + +#workspaces button.focused { + color: #a6adc8; + border-radius: 10px; +} + +#workspaces button.urgent { + color: #11111b; + background: #a6e3a1; + border-radius: 10px; +} + +#workspaces button:hover { + background: #11111b; + color: #cdd6f4; + border-radius: 10px; +} + +#taskbar button { + padding: 5px; + color: #313244; + margin-right: 5px; +} + +#taskbar button.focused { + color: #a6adc8; + background: #eba0ac; + border-radius: 10px; +} + +#taskbar button.urgent { + color: #11111b; + background: #a6e3a1; + border-radius: 10px; +} + +#workspaces button:hover { + background: #11111b; + color: #cdd6f4; + border-radius: 10px; +} + +#tray menu { + color: #cdd6f4; + font-family: monospace; + background: #1e1e2e; + border-radius: 10px; + border-width: 2px; + border-style: solid; + border-color: #2a2c36; +} + +#custom-language, +#custom-updates, +#custom-caffeine, +#custom-weather, +#window, +#clock, +#battery, +#pulseaudio, +#network, +#workspaces, +#taskbar, +#tray, +#custom-notification, +#mpd, +#mpris, +#cpu, +#memory, +#backlight { + background: #1e1e2e; + padding: 0px 10px; + margin: 3px 0px; + margin-top: 10px; + border: 1px solid #181825; +} + +#tray { + border-radius: 10px; + margin-right: 10px; +} + +#workspaces { + background: #1e1e2e; + border-radius: 10px; + margin-left: 10px; + padding-right: 0px; + padding-left: 5px; +} + +#taskbar { + background: #1e1e2e; + border-radius: 10px; + margin-left: 10px; + padding-right: 0px; + padding-left: 5px; +} + +#custom-language { + color: #f38ba8; + border-left: 0px; + border-right: 0px; +} + +#custom-updates { + color: #f5c2e7; + border-left: 0px; + border-right: 0px; + border-radius: 10px 0px 0px 10px; +} + +#custom-notification { + color: #cdd6f4; + font-size: 20px; + border-radius: 10px; + margin-right: 10px; +} + +#mpd { + color: rgba(97, 134, 214, 0.973); + background: #1e1e2e; + border-radius: 10px; + border: 1px solid #181825; +} + +#mpris { + color: rgba(97, 134, 214, 0.973); + background: #1e1e2e; + border-radius: 10px; + border: 1px solid #181825; + margin-right: 10px; +} + +#window { + border-radius: 10px; + margin-left: 60px; + margin-right: 60px; +} + +#window.empty { + border-radius: 0px; + background-color: transparent; +} + +window#waybar.empty #window { + padding: 0px; + margin: 0px; + border: 0px; + background-color: transparent; +} + +#clock { + color: #fab387; + border-radius: 10px 0px 0px 10px; + margin-left: 5px; + border-right: 0px; +} + +#network { + color: #f9e2af; + border-left: 0px; + border-right: 0px; +} + +#cpu { + color: #fab387; + border-radius: 0; + border-left: 0; + border-right: 0; +} + +#memory { + color: #fab387; + border-radius: 0px 10px 10px 0px; + border-left: 0; + border-right: 0; +} + +#pulseaudio { + color: #89b4fa; + border-right: 0px; + border-radius: 10px 0px 0px 10px; +} + +#pulseaudio.microphone { + color: #cba6f7; + margin-right: 5px; + border-left: 0px; + border-radius: 0 10px 10px 0; +} + +#battery { + color: #a6e3a1; + border-radius: 0 10px 10px 0; + margin-right: 10px; + border-left: 0px; +} + +#custom-weather { + border-radius: 0px 10px 10px 0px; + border-left: 0; + border-right: 0; + margin-left: 0px; +} diff --git a/modules/desktop/wm/niri/wofi/config b/modules/desktop/wm/niri/wofi/config new file mode 100644 index 0000000..71f7d6b --- /dev/null +++ b/modules/desktop/wm/niri/wofi/config @@ -0,0 +1,39 @@ +## Wofi Config + +## General +show=drun +prompt=Apps +normal_window=true +layer=top +term=kitty + +## Geometry +width=500px +height=305px +location=0 +orientation=vertical +halign=fill +line_wrap=off +dynamic_lines=false + +## Images +allow_markup=true +allow_images=true +image_size=24 + +## Search +exec_search=false +hide_search=false +parse_search=false +insensitive=false + +## Other +hide_scroll=true +no_actions=true +sort_order=default +gtk_dark=true +filter_rate=100 + +## Keys +key_expand=Tab +key_exit=Escape diff --git a/modules/desktop/wm/niri/wofi/style.css b/modules/desktop/wm/niri/wofi/style.css new file mode 100644 index 0000000..5c07201 --- /dev/null +++ b/modules/desktop/wm/niri/wofi/style.css @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020-2022 Aditya Shakya +*/ + +/** ********** Fonts ********** **/ +* { + font-family: monospace; + font-size: 12px; +} + +#window { + background-color: --wofi-color0; + color: --wofi-color2; + border: 2px solid --wofi-color1; + border-radius: 0px; +} + +#outer-box { + padding: 20px; +} + +#input { + background-color: --wofi-color1; + border: 0px solid --wofi-color3; + padding: 8px 12px; +} + +#scroll { + margin-top: 20px; +} + +#inner-box { +} + +#img { + padding-right: 8px; +} + +#text { + color: --wofi-color2; +} + +#text:selected { + color: --wofi-color0; +} + +#entry { + padding: 6px; +} + +#entry:selected { + background-color: --wofi-color3; + color: --wofi-color0; +} + +#unselected { +} + +#selected { +} + +#input, #entry:selected { + border-radius: 4px; +} diff --git a/modules/getty-autologin.nix b/modules/getty-autologin.nix new file mode 100644 index 0000000..4d6ba8e --- /dev/null +++ b/modules/getty-autologin.nix @@ -0,0 +1,83 @@ +{ + config, + lib, + pkgs, + ... +}: + +with lib; + +let + cfg = config.my.autologin; + gettycfg = config.services.getty; + + baseArgs = + [ + "--login-program" + "${gettycfg.loginProgram}" + ] + ++ optionals (gettycfg.loginOptions != null) [ + "--login-options" + gettycfg.loginOptions + ] + ++ gettycfg.extraArgs; + + gettyCmd = args: "@${pkgs.util-linux}/sbin/agetty agetty ${escapeShellArgs baseArgs} ${args}"; + + forAllAutologinTTYs = + config: + attrsets.mergeAttrsList ( + builtins.map (ttynum: { "getty@tty${toString ttynum}" = config; }) cfg.ttys + ); + + autologinModule = types.submodule ( + { ... }: + { + options = { + enable = mkEnableOption "autologin"; + user = mkOption { + type = types.str; + default = ""; + example = "foo"; + description = mdDoc '' + Username of the account that will be automatically logged in at the console. + ''; + }; + ttys = mkOption { + type = types.listOf types.int; + default = [ 6 ]; + description = mdDoc '' + TTY numbers for autologin.user to login to. + ''; + }; + }; + } + ); + +in + +{ + ###### interface + + options = { + + my.autologin = mkOption { + type = autologinModule; + default = { }; + }; + + }; + + ###### implementation + + config = mkIf cfg.enable { + systemd.services = forAllAutologinTTYs { + overrideStrategy = "asDropin"; # needed for templates to work + serviceConfig.ExecStart = [ + "" + (gettyCmd "--noclear --keep-baud %I 115200,38400,9600 -a ${cfg.user} $TERM") + ]; + }; + }; + +} diff --git a/modules/gpg.nix b/modules/gpg.nix new file mode 100644 index 0000000..814eb66 --- /dev/null +++ b/modules/gpg.nix @@ -0,0 +1,19 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeHomeProgramConfig { + inherit config; + programName = "gpg"; + optionPath = [ "gpg" ]; + extraConfig = { + programs.gnupg.agent = { + enable = true; + pinentryPackage = pkgs.pinentry-curses; + enableSSHSupport = true; + }; + my.persist.homeDirs = [ ".gnupg" ]; + }; +} diff --git a/modules/home-manager/default.nix b/modules/home-manager/default.nix deleted file mode 100644 index 45aae31..0000000 --- a/modules/home-manager/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -# Add your reusable home-manager modules to this directory, on their own file (https://nixos.wiki/wiki/Module). -# These should be stuff you would like to share with others, not your personal configurations. -{ - # List your module files here - # my-module = import ./my-module.nix; -} diff --git a/modules/i18n/default.nix b/modules/i18n/default.nix new file mode 100644 index 0000000..f4e0234 --- /dev/null +++ b/modules/i18n/default.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + imports = [ + ./fcitx5.nix + ./locale.nix + ]; +} diff --git a/modules/i18n/fcitx5.nix b/modules/i18n/fcitx5.nix new file mode 100644 index 0000000..df64f34 --- /dev/null +++ b/modules/i18n/fcitx5.nix @@ -0,0 +1,114 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.my.makeSwitch { + inherit config; + optionName = "default fcitx5 settings"; + optionPath = [ + "i18n" + "fcitx5" + ]; + config' = { + i18n.inputMethod = { + enable = true; + type = "fcitx5"; + fcitx5 = { + addons = with pkgs; [ + fcitx5-chinese-addons # fcitx5-mozc + fluent-fcitx5 + fcitx5-lightly + ]; + waylandFrontend = true; + settings = { + globalOptions = { + "PreeditEnabledByDefault"."0" = true; + "Hotkey"."EnumrateWithTriggerKeys" = false; + "Hotkey/TriggerKeys"."0" = ""; + "Hotkey/AltTriggerKeys"."0" = "Shift_L"; + "Hotkey/EnumerateForwardKeys"."0" = ""; + "Hotkey/EnumerateBackwardKeys"."0" = ""; + }; + inputMethod = { + "Groups/0" = { + "Name" = "Default"; + "Default Layout" = "us"; + "DefaultIM" = "pinyin"; + }; + "Groups/0/Items/0" = { + "Name" = "keyboard-us"; + "Layout" = ""; + }; + "Groups/0/Items/1" = { + "Name" = "pinyin"; + "Layout" = ""; + }; + /* + "Groups/0/Items/2" = { + "Name" = "mozc"; + "Layout" = ""; + }; + */ + "GroupOrder"."0" = "Default"; + }; + addons = { + classicui.globalSection = { + WheelForPaging = true; + Font = "sans-serif 10"; + MenuFont = "Noto Sans CJK SC 10"; + TrayFont = "Noto Sans CJK SC Bold 10"; + Theme = "lightly"; + PerScreenDPI = true; + EnableFractionalScale = true; + }; + punctuation.globalSection = { + HalfWidthPuncAfterLetterOrNumber = true; + TypePairedPunctuationsTogether = false; + Enabled = true; + }; + pinyin = { + globalSection = { + PageSize = 9; + EmojiEnabled = false; + ChaiziEnabled = true; + ExtBEnabled = true; + CloudPinyinEnabled = true; + CloudPinyinIndex = 2; + PreeditInApplication = true; + }; + sections = { + Fuzzy = { + VE_UE = true; + NG_GN = true; + Inner = true; + InnerShort = true; + PartialFinal = false; + V_U = true; + IN_ING = true; + U_OU = true; + }; + }; + }; + cloudpinyin.globalSection = { + Backend = "Baidu"; + MinimumPinyinLength = 4; + }; + clipboard.globalSection = { + TriggerKey = ""; + }; + }; + }; + ignoreUserConfig = true; + }; + }; + my.home.programs.niri.settings = { + binds."Mod+Space".action.spawn = [ + "fcitx5-remote" + "-t" + ]; + spawn-at-startup = [ { command = [ "fcitx5" ]; } ]; + }; + }; +} diff --git a/modules/i18n/locale.nix b/modules/i18n/locale.nix new file mode 100644 index 0000000..5b7e0a4 --- /dev/null +++ b/modules/i18n/locale.nix @@ -0,0 +1,26 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + default = true; + optionName = "default locale settings"; + optionPath = [ + "i18n" + "locale" + ]; + config' = { + i18n = { + defaultLocale = "en_US.UTF-8"; + extraLocaleSettings = { + LC_ADDRESS = "zh_CN.UTF-8"; + LC_IDENTIFICATION = "zh_CN.UTF-8"; + LC_MEASUREMENT = "zh_CN.UTF-8"; + LC_MONETARY = "zh_CN.UTF-8"; + LC_NAME = "zh_CN.UTF-8"; + LC_NUMERIC = "zh_CN.UTF-8"; + LC_PAPER = "zh_CN.UTF-8"; + LC_TELEPHONE = "zh_CN.UTF-8"; + LC_TIME = "zh_CN.UTF-8"; + }; + }; + }; +} diff --git a/modules/nix.nix b/modules/nix.nix new file mode 100644 index 0000000..30590b1 --- /dev/null +++ b/modules/nix.nix @@ -0,0 +1,54 @@ +{ + inputs, + config, + lib, + ... +}: +lib.my.makeSwitch { + inherit config; + default = true; + optionName = "default nix settings"; + optionPath = [ "nix" ]; + config' = { + # This will add each flake input as a registry + # To make nix3 commands consistent with your flake + nix.registry = (lib.mapAttrs (_: flake: { inherit flake; })) ( + (lib.filterAttrs (_: lib.isType "flake")) inputs + ); + + # This will additionally add your inputs to the system's legacy channels + # Making legacy nix commands consistent as well, awesome! + nix.nixPath = [ "/etc/nix/path" ]; + + nix.settings = { + # Enable flakes and new 'nix' command + experimental-features = "nix-command flakes"; + # Deduplicate and optimize nix store + auto-optimise-store = true; + substituters = lib.mkForce [ + # "https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store" + # "https://mirror.sjtu.edu.cn/nix-channels/store" + "https://mirrors.sjtug.sjtu.edu.cn/nix-channels/store" + "https://mirrors.ustc.edu.cn/nix-channels/store" + "https://nix-community.cachix.org" + "https://cache.nixos.org" + ]; + trusted-public-keys = [ + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + ]; + }; + + /* + nix.gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 30d"; + }; + */ + + environment.etc = lib.mapAttrs' (name: value: { + name = "nix/path/${name}"; + value.source = value.flake; + }) config.nix.registry; + }; +} diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix deleted file mode 100644 index 8605069..0000000 --- a/modules/nixos/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -# Add your reusable NixOS modules to this directory, on their own file (https://nixos.wiki/wiki/Module). -# These should be stuff you would like to share with others, not your personal configurations. -{ - # List your module files here - # my-module = import ./my-module.nix; -} diff --git a/modules/persist.nix b/modules/persist.nix new file mode 100644 index 0000000..905c9cc --- /dev/null +++ b/modules/persist.nix @@ -0,0 +1,77 @@ +{ + lib, + config, + username, + ... +}: +let + cfg = config.my.persist; +in +{ + options.my.persist = { + enable = lib.mkEnableOption "persist"; + homeDirs = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + example = lib.literalExpression '' + [ + ".minecraft" + ".cargo" + ] + ''; + description = lib.mdDoc '' + HomeManager persistent dirs. + ''; + }; + nixosDirs = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + example = lib.literalExpression '' + [ + "/root" + "/var" + ] + ''; + description = lib.mdDoc '' + NixOS persistent dirs. + ''; + }; + homeFiles = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + example = lib.literalExpression '' + [ + ".hmcl.json" + ] + ''; + description = lib.mdDoc '' + Persistent files. + ''; + }; + nixosFiles = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + example = lib.literalExpression '' + [ + "/etc/machine-id" + ] + ''; + description = lib.mdDoc '' + Persistent files. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + programs.fuse.userAllowOther = true; + environment.persistence."/persistent" = { + hideMounts = true; + directories = cfg.nixosDirs; + files = cfg.nixosFiles; + users.${username} = { + files = cfg.homeFiles; + directories = cfg.homeDirs; + }; + }; + }; +} diff --git a/modules/sops.nix b/modules/sops.nix new file mode 100644 index 0000000..675af73 --- /dev/null +++ b/modules/sops.nix @@ -0,0 +1,28 @@ +{ + config, + pkgs, + lib, + username, + ... +}: +lib.my.makeSwitch { + inherit config; + default = true; + optionName = "sops secret settings"; + optionPath = [ "sops" ]; + config' = { + sops.age.sshKeyPaths = [ + "/persistent/home/${username}/.ssh/id_ed25519" + ]; + users.users.${username}.extraGroups = [ "keys" ]; + environment.variables.SOPS_AGE_KEY_FILE = "/run/secrets.d/age-keys.txt"; + my.home = { + sops.age.sshKeyPaths = [ + "/persistent/home/${username}/.ssh/id_ed25519" + ]; + home.packages = [ + pkgs.sops + ]; + }; + }; +} diff --git a/modules/time.nix b/modules/time.nix new file mode 100644 index 0000000..b8ef40d --- /dev/null +++ b/modules/time.nix @@ -0,0 +1,16 @@ +{ config, lib, ... }: +lib.my.makeSwitch { + inherit config; + default = true; + optionName = "default time settings"; + optionPath = [ "time" ]; + config' = { + time.timeZone = "Asia/Shanghai"; + networking.timeServers = [ + "0.cn.pool.ntp.org" + "1.cn.pool.ntp.org" + "2.cn.pool.ntp.org" + "3.cn.pool.ntp.org" + ]; + }; +} diff --git a/modules/user.nix b/modules/user.nix new file mode 100644 index 0000000..56dbea9 --- /dev/null +++ b/modules/user.nix @@ -0,0 +1,62 @@ +{ + config, + lib, + pkgs, + username, + userdesc, + sopsRoot, + ... +}: +lib.my.makeSwitch { + inherit config; + default = true; + optionName = "default user settings"; + optionPath = [ "user" ]; + config' = { + programs.zsh.enable = true; + + sops.secrets.imxyy-nix-hashed-password = { + sopsFile = sopsRoot + /imxyy-nix-hashed-password.txt; + format = "binary"; + }; + users = { + mutableUsers = false; + users.${username} = { + isNormalUser = true; + description = "${userdesc}"; + shell = pkgs.zsh; + extraGroups = [ + "wheel" + username + ]; + hashedPasswordFile = lib.mkDefault config.sops.secrets.imxyy-nix-hashed-password.path; + }; + groups.${username} = { }; + }; + users.users.root.hashedPasswordFile = lib.mkDefault config.sops.secrets.imxyy-nix-hashed-password.path; + + security.sudo.extraRules = [ + { + users = [ "${username}" ]; + commands = [ + { + command = "ALL"; + options = [ "NOPASSWD" ]; + } + ]; + } + ]; + + nix.settings.trusted-users = [ + "root" + "${username}" + ]; + + my.home = { + home = { + inherit username; + homeDirectory = "/home/${username}"; + }; + }; + }; +} diff --git a/modules/virt/default.nix b/modules/virt/default.nix new file mode 100644 index 0000000..4b547fc --- /dev/null +++ b/modules/virt/default.nix @@ -0,0 +1,228 @@ +{ + config, + lib, + pkgs, + username, + ... +}: +let + cfg = config.my.virt; + generateConfig = + settings: + lib.generators.toINI { + mkKeyValue = lib.generators.mkKeyValueDefault { + mkValueString = + v: + if (true == v) then + "yes" + else if (false == v) then + "no" + else + (lib.generators.mkValueStringDefault { } v); + } "="; + } settings; +in +{ + imports = [ + (lib.my.makeHomePackageConfig { + inherit config pkgs; + packageName = "moonlight-qt"; + packagePath = [ "moonlight-qt" ]; + optionPath = [ + "virt" + "moonlight" + ]; + }) + ]; + + options.my.virt = { + enable = lib.mkEnableOption "virtualization"; + looking-glass = { + enable = lib.mkEnableOption "looking-glass"; + package = lib.mkPackageOption pkgs "looking-glass-client" { }; + kvmfr = { + enable = lib.mkEnableOption "KVM Frame Relay (kvmfr)"; + + package = lib.mkPackageOption config.boot.kernelPackages "kvmfr" { + pkgsText = "config.boot.kernelPackages"; + }; + + owner = lib.mkOption { + description = "Owner of the kvmfr device file(s). You probably want to set this to the name of the user who will run looking-glass-client."; + default = "kvm"; + example = "your-user-name"; + type = lib.types.str; + }; + + group = lib.mkOption { + description = "Group of the kvmfr device file(s)"; + default = "kvm"; + example = "kvm"; + type = lib.types.str; + }; + + sizeMB = lib.mkOption { + description = "Size (in megabytes) of the kvmfr device"; + default = 32; + example = 128; + type = lib.types.ints.positive; + }; + + configureDeviceACLs = lib.mkOption { + description = '' + Configure libvirtd's qemu.conf to include the kvmfr device in the + cgroup_device_acl setting. When enabled, this module adds a block + to the 'virtualisation.libvirtd.qemu.verbatimConfig' option which + sets cgroup_device_acl to the default list of devices along with + the kvmfr0 device. You probably want this enabled unless you + explicitly set the 'verbatimConfig' option elsewhere. + If you already set a custom value for cgroup_device_acl, you should + not enable this option. Instead, add '/dev/kvmfr0' to the setting + yourself. + If you do not add '/dev/kvmfr0' to the list or enable this option, + any VMs attempting to utilize kvmfr will fail to start, and libvirt + will report a Permission Denied error. + ''; + default = false; + example = true; + type = lib.types.bool; + }; + }; + + # Options for creating the /dev/shm shared memory file + shm = { + enable = lib.mkEnableOption "Shared Memory Frame Relay"; + + owner = lib.mkOption { + description = "Owner of the shared memory file"; + default = "kvm"; + example = "your-user-name"; + type = lib.types.str; + }; + + name = lib.mkOption { + description = "Name of the shared memory file under /dev/shm"; + default = "looking-glass"; + example = "looking-glass"; + }; + }; + + # Client configuration (written to /etc/looking-glass-client.ini) + settings = lib.mkOption { + description = "Looking Glass client configuration"; + default = { }; + type = lib.types.submodule ./types; + + example = { + app.shmFile = "/dev/kvmfr0"; + input.escapeKey = "KEY_RIGHTCTRL"; + + win = { + fullScreen = true; + noScreensaver = true; + showFPS = true; + }; + }; + }; + }; + }; + + config = lib.mkMerge [ + (lib.mkIf cfg.looking-glass.enable ( + let + cfg' = cfg.looking-glass; + in + { + warnings = lib.lists.optional (!cfg'.kvmfr.enable && !cfg'.shm.enable) '' + Neither the shared memory nor kvmfr kernel module are enabled. + You must configure one of these manually or set one of programs.looking-glass.kvmfr.enable + or programs.looking-glass.shm.enable to have them automatically configured. + ''; + + # Install looking glass + environment.systemPackages = [ cfg'.package ]; + + # Optionally install the kvmfr kernel module + boot.extraModulePackages = lib.lists.optional cfg'.kvmfr.enable cfg'.kvmfr.package; + + # Create the configuration file if requested + environment.etc = { + # Write the looking glass configuration + "looking-glass-client.ini".text = generateConfig cfg'.settings; + + # Set the frame size if kvmfr is enabled + "modprobe.d/kvmfr.conf" = { + enable = cfg'.kvmfr.enable; + text = '' + options kvmfr static_size_mb=${toString cfg'.kvmfr.sizeMB} + ''; + }; + + # Load the kvmfr module at boot if enabled + "modules-load.d/kvmfr.conf" = { + enable = cfg'.kvmfr.enable; + text = '' + # KVMFR Looking Glass Module + kvmfr + ''; + }; + }; + + # Automatically apply permissions to the kvmfr device as requested + services.udev.packages = lib.lists.optional cfg'.kvmfr.enable ( + pkgs.writeTextFile { + name = "99-looking-glass-kvmfr.rules"; + destination = "/etc/udev/rules.d/99-looking-glass-kvmfr.rules"; + text = '' + SUBSYSTEM=="kvmfr", OWNER="${cfg'.kvmfr.owner}", GROUP="${cfg'.kvmfr.group}", MODE="0660" + ''; + } + ); + + # Create the /dev/shm file if requested + systemd.tmpfiles.rules = lib.lists.optional cfg'.shm.enable '' + f /dev/shm/${cfg'.shm.name} 0660 ${cfg'.shm.owner} qemu-libvirtd - + ''; + + # Allow access to the kvmfr device from the libvirt cgroups + virtualisation.libvirtd.qemu.verbatimConfig = + lib.strings.optionalString (cfg'.kvmfr.enable && cfg'.kvmfr.configureDeviceACLs) + '' + cgroup_device_acl = [ + "/dev/null", "/dev/full", "/dev/zero", + "/dev/random", "/dev/urandom", + "/dev/ptmx", "/dev/kvm", "/dev/kqemu", + "/dev/rtc","/dev/hpet", "/dev/vfio/vfio", + "/dev/kvmfr0" + ] + ''; + + # Add libvirt-qemu apparmor policy allowing rw access to kvmfr device if apparmor is enabled + security.apparmor.packages = + lib.lists.optional (cfg'.kvmfr.enable && config.security.apparmor.enable) + ( + pkgs.writeTextFile { + name = "looking-glass-kvmfr-apparmor-policy"; + destination = "/etc/apparmor.d/local/abstractions/libvirt-qemu"; + text = '' + # Looking Glass + /dev/kvmfr0 rw, + ''; + } + ); + } + )) + (lib.mkIf cfg.enable { + virtualisation.libvirtd = { + enable = true; + qemu.verbatimConfig = '' + dynamic_ownership = 0 + remember_owner = 0 + ''; + }; + programs.virt-manager.enable = true; + users.users.${username}.extraGroups = [ "libvirtd" ]; + environment.systemPackages = with pkgs; [ virglrenderer ]; + }) + ]; +} diff --git a/modules/virt/types/app.nix b/modules/virt/types/app.nix new file mode 100644 index 0000000..a5f9a7e --- /dev/null +++ b/modules/virt/types/app.nix @@ -0,0 +1,34 @@ +{ lib, ... }: +{ + options = { + renderer = lib.mkOption { + description = "Specify the renderer to use"; + default = "auto"; + type = lib.types.str; + }; + + cursorPollInterval = lib.mkOption { + description = "How often to check for a cursor update in microseconds"; + default = 1000; + type = lib.types.ints.positive; + }; + + framePollInterval = lib.mkOption { + description = "How often to check for a frame update in microseconds"; + default = 1000; + type = lib.types.ints.positive; + }; + + allowDMA = lib.mkOption { + description = "Allow DMA transfers if supported"; + default = true; + type = lib.types.bool; + }; + + shmFile = lib.mkOption { + description = "Path to the shared memory file or kvmfr device"; + default = "/dev/kvmfr0"; + type = lib.types.str; + }; + }; +} diff --git a/modules/virt/types/audio.nix b/modules/virt/types/audio.nix new file mode 100644 index 0000000..c31485f --- /dev/null +++ b/modules/virt/types/audio.nix @@ -0,0 +1,32 @@ +{ lib, ... }: +{ + options = { + periodSize = lib.mkOption { + description = "Requested audio device period size in samples"; + default = 2048; + type = lib.types.ints.positive; + }; + + bufferLatency = lib.mkOption { + description = "Additional buffer latency in milliseconds"; + default = 13; + type = lib.types.ints.positive; + }; + + micDefault = lib.mkOption { + description = "Default action when an application opens the microphone"; + default = "prompt"; + type = lib.types.enum [ + "prompt" + "allow" + "deny" + ]; + }; + + micShowIndicator = lib.mkOption { + description = "Display microphone usage indicator"; + default = true; + type = lib.types.bool; + }; + }; +} diff --git a/modules/virt/types/default.nix b/modules/virt/types/default.nix new file mode 100644 index 0000000..2d1f849 --- /dev/null +++ b/modules/virt/types/default.nix @@ -0,0 +1,52 @@ +{ lib, ... }: +{ + options = { + app = lib.mkOption { + description = "Application-wide configuration"; + default = { }; + type = lib.types.submodule ./app.nix; + }; + + win = lib.mkOption { + description = "Window configuration"; + default = { }; + type = lib.types.submodule ./win.nix; + }; + + input = lib.mkOption { + description = "Input configuration"; + default = { }; + type = lib.types.submodule ./input.nix; + }; + + spice = lib.mkOption { + description = "Spice agent configuration"; + default = { }; + type = lib.types.submodule ./spice.nix; + }; + + audio = lib.mkOption { + description = "Audio configuration"; + default = { }; + type = lib.types.submodule ./audio.nix; + }; + + egl = lib.mkOption { + description = "EGL configuration"; + default = { }; + type = lib.types.submodule ./egl.nix; + }; + + opengl = lib.mkOption { + description = "OpenGL configuration"; + default = { }; + type = lib.types.submodule ./opengl.nix; + }; + + wayland = lib.mkOption { + description = "Wayland configuration"; + default = { }; + type = lib.types.submodule ./wayland.nix; + }; + }; +} diff --git a/modules/virt/types/egl.nix b/modules/virt/types/egl.nix new file mode 100644 index 0000000..33bd82e --- /dev/null +++ b/modules/virt/types/egl.nix @@ -0,0 +1,70 @@ +{ lib, ... }: +{ + options = { + vsync = lib.mkOption { + description = "Enable vsync"; + default = false; + type = lib.types.bool; + }; + + doubleBuffer = lib.mkOption { + description = "Enable double buffering"; + default = false; + type = lib.types.bool; + }; + + multiSample = lib.mkOption { + description = "Enable multisampling"; + default = true; + type = lib.types.bool; + }; + + nvGainMax = lib.mkOption { + description = "The maximum night vision gain"; + default = 1; + type = lib.types.int; + }; + + nvGain = lib.mkOption { + description = "The initial night vision gain at startup"; + default = 0; + type = lib.types.int; + }; + + cbMode = lib.mkOption { + description = "Color Blind Mode (0 = Off, 1 = Protanope, 2 = Deuteranope, 3 = Tritanope)"; + default = 0; + type = lib.types.addCheck lib.types.int (x: x >= 0 && x <= 3); + }; + + scale = lib.mkOption { + description = "Set the scale algorithm (0 = auto, 1 = nearest, 2 = linear)"; + default = 0; + type = lib.types.addCheck lib.types.int (x: x >= 0 && x <= 2); + }; + + debug = lib.mkOption { + description = "Enable debug output"; + default = false; + type = lib.types.bool; + }; + + noBufferAge = lib.mkOption { + description = "Disable partial rendering based on buffer age"; + default = false; + type = lib.types.bool; + }; + + noSwapDamage = lib.mkOption { + description = "Disable swapping with damage"; + default = false; + type = lib.types.bool; + }; + + scalePointer = lib.mkOption { + description = "Keep the pointer size 1:1 when downscaling"; + default = true; + type = lib.types.bool; + }; + }; +} diff --git a/modules/virt/types/input.nix b/modules/virt/types/input.nix new file mode 100644 index 0000000..c164e8a --- /dev/null +++ b/modules/virt/types/input.nix @@ -0,0 +1,84 @@ +{ lib, ... }: +{ + options = { + grabKeyboard = lib.mkOption { + description = "Grab the keybaord in capture mode"; + default = true; + type = lib.types.bool; + }; + + grabKeyboardOnFocus = lib.mkOption { + description = "Grab the keyboard when focused"; + default = false; + type = lib.types.bool; + }; + + releaseKeysOnFocusLoss = lib.mkOption { + description = "On focus loss, send key up events to guest for all held keys"; + default = true; + type = lib.types.bool; + }; + + escapeKey = lib.mkOption { + description = "Specify the escape/menu key to use"; + default = "KEY_SCROLLLOCK"; + type = import ./keys.nix { + inherit lib; + }; + }; + + ignoreWindowsKeys = lib.mkOption { + description = "Do not pass events for the windows keys to the guest"; + default = false; + type = lib.types.bool; + }; + + hideCursor = lib.mkOption { + description = "Hide the local mouse cursor"; + default = true; + type = lib.types.bool; + }; + + mouseSens = lib.mkOption { + description = "Initial mouse sensitivity when in capture mode (-9 to 9)"; + default = 0; + type = lib.types.addCheck lib.types.int (x: x >= -9 && x <= 9); + }; + + mouseSmoothing = lib.mkOption { + description = "Apply simple mouse smoothing when rawMouse is not in use"; + default = true; + type = lib.types.bool; + }; + + rawMouse = lib.mkOption { + description = "Use RAW mouse input when in capture mode (good for gaming)"; + default = false; + type = lib.types.bool; + }; + + mouseRedraw = lib.mkOption { + description = "Mouse movements trigger redraws (ignore FPS minimum)"; + default = true; + type = lib.types.bool; + }; + + autoCapture = lib.mkOption { + description = "Try to keep the mouse captured when needed"; + default = false; + type = lib.types.bool; + }; + + captureOnly = lib.mkOption { + description = "Only enable input via SPICE if in capture mode"; + default = false; + type = lib.types.bool; + }; + + helpMenuDelay = lib.mkOption { + description = "Show help menu after holding down the escape key for this many milliseconds"; + default = 200; + type = lib.types.ints.positive; + }; + }; +} diff --git a/modules/virt/types/keys.nix b/modules/virt/types/keys.nix new file mode 100644 index 0000000..1df0381 --- /dev/null +++ b/modules/virt/types/keys.nix @@ -0,0 +1,129 @@ +{ lib, ... }: +lib.types.enum [ + "KEY_RESERVED" + "KEY_ESC" + "KEY_1" + "KEY_2" + "KEY_3" + "KEY_4" + "KEY_5" + "KEY_6" + "KEY_7" + "KEY_8" + "KEY_9" + "KEY_0" + "KEY_MINUS" + "KEY_EQUAL" + "KEY_BACKSPACE" + "KEY_TAB" + "KEY_Q" + "KEY_W" + "KEY_E" + "KEY_R" + "KEY_T" + "KEY_Y" + "KEY_U" + "KEY_I" + "KEY_O" + "KEY_P" + "KEY_LEFTBRACE" + "KEY_RIGHTBRACE" + "KEY_ENTER" + "KEY_LEFTCTRL" + "KEY_A" + "KEY_S" + "KEY_D" + "KEY_F" + "KEY_G" + "KEY_H" + "KEY_J" + "KEY_K" + "KEY_L" + "KEY_SEMICOLON" + "KEY_APOSTROPHE" + "KEY_GRAVE" + "KEY_LEFTSHIFT" + "KEY_BACKSLASH" + "KEY_Z" + "KEY_X" + "KEY_C" + "KEY_V" + "KEY_B" + "KEY_N" + "KEY_M" + "KEY_COMMA" + "KEY_DOT" + "KEY_SLASH" + "KEY_RIGHTSHIFT" + "KEY_KPASTERISK" + "KEY_LEFTALT" + "KEY_SPACE" + "KEY_CAPSLOCK" + "KEY_F1" + "KEY_F2" + "KEY_F3" + "KEY_F4" + "KEY_F5" + "KEY_F6" + "KEY_F7" + "KEY_F8" + "KEY_F9" + "KEY_F10" + "KEY_NUMLOCK" + "KEY_SCROLLLOCK" + "KEY_KP7" + "KEY_KP8" + "KEY_KP9" + "KEY_KPMINUS" + "KEY_KP4" + "KEY_KP5" + "KEY_KP6" + "KEY_KPPLUS" + "KEY_KP1" + "KEY_KP2" + "KEY_KP3" + "KEY_KP0" + "KEY_KPDOT" + "KEY_102ND" + "KEY_F11" + "KEY_F12" + "KEY_RO" + "KEY_HENKAN" + "KEY_KATAKANAHIRAGANA" + "KEY_MUHENKAN" + "KEY_KPENTER" + "KEY_RIGHTCTRL" + "KEY_KPSLASH" + "KEY_SYSRQ" + "KEY_RIGHTALT" + "KEY_HOME" + "KEY_UP" + "KEY_PAGEUP" + "KEY_LEFT" + "KEY_RIGHT" + "KEY_END" + "KEY_DOWN" + "KEY_PAGEDOWN" + "KEY_INSERT" + "KEY_DELETE" + "KEY_MUTE" + "KEY_VOLUMEDOWN" + "KEY_VOLUMEUP" + "KEY_KPEQUAL" + "KEY_PAUSE" + "KEY_KPCOMMA" + "KEY_HANGEUL" + "KEY_HANJA" + "KEY_YEN" + "KEY_LEFTMETA" + "KEY_RIGHTMETA" + "KEY_COMPOSE" + "KEY_NEXTSONG" + "KEY_PLAYPAUSE" + "KEY_PREVIOUSSONG" + "KEY_STOPCD" + "KEY_F13" + "KEY_F14" + "KEY_F15" + "KEY_PRINT" +] diff --git a/modules/virt/types/opengl.nix b/modules/virt/types/opengl.nix new file mode 100644 index 0000000..8812f1c --- /dev/null +++ b/modules/virt/types/opengl.nix @@ -0,0 +1,28 @@ +{ lib, ... }: +{ + options = { + mipmap = lib.mkOption { + description = "Enable mipmapping"; + default = true; + type = lib.types.bool; + }; + + vsync = lib.mkOption { + description = "Enable vsync"; + default = false; + type = lib.types.bool; + }; + + preventBuffer = lib.mkOption { + description = "Prevent the driver from buffering frames"; + default = true; + type = lib.types.bool; + }; + + amdPinnedMem = lib.mkOption { + description = "Use GL_AMD_pinned_memory if it is available"; + default = true; + type = lib.types.bool; + }; + }; +} diff --git a/modules/virt/types/spice.nix b/modules/virt/types/spice.nix new file mode 100644 index 0000000..474490c --- /dev/null +++ b/modules/virt/types/spice.nix @@ -0,0 +1,76 @@ +{ lib, ... }: +{ + options = { + enable = lib.mkOption { + description = "Enable the built-in SPICE client for input and/or clipboard support"; + default = true; + type = lib.types.bool; + }; + + host = lib.mkOption { + description = "The SPICE server host or UNIX socket"; + default = "127.0.0.1"; + type = lib.types.str; + }; + + port = lib.mkOption { + description = "The SPICE server port (0 = unix socket)"; + default = 5900; + type = lib.types.port; + }; + + input = lib.mkOption { + description = "Use SPICE to send keyboard and mouse input events to the guest"; + default = true; + type = lib.types.bool; + }; + + clipboard = lib.mkOption { + description = "Use SPICE to synchronize the clipboard contents with the guest"; + default = true; + type = lib.types.bool; + }; + + clipboardToVM = lib.mkOption { + description = "Allow the clipboard to be synchronized TO the VM"; + default = true; + type = lib.types.bool; + }; + + clipboardToLocal = lib.mkOption { + description = "Allow the clipbaord to be synchronized FROM the VM"; + default = true; + type = lib.types.bool; + }; + + audio = lib.mkOption { + description = "Enable SPICE audio support"; + default = true; + type = lib.types.bool; + }; + + scaleCursor = lib.mkOption { + description = "Scale cursor input position to screen size when up/down scaled"; + default = true; + type = lib.types.bool; + }; + + captureOnStart = lib.mkOption { + description = "Capture mouse and keybaord on start"; + default = false; + type = lib.types.bool; + }; + + alwaysShowCursor = lib.mkOption { + description = "Always show host cursor"; + default = false; + type = lib.types.bool; + }; + + showCursorDot = lib.mkOption { + description = "Use a 'dot' cursor when the window does not have focus"; + default = true; + type = lib.types.bool; + }; + }; +} diff --git a/modules/virt/types/wayland.nix b/modules/virt/types/wayland.nix new file mode 100644 index 0000000..cad76b6 --- /dev/null +++ b/modules/virt/types/wayland.nix @@ -0,0 +1,16 @@ +{ lib, ... }: +{ + options = { + warpSupport = lib.mkOption { + description = "Enable cursor warping"; + default = true; + type = lib.types.bool; + }; + + fractionScale = lib.mkOption { + description = "Enable fractional scale"; + default = true; + type = lib.types.bool; + }; + }; +} diff --git a/modules/virt/types/win.nix b/modules/virt/types/win.nix new file mode 100644 index 0000000..06cb837 --- /dev/null +++ b/modules/virt/types/win.nix @@ -0,0 +1,160 @@ +{ lib, ... }: +{ + options = { + title = lib.mkOption { + description = "Window Title"; + default = "Looking Glass (client)"; + type = lib.types.str; + }; + + position = lib.mkOption { + description = "Initial window position at startup"; + default = "center"; + type = lib.types.str; + }; + + size = lib.mkOption { + description = "Initial window size at startup"; + default = "1024x768"; + type = lib.types.str; + }; + + autoResize = lib.mkOption { + description = "Auto resize the window to the guest"; + default = false; + type = lib.types.bool; + }; + + allowResize = lib.mkOption { + description = "Allow the window to be resized manually"; + default = true; + type = lib.types.bool; + }; + + keepAspect = lib.mkOption { + description = "Maintain correct aspect ratio"; + default = true; + type = lib.types.bool; + }; + + forceAspect = lib.mkOption { + description = "Force the window to maintain the aspect ratio"; + default = true; + type = lib.types.bool; + }; + + dontUpscale = lib.mkOption { + description = "Never try to upscale the window"; + default = false; + type = lib.types.bool; + }; + + intUpscale = lib.mkOption { + description = "Allow only integer upscaling"; + default = false; + type = lib.types.bool; + }; + + shrinkOnUpscale = lib.mkOption { + description = "Limit the window dimensions when dontUpscale is enabled"; + default = false; + type = lib.types.bool; + }; + + borderless = lib.mkOption { + description = "Borderless mode"; + default = false; + type = lib.types.bool; + }; + + fullScreen = lib.mkOption { + description = "Launch in fullscreen borderless mode"; + default = false; + type = lib.types.bool; + }; + + maximize = lib.mkOption { + description = "Launch window maximized"; + default = false; + type = lib.types.bool; + }; + + minimizeOnFocusLoss = lib.mkOption { + description = "Minimize window on focus loss"; + default = false; + type = lib.types.bool; + }; + + fpsMin = lib.mkOption { + description = "Frame rate minimum (0 = disabled - not recommended, -1 = auto-detect)"; + default = -1; + type = lib.types.addCheck lib.types.int (x: x == -1 || x >= 0); + }; + + ignoreQuit = lib.mkOption { + description = "Ignore requests to quit (i.e. Alt+F4)"; + default = false; + type = lib.types.bool; + }; + + noScreensaver = lib.mkOption { + description = "Prevent the screensaver from starting"; + default = false; + type = lib.types.bool; + }; + + autoScreensaver = lib.mkOption { + description = "Prevent the screensaver from starting when the guest requests it"; + default = false; + type = lib.types.bool; + }; + + alerts = lib.mkOption { + description = "Show on screen alert messages"; + default = true; + type = lib.types.bool; + }; + + quickSplash = lib.mkOption { + description = "Skip fading out the splash screen when a connection is established"; + default = false; + type = lib.types.bool; + }; + + overlayDimsDesktop = lib.mkOption { + description = "Dim the desktop when in interactive overlay mode"; + default = true; + type = lib.types.bool; + }; + + rotate = lib.mkOption { + description = "Rotate the displayed image (0, 90, 180, 270)"; + default = 0; + type = lib.types.int; + }; + + uiFont = lib.mkOption { + description = "The font to use when rendering on-screen UI"; + default = "DejaVu Sans Mono"; + type = lib.types.str; + }; + + uiSize = lib.mkOption { + description = "The font size to use when rendering on-screen UI"; + default = 14; + type = lib.types.ints.positive; + }; + + jitRender = lib.mkOption { + description = "Enable just-in-time rendering"; + default = false; + type = lib.types.bool; + }; + + showFPS = lib.mkOption { + description = "Enable the FPS and UPS display"; + default = false; + type = lib.types.bool; + }; + }; +} diff --git a/modules/xdg.nix b/modules/xdg.nix new file mode 100644 index 0000000..5ea041b --- /dev/null +++ b/modules/xdg.nix @@ -0,0 +1,63 @@ +{ + lib, + config, + pkgs, + ... +}: +let + cfg = config.my.xdg; +in +{ + options.my.xdg = { + enable = lib.mkEnableOption "xdg"; + defaultApplications = lib.mkOption { + type = lib.types.attrs; + default = { }; + }; + extraBookmarks = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + }; + }; + + config = lib.mkIf cfg.enable { + my.home = + let + homedir = config.my.home.home.homeDirectory; + in + { + home.packages = with pkgs; [ + xdg-utils # `xdg-mime` `xdg-open` and so on + ]; + xdg = { + enable = true; + + cacheHome = "${homedir}/.cache"; + configHome = "${homedir}/.config"; + dataHome = "${homedir}/.local/share"; + stateHome = "${homedir}/.local/state"; + + userDirs.enable = true; + + configFile."mimeapps.list".force = true; + + mimeApps = { + enable = true; + inherit (cfg) defaultApplications; + }; + }; + gtk.gtk3.bookmarks = [ + "file://${homedir}/Documents 文档" + "file://${homedir}/Downloads 下载" + "file://${homedir}/Pictures 图片" + "file://${homedir}/Videos 视频" + "file://${homedir}/Music 音乐" + "file://${homedir}/workspace 工作空间" + "file://${homedir}/Documents/%E7%8F%AD%E7%BA%A7%E4%BA%8B%E5%8A%A1 班级事务" + "file://${homedir}/NAS NAS" + "file://${homedir}/NAS/imxyy_soope_ NAS imxyy_soope_" + "file://${homedir}/NAS/imxyy_soope_/OS NAS OS" + ]; + }; + }; +} diff --git a/nixos/configuration.nix b/nixos/configuration.nix deleted file mode 100644 index c3babf7..0000000 --- a/nixos/configuration.nix +++ /dev/null @@ -1,105 +0,0 @@ -# This is your system's configuration file. -# Use this to configure your system environment (it replaces /etc/nixos/configuration.nix) -{ - inputs, - outputs, - lib, - config, - pkgs, - ... -}: { - # You can import other NixOS modules here - imports = [ - # If you want to use modules your own flake exports (from modules/nixos): - # outputs.nixosModules.example - - # Or modules from other flakes (such as nixos-hardware): - # inputs.hardware.nixosModules.common-cpu-amd - # inputs.hardware.nixosModules.common-ssd - - # You can also split up your configuration and import pieces of it here: - # ./users.nix - - # Import your generated (nixos-generate-config) hardware configuration - ./hardware-configuration.nix - ]; - - nixpkgs = { - # You can add overlays here - overlays = [ - # Add overlays your own flake exports (from overlays and pkgs dir): - outputs.overlays.additions - outputs.overlays.modifications - outputs.overlays.unstable-packages - - # You can also add overlays exported from other flakes: - # neovim-nightly-overlay.overlays.default - - # Or define it inline, for example: - # (final: prev: { - # hi = final.hello.overrideAttrs (oldAttrs: { - # patches = [ ./change-hello-to-hi.patch ]; - # }); - # }) - ]; - # Configure your nixpkgs instance - config = { - # Disable if you don't want unfree packages - allowUnfree = true; - }; - }; - - # This will add each flake input as a registry - # To make nix3 commands consistent with your flake - nix.registry = (lib.mapAttrs (_: flake: {inherit flake;})) ((lib.filterAttrs (_: lib.isType "flake")) inputs); - - # This will additionally add your inputs to the system's legacy channels - # Making legacy nix commands consistent as well, awesome! - nix.nixPath = ["/etc/nix/path"]; - environment.etc = - lib.mapAttrs' - (name: value: { - name = "nix/path/${name}"; - value.source = value.flake; - }) - config.nix.registry; - - nix.settings = { - # Enable flakes and new 'nix' command - experimental-features = "nix-command flakes"; - # Deduplicate and optimize nix store - auto-optimise-store = true; - }; - - # FIXME: Add the rest of your current configuration - - networking.hostName = "imxyy-nix"; - - boot.loader.systemd-boot.enable = true; - - users.users = { - imxyy = { - isNormalUser = true; - openssh.authorizedKeys.keys = [ - # TODO: Add your SSH public key(s) here, if you plan on using SSH to connect - ]; - # TODO: Be sure to add any other groups you need (such as networkmanager, audio, docker, etc) - extraGroups = ["wheel"]; - }; - }; - - # This setups a SSH server. Very important if you're setting up a headless system. - # Feel free to remove if you don't need it. - services.openssh = { - enable = true; - settings = { - # Forbid root login through SSH. - PermitRootLogin = "no"; - # Use keys only. Remove if you want to SSH using password (not recommended) - PasswordAuthentication = false; - }; - }; - - # https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion - system.stateVersion = "23.05"; -} diff --git a/nixos/hardware-configuration.nix b/nixos/hardware-configuration.nix deleted file mode 100644 index dd00939..0000000 --- a/nixos/hardware-configuration.nix +++ /dev/null @@ -1,10 +0,0 @@ -# This is just an example, you should generate yours with nixos-generate-config and put it in here. -{ - fileSystems."/" = { - device = "/dev/sda1"; - fsType = "ext4"; - }; - - # Set your system kind (needed for flakes) - nixpkgs.hostPlatform = "x86_64-linux"; -} diff --git a/overlays/cage-specify-output-name.patch b/overlays/cage-specify-output-name.patch new file mode 100644 index 0000000..8b55c87 --- /dev/null +++ b/overlays/cage-specify-output-name.patch @@ -0,0 +1,57 @@ +diff --git a/cage.c b/cage.c +index 75f0696..b733010 100644 +--- a/cage.c ++++ b/cage.c +@@ -228,6 +228,9 @@ parse_args(struct cg_server *server, int argc, char *argv[]) + server->output_mode = CAGE_MULTI_OUTPUT_MODE_LAST; + } else if (strcmp(optarg, "extend") == 0) { + server->output_mode = CAGE_MULTI_OUTPUT_MODE_EXTEND; ++ } else { ++ server->output_mode = CAGE_MULTI_OUTPUT_MODE_SPECIFIED; ++ server->output_name = optarg; + } + break; + case 's': +diff --git a/output.c b/output.c +index 465c0ed..992d6e1 100644 +--- a/output.c ++++ b/output.c +@@ -13,6 +13,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -294,6 +295,10 @@ handle_new_output(struct wl_listener *listener, void *data) + if (server->output_mode == CAGE_MULTI_OUTPUT_MODE_LAST && wl_list_length(&server->outputs) > 1) { + struct cg_output *next = wl_container_of(output->link.next, next, link); + output_disable(next); ++ } else if (server->output_mode == CAGE_MULTI_OUTPUT_MODE_SPECIFIED && ++ strcmp(wlr_output->name, server->output_name) != 0) { ++ output_disable(output); ++ return; + } + + if (!wlr_xcursor_manager_load(server->seat->xcursor_manager, wlr_output->scale)) { +diff --git a/server.h b/server.h +index 6e2fddf..bdb289f 100644 +--- a/server.h ++++ b/server.h +@@ -15,6 +15,7 @@ + enum cg_multi_output_mode { + CAGE_MULTI_OUTPUT_MODE_EXTEND, + CAGE_MULTI_OUTPUT_MODE_LAST, ++ CAGE_MULTI_OUTPUT_MODE_SPECIFIED, + }; + + struct cg_server { +@@ -31,6 +32,7 @@ struct cg_server { + struct wl_list inhibitors; + + enum cg_multi_output_mode output_mode; ++ char *output_name; + struct wlr_output_layout *output_layout; + struct wlr_scene *scene; + /* Includes disabled outputs; depending on the output_mode diff --git a/overlays/default.nix b/overlays/default.nix index a13ea3c..0ee9112 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -1,15 +1,21 @@ # This file defines overlays -{inputs, ...}: { +{ inputs, ... }: +{ # This one brings our custom packages from the 'pkgs' directory - additions = final: _prev: import ../pkgs {pkgs = final;}; + additions = final: prev: import ../pkgs prev; - # This one contains whatever you want to overlay - # You can change versions, add patches, set compilation flags, anything really. - # https://nixos.wiki/wiki/Overlays modifications = final: prev: { - # example = prev.example.overrideAttrs (oldAttrs: rec { - # ... - # }); + cage = prev.cage.overrideAttrs { + patches = [ ./cage-specify-output-name.patch ]; + }; + qq = prev.qq.overrideAttrs { + preInstall = '' + gappsWrapperArgs+=( + --prefix GTK_IM_MODULE : fcitx + ) + ''; + }; + easytier = final.master.easytier; }; # When applied, the unstable nixpkgs set (declared in the flake inputs) will @@ -20,4 +26,20 @@ config.allowUnfree = true; }; }; + + stable-packages = final: _prev: { + stable = import inputs.nixpkgs-stable { + system = final.system; + config.allowUnfree = true; + }; + }; + + master-packages = final: _prev: { + master = import inputs.nixpkgs-master { + system = final.system; + config.allowUnfree = true; + }; + }; + + nur-packages = inputs.nur.overlays.default; } diff --git a/pkgs/default.nix b/pkgs/default.nix index 3d9e23c..02b2b7a 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -1,5 +1,13 @@ -# Custom packages, that can be defined similarly to ones from nixpkgs -# You can build them using 'nix build .#example' -pkgs: { - # example = pkgs.callPackage ./example { }; -} +pkgs: +let + packages = [ + "win11-icon-theme" + "mono-gtk-theme" + "fcitx5-themes" + "fcitx5-lightly" + "fluent-fcitx5" + "wps-office-fonts" + "translate-shell" + ]; +in +pkgs.lib.genAttrs packages (package: pkgs.callPackage ./${package}.nix { }) diff --git a/pkgs/fcitx5-lightly.nix b/pkgs/fcitx5-lightly.nix new file mode 100644 index 0000000..96086c9 --- /dev/null +++ b/pkgs/fcitx5-lightly.nix @@ -0,0 +1,30 @@ +{ + lib, + stdenvNoCC, +}: + +stdenvNoCC.mkDerivation { + pname = "fcitx5-lightly"; + version = "unstable"; + + src = ./lightly; + + phases = [ + "unpackPhase" + "installPhase" + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/share/fcitx5/themes/lightly + cp -r * $out/share/fcitx5/themes/lightly + + runHook postInstall + ''; + + meta = with lib; { + description = "lightly-qt fcitx5 theme (generated by fcitx5 plasma theme)"; + platforms = platforms.all; + }; +} diff --git a/pkgs/fcitx5-themes.nix b/pkgs/fcitx5-themes.nix new file mode 100644 index 0000000..530e591 --- /dev/null +++ b/pkgs/fcitx5-themes.nix @@ -0,0 +1,38 @@ +{ + lib, + stdenv, + fetchFromGitHub, +}: + +stdenv.mkDerivation { + pname = "fcitx5-themes"; + version = "unstable-2022-09-28"; + + src = fetchFromGitHub { + owner = "thep0y"; + repo = "fcitx5-themes"; + rev = "9d6e437289aa8de61d2c198b2e6ce4b5edea204f"; + hash = "sha256-iNOquWc6d1rgdWeGPBQ6na/bq+ZOV9cx4MCLf3SdBLg="; + }; + + phases = [ + "unpackPhase" + "installPhase" + ]; + + installPhase = '' + runHook preInstall + + rm -rf images README.md install.sh + + mkdir -p $out/share/fcitx5/themes + cp -r * $out/share/fcitx5/themes + runHook postInstall + ''; + + meta = with lib; { + description = "fcitx5的简约风格皮肤——四季"; + homepage = "https://github.com/thep0y/fcitx5"; + platforms = platforms.all; + }; +} diff --git a/pkgs/fluent-fcitx5.nix b/pkgs/fluent-fcitx5.nix new file mode 100644 index 0000000..6bfbece --- /dev/null +++ b/pkgs/fluent-fcitx5.nix @@ -0,0 +1,37 @@ +{ + lib, + stdenv, + fetchFromGitHub, +}: + +stdenv.mkDerivation { + pname = "fluent-fcitx5"; + version = "unstable-2024-03-10"; + + src = fetchFromGitHub { + owner = "Reverier-Xu"; + repo = "Fluent-fcitx5"; + rev = "e4745fd598ddfd4b26f693cfb951cd028575a1f0"; + hash = "sha256-tVPp6kFgsWlSLcEUffOvXCWDEV0y7qcSqYKQkGO7lrM="; + }; + + phases = [ + "unpackPhase" + "installPhase" + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/share/fcitx5/themes + cp -r Fluent* $out/share/fcitx5/themes + + runHook postInstall + ''; + + meta = with lib; { + description = "A Fluent-Design theme with blur effect and shadow. "; + homepage = "https://github.com/Reverier-Xu/Fluent-fcitx5"; + platforms = platforms.all; + }; +} diff --git a/pkgs/lightly/arrow.png b/pkgs/lightly/arrow.png new file mode 100644 index 0000000..a9061c1 Binary files /dev/null and b/pkgs/lightly/arrow.png differ diff --git a/pkgs/lightly/highlight.png b/pkgs/lightly/highlight.png new file mode 100644 index 0000000..2bdb86b Binary files /dev/null and b/pkgs/lightly/highlight.png differ diff --git a/pkgs/lightly/line.png b/pkgs/lightly/line.png new file mode 100644 index 0000000..6652e59 Binary files /dev/null and b/pkgs/lightly/line.png differ diff --git a/pkgs/lightly/mask.png b/pkgs/lightly/mask.png new file mode 100644 index 0000000..73b6da9 Binary files /dev/null and b/pkgs/lightly/mask.png differ diff --git a/pkgs/lightly/next.png b/pkgs/lightly/next.png new file mode 100644 index 0000000..acda0ef Binary files /dev/null and b/pkgs/lightly/next.png differ diff --git a/pkgs/lightly/panel.png b/pkgs/lightly/panel.png new file mode 100644 index 0000000..2db821a Binary files /dev/null and b/pkgs/lightly/panel.png differ diff --git a/pkgs/lightly/prev.png b/pkgs/lightly/prev.png new file mode 100644 index 0000000..9c15472 Binary files /dev/null and b/pkgs/lightly/prev.png differ diff --git a/pkgs/lightly/radio.png b/pkgs/lightly/radio.png new file mode 100644 index 0000000..1279edc Binary files /dev/null and b/pkgs/lightly/radio.png differ diff --git a/pkgs/lightly/theme.conf b/pkgs/lightly/theme.conf new file mode 100644 index 0000000..f0d9d2a --- /dev/null +++ b/pkgs/lightly/theme.conf @@ -0,0 +1,98 @@ +[Metadata] +Name=Light +Version=1 +Author=Fcitx +Description="从 Plasma 主题 lightly 生成的主题" + +[InputPanel] +NormalColor=#282a2f +HighlightCandidateColor=#282a2f +HighlightColor=#eff0f1 +HighlightBackgroundColor=#526f95 +BlurMask=mask.png +EnableBlur=True + +[InputPanel/ContentMargin] +Left=14 +Top=14 +Right=14 +Bottom=14 + +[InputPanel/ShadowMargin] +Left=10 +Top=10 +Right=10 +Bottom=10 + +[InputPanel/Background] +Image=panel.png + +[InputPanel/Background/Margin] +Left=14 +Top=14 +Right=14 +Bottom=14 + +[InputPanel/Highlight] +Image=highlight.png + +[InputPanel/Highlight/Margin] +Left=4 +Top=4 +Right=4 +Bottom=4 + +[InputPanel/TextMargin] +Left=4 +Top=7 +Right=4 +Bottom=7 + +[InputPanel/PrevPage] +Image=prev.png + +[InputPanel/NextPage] +Image=next.png + +[Menu] +Spacing=2.500000 + +[Menu/ContentMargin] +Left=14 +Top=14 +Right=14 +Bottom=14 + +[Menu/Background] +Image=panel.png + +[Menu/Background/Margin] +Left=14 +Top=14 +Right=14 +Bottom=14 + +[Menu/Highlight] +Image=highlight.png + +[Menu/Highlight/Margin] +Left=4 +Top=4 +Right=4 +Bottom=4 + +[Menu/TextMargin] +Left=4 +Top=4 +Right=4 +Bottom=4 + +[Menu/SubMenu] +Image=arrow.png + +[Menu/CheckBox] +Image=radio.png + +[Menu/Separator] +Image=line.png + diff --git a/pkgs/mono-gtk-theme.nix b/pkgs/mono-gtk-theme.nix new file mode 100644 index 0000000..9668532 --- /dev/null +++ b/pkgs/mono-gtk-theme.nix @@ -0,0 +1,40 @@ +{ + lib, + stdenvNoCC, + fetchFromGitHub, +}: + +stdenvNoCC.mkDerivation { + pname = "mono-gtk-theme"; + version = "main"; + + src = fetchFromGitHub { + owner = "witalihirsch"; + repo = "Mono-gtk-theme"; + rev = "89fa83a14b4e26c5b8fc4dbfa5558a7df704d5a4"; + sha256 = "sha256-NaZgOOo5VVTlEand3qWryZ5ceNmyHaEt0aeT7j/KwvE="; + }; + + phases = [ + "unpackPhase" + "installPhase" + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/share/{Mono-gtk-theme,themes} + cp -r MonoTheme $out/share/themes + cp -r MonoThemeDark $out/share/themes + cp LICENSE $out/share/Mono-gtk-theme + + runHook postInstall + ''; + + meta = { + description = "..."; + homepage = "https://github.com/witalihirsch/Mono-gtk-theme"; + platforms = lib.platforms.linux; + license = lib.licenses.gpl3Only; + }; +} diff --git a/pkgs/translate-shell.nix b/pkgs/translate-shell.nix new file mode 100644 index 0000000..e74615e --- /dev/null +++ b/pkgs/translate-shell.nix @@ -0,0 +1,37 @@ +{ + lib, + stdenvNoCC, + fetchFromGitHub, +}: +stdenvNoCC.mkDerivation rec { + pname = "translate-shell"; + version = "0.9.7.1"; + + src = fetchFromGitHub { + owner = "soimort"; + repo = "${pname}"; + rev = "gh-pages"; + hash = "sha256-YQevXwslWzHen9n+Fn0a+oNx/EKg0Kd/Ge8ksYP0ekY="; + }; + + phases = [ + "unpackPhase" + "installPhase" + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/bin + patchShebangs ./trans + cp ./trans $out/bin/trans + + runHook postInstall + ''; + + meta = { + description = "Command-line translator using Google Translate, Bing Translator, Yandex.Translate, etc."; + homepage = "https://github.com/soimort/translate-shell"; + license = lib.licenses.unlicense; + }; +} diff --git a/pkgs/win11-icon-theme.nix b/pkgs/win11-icon-theme.nix new file mode 100644 index 0000000..2ef1073 --- /dev/null +++ b/pkgs/win11-icon-theme.nix @@ -0,0 +1,46 @@ +{ + lib, + stdenvNoCC, + fetchFromGitHub, + gtk3, +}: + +stdenvNoCC.mkDerivation { + pname = "win11-icon-themes"; + version = "main"; + + src = fetchFromGitHub { + owner = "yeyushengfan258"; + repo = "Win11-icon-theme"; + rev = "9c69f73b00fdaadab946d0466430a94c3e53ff68"; + sha256 = "sha256-jN55je9BPHNZi5+t3IoJoslAzphngYFbbYIbG/d7NeU="; + }; + + nativeBuildInputs = [ + gtk3 + ]; + + phases = [ + "unpackPhase" + "installPhase" + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/share/icons + patchShebangs ./install.sh + sed -i "s@shift 2@shift 1@" ./install.sh + ./install.sh -d "$out/share/icons" -n Win11 + ./install.sh -d "$out/share/icons" -n Win11 -a + + runHook postInstall + ''; + + meta = { + description = "A colorful design icon theme for linux desktops"; + homepage = "https://github.com/yeyushengfan258/Win11-icon-theme"; + platforms = lib.platforms.linux; + license = lib.licenses.gpl3Only; + }; +} diff --git a/pkgs/wps-office-fonts.nix b/pkgs/wps-office-fonts.nix new file mode 100644 index 0000000..62b41ed --- /dev/null +++ b/pkgs/wps-office-fonts.nix @@ -0,0 +1,34 @@ +{ + lib, + stdenvNoCC, + fetchurl, +}: +stdenvNoCC.mkDerivation rec { + pname = "wps-office-fonts"; + version = "1.0"; + + src = fetchurl { + url = "https://github.com/Universebenzene/wps-office-fonts/archive/refs/tags/v${version}.tar.gz"; + sha256 = "db01fc07324115b181cb06f50dfe09fd17feee132c46423ee70b260830211224"; + }; + + phases = [ + "unpackPhase" + "installPhase" + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/share/fonts/wps-office-fonts + cp *.TTF $out/share/fonts/wps-office-fonts + + runHook postInstall + ''; + + meta = { + description = "The wps-office-fonts package contains Founder Chinese fonts"; + homepage = "https://github.com/Universebenzene/wps-office-fonts"; + license = lib.licenses.unlicense; + }; +} diff --git a/secrets/dae-imxyy-nix-server.dae b/secrets/dae-imxyy-nix-server.dae new file mode 100644 index 0000000..0cb73de --- /dev/null +++ b/secrets/dae-imxyy-nix-server.dae @@ -0,0 +1,19 @@ +{ + "data": "ENC[AES256_GCM,data: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,iv:aivrfA3CZAPWjxH46HWX9a8qredn3d+Qglrl3JWjfFU=,tag:SLr83SfB5fxGzGNaiiXVoA==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvaVp5OFFWVE1MTVY0Y1Rk\neDU2RGx2Mmd5dzQ0QzNkZ0tVbEZId2FCUmxjCjJLMjMreS9qSm9mOGFIMjYva3JQ\nc3Q3dVVOQ05kZ2dzRFJ2TXRndmVyakkKLS0tIGFuSExTRTUwbE9Tc1RTWTVkTmFJ\nbkNsNHlSVmtzWWc5UkpVbG5KYWc3ZjQKb16GEKfjt8nue0DKk27gwVoMpSPweJdT\niBwcxBVI8Bv64yTuA7Kx+TlKBviCykjWcnyl8AmQ6n0nkgzZpXkPZQ==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQODJmQUwvSVUrSWRDdDVI\nZXdMbkNiakgzYThGckwxdGwyYjl0bU50Y1JzCmltNDBwTDFnZGM2aXFORUc3Mm9P\ncDl4WGZyV3Y4T25DYU01VEF1anZ0TmsKLS0tIHNjcVJRa1dPTmJSanIrcFY0QmI4\nc05EaGZBaUVZcUQ4K0NlTTkwV0Z5NjgKNBOBTXMC/b3xZBVQe9iAzkKkpxt8WuG4\nChqVrxqk5cVAUuiunjGFVSd4YpRJQ1J5TdVPsXrEeDs0lBio4ssk1Q==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-04-05T04:26:42Z", + "mac": "ENC[AES256_GCM,data:3cGHj5ZWLtW0NW7j+fAO6r0ke2P9qgjJScYXZgOX1Gs+bh3ylORnhqdfO5+ECy3BZRZOMK9XbGnI9fBanjkiUy3O9SyuvsO62TWIirwg+zn5JqEbx+A7Hr6E9u85sR+i5UEpQ0uoZ8R5k12+CUjr+QURCInQWn4qplAXGR8ohrM=,iv:qSf0vdVeH7UK0lwDJo8KT7u7W4breIup7AdXCZy65Sw=,tag:qxl8BUH0jnynBUg14Qb6fQ==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.1" + } +} diff --git a/secrets/dae-imxyy-nix.dae b/secrets/dae-imxyy-nix.dae new file mode 100644 index 0000000..78ede32 --- /dev/null +++ b/secrets/dae-imxyy-nix.dae @@ -0,0 +1,19 @@ +{ + "data": "ENC[AES256_GCM,data:9LDa0hSacJt1yC9EFPkPSG20zuvKBPQycuCzhjxmJmXvi2ooxB4v0R+xkC+5TD662IECvTbuEUhGJiD9tBKkrGP4FBuKUz+y7IbHSBTK0hIwr0j7/BKJM/LpQwF/kZbXBVwq8JsQhcvwFljaZpAhRkO8jErhvPXqTUDz8GHesCiZfjqxGVGR/mpkp4c2ayXyOeRdDwQfcpNAohxOi/5amhVTheW9uxBJ6UEliA2VfG4VgdJF5NHq3fZZT958YheGrJ2uRuSngConTAIjXZhRN5ylZkxzbMTmRaXELNdCh+hehhLuBnM/hzVGB+L9bT4bE3rzWNscA2drsKxhl7FPvQi+q1nLqH7g3sEIRFQ91go0GJ8kUhyon7V++AYJhjO4/gMF8CeHUlGwvqtiMfZILSDuqveWwdGPGar+A/btJDkR07JvaUBbEmXdYH1AUzlAcg3q9Gmlb8JHmQfSziXJMrNdIlWIYZfKcPzgBXBpIoKt+NkHhZbQBaCyUEnd+bdm+6es1lK7MUreU3fY5C0r+T6B/b4NWQsKzRjwc53+FW4RBa1AjGZFd+mNFjJKNZDOyfVBaSDwdOQzwolShC8/eSoY+64cDxwshAWfgT2W0F0SVus10KkV+uaYqsxpGKZZEFqY0IdzTKNjHwWACIpZwpeixSBiNSdgGTaG1SdKXxmVMa/i3qIxtRL9KGwVXNzVSS3gAPnjbAnCfWn9zks7j66H3t8d8Vv4Kyl/KYuceUgApfRMZLjYIlftFfeDfWqpwVgirVFMtiMeIodrJoBagTCgxJ5FpumeUW7a/G4igU86vGR3HlAwNBy5FYc38nY2P+edPRGaDBeEqJP2rZ5twyeSKhhMVziiba12sBZsP3U1JvnGf4pjt1/xxVkd+xEmxDAuUGCAAk1CjtckV8qhi7MQA11lS73ly9aDRVeEUnXSFKjvaaY2DWC6zQZm2y/AzRxolmKzO65XGLy4ouz/p1TLMrVcMZa90Zbx6NfJZHGfHd/DCRD43WIaAULanDx6A5R8jzRssSCinNoXD8TepL9JP3Y+osPR3uLJ3aZZjlfNoXNwqKdD0C+8Ld50+qesH4ovAfReTsK7N7IK6F8CAUZCdnp+cZEM9AvYWgCn4U3rJ368CTC6os5pVdCPodKvG3HpkXgAmosaU6I4ERuwdlvQvYrA98LeAd/2KxCSmtIMVLN88Aq1uIDPUv6g7JGe+X/5H7XP4SAo1V664LMY6HpVgduTBBEaQ8rDoCbr6+Nof9skrwZ0pmGg6/zr1i5BaVWdl4KpYmAe70HZj66JZp0NpnsyUxhTIHbvxApOZ6E71aDPbLZiI4I06y1Tpysrc9tCKdoJH8e6J2DVrAba3MrS5zhPRTnqInS9XYynDzUWVHFXnaCTJNpqO49BYh3nScHsTko0SzOPjULBVeo69+z4b1R1FRJAG/196h0NwJ9SQLNONcFEqxdwaiE6Hm87CumZs0pmg0DH+rhzeUwXgalrIWOQzpC4Aycrcj0YAcXvf/+rM8+cKum8YGLH1ub+KaeN/1vMEAzVL+8BAJNHkc77GI+4s1T6aM6/x70lVS6tTIKDvhuslc8x1ofcbetDv8obC3M/OcP7nXMo6VC2jVmV1qOjnh9SfOI2gLEm7/COt3vgZ30sE6ASh+sjIE0GAzuWARJW7yLcOfdSxcJhi85JiI9ZyPhe8ThGc6p0nPQv3aaH35AkLS/GakJcpXoPychkP0ndWpk8nsgnDW7i00dLlifQ+4skKgcVaB/PJW/r2Y5w4dijPZa4F4l46Kc2n5b4/qUwP+xZIpksulFRmu6L/HbJIA0pvfgaS99zREMFWFKp1n6ySZWjolBOg4OrcmTJslWmS3iiBohk6jwrB30KP/EswyhaEv8AtBp/icFrm0NCDYdLjrR6VXVi4/9PxUowGyi3r9UmBeiDjAMnY0+Jz2CL5mYutUnTyZSCU00LsWZXy7SSHYZ2d4xAPkOGnv298KFNVQPlHZWq7XGH/brMSXgPEfjGq/PQTQlvXVuMqo9c8NuYrcVk9QtG8INNz/SdAEsGYlB75kTT8I4UMbg3Ql6QOZpeEULmVG6okP02/U/VeX/hgNvmLP0/c7+nkVCFrkYR6QBIyDIS3kKJ23IBO663hhAyASstfpAvGCvNDzY1mIPSP9DcK6n+8qKo7kadYG06TjnFcb9dyOaUEa9TnG36MvG/dUMWiAc061efQ+9voU3vCyFWeC+s9lzjS5wd8Pd2LQBhy9/rsLpX5gQnnu2i7Js6hcthSAHoszbFQHJxs4TmDMzc2nTPVPt6wAVgNslD+LnbB4FUL8e/nsKks5gPW5cM2oxDxqwbvmGOG84l6CzBzyxMXIkow60NnYRV/itQV6Rvnt1EMJrhPhJOM7VRKRueo0AW15Szptsu29LWm/H/QE6ucpwNjpeZH79/Oo1OBQVGUdEXcjrmmej/DDUq8h1/Sp5beocxF6INZ90Z4xssUzYhNwdsM26FCcB97Thi8PHbg1q9jztpbdZwQRcj8Aw2Gp+4khmILgnKlIx1z1FYsePDQi+FCmIrz4ZUdUbp6N3i2iGQs5+dipPDKHzMfcl7Gp+b6GEopULnE6FNCfQ3zJ/g6cNXxEvhaXjrTcTDgcc4kozFTAO6bj/3y8v7e+PIFfu8+8eqEpLOTjqiXRwfpb0jUbe6NcMXVo+0WMMNTWrFGTMnurVUdmawV/pDiYjIhSly25Lfnnkz8KqQvLts0tqkZGebOSB5F44P7ycUAz+PfxiFbPe9Hoz/DkMrvpsfkDuN8rnIFpPaK9R4a5DdUPo+Pb7281MC8KO/nZLRMPrWtS3yysRwR2QLyqu+T73iAa+7xpDAxDVZmHI7Eii2g9dUZLJSBD0AqvPAWnMh+r4VEdXJy9XORREfao5tcGUZUr5/XS0E+Wb+lpDNE8UaMGrXDxYDM0bJ51aSC9VC6HDUEhJgOQXC2y+0lXDU5zlh+gSyR4wtFLShFt5iTvDBWconIVsLo64AC6jZvhd3RRyX+e6UBQfW0kRu2PlVflKDfjOSbHUEeFEA9xREM0XjzPigYFBhUqlg1LdAO4zFX/KNREUTZpQP+l6hRtWiiBFuNdoedd/bMZahlpGIP9SEV26ILPz/r6j3xdrPGj6tn0coIjU+Np4uihYMFwiJy3XD+0k5+/MlyJLvSi4d37SlRFVLr8iQQJW1jmUKIHSeyFe8Ueo7b3hIe/ntL3AcS1ibC8f8SR0sNejiC3OVB8gv2EikUFzJfmMOhG5x8dk5zb28pKph3apKtCP9X/fGzJ28qTuL59m8htnw4FUbx4/GdK2N5Iq1gp51EWGIDJNFz4xXGf5B8+EU/nLl+8ASCl7dxZENxIHawm6E87/lZhAmAiNXpNJYwJ41u5Tf5CSjWPhkcmieAWxGGStRjdAQBpiNluHF2xAhB7K4o/nqLr9UDzlxDmE11pL7PkuuSJN9PbrBM+QdNgDYINurjUefpzRdUWA8g0UYVrFS5r7AeG52xodEx645qJsBPRCm6WbJAI1Y5FJNMiXt+SRjErrQ4Ff8S6iabf2p0Oe1JLjRabOoXfO+sNUoYRu1QqriFZOywi6AOzVZ4hcA2DCXlvSHl7DbK7bsOPVq2ZGb3H9ZdgpB8UBKf2lDw00uJKGQos+I6Q7GxE5N0VVL9rHQsh7Mg6CqEzRei+N3gCHrOf+t0hlO4uoW25n3m/jnvkoO51jHj/9jWElhNcN2N44z/h6sibRbpVFdeCi8yhc6KHUogrwLgyoUHX/Ya0BMAVOalFJvfKU1pq+Jg+ykxNxdc9QnyoB3KUE8CYIf51FWRH1gdffsD2J222gSdzS+SxJfj4FhGe7cVSNjlmGyVlgYh8x+qi2KWmBCvs40CrW25pUw7p6nJeo0wNucXeUGd59uaBsQlbJLVOTG7X018hkuzLIeo9HcX8xP6YSVMx6/bvwvq+5Jxoj8dspV+kPX1/Pu8WmQqm0n+L9uYHYZb4Zwi016sPLgWq3CmIzokmqMxik7peupgQqNza3h4JHgAUjIf7j7zcJcrLRyXATfCSYeMeDLSSQpXMssbbrhKLVPWt2+26MloOkjaViN/g+Qgo5vEZh/GNf6imNwRNTihEaHpuhsHEM4tsxKEBlZBewbOfzfgUIKypAd12PTe1d/LWbhRwjYwDpLWAiWiOhIii7EEeXmcB3jafgBlN0Br5Fkp0J2+P4KdDuaso2R5QhkfcBbI2gsror6THiG+p/v76eDj9r7shOxY/LPnkx6EZYdy+QYyj/2JKRo+HcGBmJsuKbe+qohfooN3SNZ1rMINLIkEZvjVCu2uutRIW3CGUr9jg5nQ7R8jAdeo9Ayudsl355EALefaB6uWDOCjgKT+ag/lVD+NWUQuPKmBQ9ejuUDYK4UrQ9X8z3yl9Qa//q7IH18QdLUoYIWb5iGwxW5AllC+TtlEskdce+kCXWwVfbvNSqzbRUrCmtEykOs78UjVj0FRORJc9N4MuB8hVjZLkVsW4udhtzUn3msRrulR8j8X9GbtnzeFySVnPZf0yxTwI0FfkQzyz2V4KFMeBSsEL2MjbDfzh73moXvTeLegEAahK51nOQVZp18/vnbU7uLgOEcC4IeqmUwMwGtNaZozKVhhscWXMZWghBmp4nJ9p4T7C/zVzYt4H5yrqvtLB3wfYCMAo9/aYm3FEUT7rSJwY3dTYzHp3qid1aQE7OwAM4Xbb0dcuwNxRVAF8wTD8OynjK+ITiU4VEgr8faswPAAW28ul8HAiNzTKG8yCLdW/BwgpOq1AhVWqET24C8cTTqRpBEwkyu1hQf22ejn8Nh5bUcf3R8ZbiPvCtC7EQ+WN4ETxzNh2KuaJQ7x7i+hUvLPMeL0OzhapbVoRrjivm5MGaWWhVdp6+yueslf+2ak9/b2kL+v7UFF1mviJY7JBrc658wHrFZZhX+8qDopnXOaNiW9MMSlwM/KLkc/t3aLE3AMok0cGDpKzf+8O90fxpmuD4z1jjMwti0rWAxnawJXHkgVoA4BsM8bthgxStCOnC94msUwWjdCxXYBkg0XBouDMPS0MeLI4wxW+JuMJYqu+/7vNbtIvHIbgzbUfCJeI16AHxAKgR7DhXjiF1j2CN2S9T6YaliD2jSidBayiUg90Zabr957qdxKkYnr0v/xSOOBmV1yKT2yalvRPJFe7Ukwf8NHyrhDBFDztAShOj9ppfb2mQBIDPaOX/Jypup1Ht5OjfAAxVtyPadern6Ar77SEUY3AUyjl3dpBIMDxxx4dJJNvZUxVjWuvqAaruNeYlamTh3okK8m8gHtcVavvoDv9ATOIyjPH0AvJPOmOj/vc2v4Fg4ddEPgumAmOAo09dOtOyuMCD9FnMaHN1fIoGw+5p67oaoEgVDxn7mHxRMgljcd83rQPMQAW67a7+LyvhhEE7pjh00krQGJgZd/JQRZjIbc6uTk/t+tAb1H+Yjn0QbThDK6rgrCIkB75fKREpbASkX7FweSj3uHrFeUHNr2AtOnJmbF+8OzAAteuinFKWt4R03GnhWpm+7zQT3jPaLW5Hj0EteH0xOszBmdxFDh0D34LCX1Gx346JzlZjxFCvcBSkYydxKsAvPLsVPxd6RvX+4nsH9z+jfO1D6L0P/LBg6kIQno3p6IXA4sCkvW5cRvobrtduKyvkkGQoss08KCxu+OKdagnyOVirB2BOma5p0vPM+/iM2GhNhynzBX8/toDFiA2+NLt2Nj8bwJosI2Eu4ZYQeetwbWGtGzCMEAWWMlcuO5fDzPyVMKHDympp7j0UbRwLUXJvB5O0RNkyJNZ2XI6Ek7IVh9dKxKxV8r1HwRyGWBxDs4yenXGKB6OhUX82J/3ZCt5FkJInIh5wvlenb1ChvrpqbQ0AzmzYSiQy6UaDpEvYqv5GIJLVH3Izk8RWhajMtVLtx8wLarmUAeFlFSaCYGyLQhsCzi8r+dFx8k08LDQh9hpNpme3cPZb/dvp8lPUjA8vwCQUB2Vswpyo6W3W/BdYzF2nkVGVvCB3+/m27XBW6lVH/TjFFMntyN6G+Fx19NUzce1oSXhGyaphZLDEjizlKYIiYAzN4cIRV3qprUrSdwQ8Ml/4miJCHdJkznWXvNkJ9ek8lxIV40LTOl9HwG9remG5XI01quO1yvkCjATTgtiwTNJKwB1jHDKZeqVOwQLNB7uEI60um7r7bzDzeYnCdKJnp0Mqfiag+XreJy1ETiyIoKDx74bwWzGJwtjNzPh38fQ==,iv:3IaiR37d5TerXzSWoclNfiE6B5g8WV9dofx3uFS3CRs=,tag:s90ko19cdocIUoqCR0JIcg==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXME1YNmR5Y0prTndLRDBL\nM0xMaUxQbDB4MHZOQXh6SmVUSGpIOXp6VFF3CjU2UkZldGZMbCtwbkhUZk8yU1RM\ncTJobG90M2VMV2p4WCs2SEdiV0s3V1EKLS0tIGRlSU1odG1PRGJwQVJTVkJaLyt4\nZEdoeU03VjkxQUxOcGI1cTB5dGEwWDQKijyeTfFDGkDsU6H7AbKICH/or9q/NSoP\nltlo84+8osICAOaZ8mx+HZGmSHSPsWCbGJkokD8Y7NhO8G8IwQA+vQ==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaSi9TY01tbURjcmxqMTY2\nRUdPZU1xb0F6QlVObmUzL0VZWE9QVzBsQWlzCmw0d1BVOGFVQVprNW9jOFNxVjY1\nekxpSGZIQ2VJMUs3Q21LTWVsUG9JWkUKLS0tIHFRSXBZMTZUZ054SFlRSjV1eWlo\nZmtzTU04TG5RTGhCZ0hWUUQ3TXk5aVkK3aGcAWAJwh4xDX8SkoPWW9NttvxDfgy3\nmZ1pV6LS4i+0CPddc+qxGsrOpxMokZE+th4yU3pAVCn5c5cnOfSSVQ==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-04-05T04:26:25Z", + "mac": "ENC[AES256_GCM,data:iqbpnwKckPsIKAZrZNPpuYA+lst4t/Uq5tXOIzM9+Pt66YXET3WX8QEkG1lXBq4vK+49oFu4xaGyEp7tyezDns5t4IrgND195nPkRX9P6Joi+fYXhQ9RY4+ogpaGQ0qYqrAo2fgbsZS6V3/QfpKYrs0z0xdY4spcvHfqeLARjY0=,iv:xkCwZ7hSvDA9I5cSl5jF1Zx/ULPQi3W9OGJsoqGJuWI=,tag:yeZi2UXu17fmqdUpeLAs5Q==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.1" + } +} diff --git a/secrets/et-imxyy-nix-server.toml b/secrets/et-imxyy-nix-server.toml new file mode 100644 index 0000000..e066643 --- /dev/null +++ b/secrets/et-imxyy-nix-server.toml @@ -0,0 +1,24 @@ +{ + "data": "ENC[AES256_GCM,data:QfLWRYmj6TwA4uad+lZ9HfDOpzMqafIUxVhh97bsfl/eU16NGcm88NhdqFixzfGKY0jcGg705Qwh4gGSTnNg1zbdPCX/Id6rgBHhUR/XHYe0qrQ2iDaX4t9NqmlDOlnkHJa/ApaddzEZm/Y5NJqJA8X8F9A8xwNCw0TWuAlok3Sb3pxRNhKjbU+76lGpk8xr4kX/E9PKtvwVCzNtPqo7gQlwVcxDlwTUe2rMkfOpc/CfQpJOieDdHnQ8SYoatwgG+sBs6UOjASCKra3OyjhglwSseGCINybtCfqmATrb/iWpG9SNa5PBwjm8zknOJWAfwN4o41ir7EK1Uuovcuqh7EnBkVAV6ruTiMvBuOVCzK0Lgktcc7eI4VqgHuNs8172rb2f54gSxu6K4uzG5HtabJEuOG5RLlOt+3k+ewYLC5zSONPnwbHqMM0DMXyv1P9EC4hpoEaDtN7RLTiQBgaP+e0dZaRMjBbnyQZI7AFXdzCpbCPWIcOqNJCs0946lNLevnsHBo5ymBX4YMLBrHnq/cjo01MpeOJTgieBTFmWLFy4vlXuESmplp0SArESRSNrKVMTC5a7U4OkbsKVD/kzzgQaDSqsrhYH26bcOsQqklcDswOdfItSileLQlFcUyGBjh+MetoH70H4WYlZjahqYHk9t0sPjMs/0JjABfakRSGv1eymc7sxF4OFrEIAG3hU98vLphtvsUbzdQM=,iv:hP3NaXOz963dor2/ivyBOEN4yzr8Jo/lGMbV1lA861s=,tag:2BANLVtI0nYZC6S3ZdJsBA==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxdXlyZjJjYzNZdUUxMnpl\nYzU2aEI5QkdrbG1uUkJvaWozSXMwbU9DZ3cwCldnbkkyaVFOaW5zT2VITjhPcWts\nUnhSQm9nV3lXREFySHFzUXpJM25ZUGMKLS0tIFBUcW5yQkVrUmdQRm1pcnhOWW54\nZVM4eVB5RkdBS3hpK016SGdPSWVZUTgKDTUexW0QKzsYa40aJgghLt080MOkAIKt\nvSsQZoRU9ArFI4XqPy3b1BmKZKASGb8AM7KdxkqpwaA1tjLaHV8CIQ==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGTUZjN0FqbUtCQ3RFUlZL\nRXpSTmRWZ2hSSEJIVDdwMlgrc3BPZ0RIQVVRCkNKa1hKSjRoTllXZ2VuN2ViZ0xM\ndXNEZzNlOUx3Unp1NFp3SEk2UkdGVGMKLS0tIElnMWNBUDBNYmdLSDZjRVhXckpZ\nR3lLR2xRS3BwV2J1bXR5Nk9tbDdSdm8KHyGKvn9lyigNTDx81dRYjdtibxcfmpeS\nzKI8bA6nSyFqvweXlxxRchC1g3v8NGjMEMhin14lKyIzBzsfqoULAA==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-03-02T03:25:42Z", + "mac": "ENC[AES256_GCM,data:nfLHwjKLtiabq6qEhnFENrwPIH5Aehyng8Nkl4IuBc18fjSEmFkktS5U2lJaAUPNCvLoSA69icGTRk75EflyHXGx0w1j+EwTWD3/OrNxyEr6z4gSLNxJkGRjMJjuILhkxJ+UU6X7rCqEjMCuvUz8IjGL3llPBnRTUb6s9ynIGCo=,iv:TspuM0wfklVl/yTsv+/iVPNsT+AuJ1gJe3nLia5cD+8=,tag:nt+ZJZfjWzlaByOxv5944A==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/secrets/et-imxyy-nix.toml b/secrets/et-imxyy-nix.toml new file mode 100644 index 0000000..e899f83 --- /dev/null +++ b/secrets/et-imxyy-nix.toml @@ -0,0 +1,24 @@ +{ + "data": "ENC[AES256_GCM,data:ejwOSJ4303kClavS4NqbhFRjSPscnxeXeF03Eo81Nq29HziRPMeFVGLuSP7T6DY8a1MEtFd2Rd/OAfcNP5cx5WxsmwMDeWJuuZ0FDFtH7eRpbvwEk96nqWiIVUFA+GejRr9OL8o8Y06HnZ6wHQfrXSJeFA0d6Vs5VJQExj1SWGbJNPe9uKmosuq1exi1QEr0dHx+/T0YXB5kNH/CSJw/sSi4C7yaNu3+nKRy3JGGz1X+mWYQIsAEHeAgNGU1CDH/UiayTQpQL3QeJFW9KXANDm4afUWVNLtKOEvQco7c7yigIAmAmv8JpKVqHcHrbv5+shph+FPdLAjIU3+C31zAkCaRNJd1XmUC3ipldPGmvxcMC8W3vb2qmrHi6YEWY9etCli+w0PtMtH5zbC/gnCNeZ+/eQPNiO244oWAyCNVods3daQjv9RU5ZJcEh2E5xFLUc7lqiHhwT8p5AQJ5KVASjIxVxzUpzH1YCdIVjTUxFCW2xOfKIqpNPsKzeWkwrM3+5vrJkHpONGX63WcrK/oyIAgHiREkAJAS2SMXn9KzvkeFSnPxuh4XZTsDN+i20kxkGjEPdiJ2DdTVERp0aWE3NLJj8euBW+pxmkC6dS6w3ss43PrR4Nc+a2qMBHmOe3UNDe3tAwX/SyU,iv:tTztR8DMMKcV97Fn2tVk43jDDSzYVzHP5SE4Ah7TjTA=,tag:4xi66fK5/Mv6fh75Gff0HQ==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNWWxRK2VHSEtmQSsySUJ2\nTW5kbGYwa3o4N2hLU0hzL2NFeFJucmQ5Z2t3Ci9NMkNBb1k0RjFiaE45QmxmZDds\nclNZU2Z2akdlbUFCS29SamQ5cERDQ2cKLS0tIGNqdWM0dWJ3R3NZaHljeE1YVEVa\nZUd3Z1ZzNmhHOXFhTVBMaVEwR09QMFUK7iYM3Gc6rBd9wLJMeGGsbJ5ydUn+FnM+\nFJE1fkjXQckFvk0rO1kXKF644cbLagDOLTQEsRoAwL/HHOchFaFnKQ==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkU0NYT0FrbTIwZzJNZ0gy\ndW82OHZkRnB0bHpEdnBXNFZFeml5NTFrU2tnCk90UmZSWklVdVNFSUR3WnFCTFlz\nSzNXT1ZRRnovZXdiZFZmaWtLUVprbVEKLS0tIE0vTE11SmtsakdFN21XTDNPajFU\nYUpNaWRYTTVWNk5EQ3dXTjlaUjd2TlEK7tAAgMuOphvHmlST1WZsF5A/Fni7+KGI\n6v3x3Ec6HLkZm0dvbdiIvXxQMCJZTn7ltxc66XGziO+nherTmI8dwg==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-03-02T03:00:34Z", + "mac": "ENC[AES256_GCM,data:aRyMLpLOd+0lea0rvBsmUkB7TICyLERl0U1hYjadowIWhZsv5ZdrppAwpqljnqAcgnAVqMMLVnwsomSCJCuslLV2i5U/5uypIMzQR+8pFy5l1A4bibuUxqfFl/gQ9LtdqWnXg0QQgu2/KSVFvQnRN7/5QiOs2ELyeyIQi/KAQP0=,iv:DEqMTuabm+S7JuxxRD/T6AhJDn25MSDEaVsU4Q2to1o=,tag:gZ/+hGS0xyTuPySfF0Jtug==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/secrets/flatnote.env b/secrets/flatnote.env new file mode 100644 index 0000000..173a9b2 --- /dev/null +++ b/secrets/flatnote.env @@ -0,0 +1,13 @@ +FLATNOTES_USERNAME=ENC[AES256_GCM,data:0PQXYoefoXiJZ0uC,iv:ZMDEJBDEz6a6p6ZMN3fHCuOV+KhBlsPB449Yd3XoP7o=,tag:uYuqobQom35xKi+GHCbmpw==,type:str] +FLATNOTES_PASSWORD=ENC[AES256_GCM,data:jC/lVZPDGvcYzXhdnvjs,iv:0O6nNNlWjD5OWIa2ovp2wGqtjtelOLH46dFTpVH0XLg=,tag:H/fSfzI9suDaRgz8Hz8XUQ==,type:str] +FLATNOTES_SECRET_KEY=ENC[AES256_GCM,data:I8zrSTMRnPNWn7u+KZiQW2YdpAkKOBxRKv7ov7dLLNA=,iv:I4YP4KqyMR6jfofEdYxQ+I9PQjTNQwCgnTUfHnDW55A=,tag:P7QcugaQWMCfb5+G5JdMXw==,type:str] +PUID=ENC[AES256_GCM,data:ZA==,iv:xfnOzfWvf7gozw9YMTAw2uarfsGHRpx3rsEN5ja1k7w=,tag:yuXkWMkXAUpF7h+AaYW14g==,type:str] +PGID=ENC[AES256_GCM,data:RA==,iv:m8CO/d9Gh0cjc4QYX6CsUx87Vu5iqtU0uVOsA3AeWgs=,tag:Ri0arOjuwRC83fz4EynVtg==,type:str] +sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzSVNSS1A5SWtCM1JzNlJH\nUTRGOUVmdlYyNE9EWVo5VExtZlkwSVEwSGdVCmhzV0xNcDF3alVuS3ZSNzdjclQ5\nNnBvVXlXc1VVSTcwV2VBOGNTUnhZRFkKLS0tIGYwN0NQVFpSaGFaeTMzZVBEY1oz\nYUF2RHN2T2J6d3Y1akl2TXc3L3l5QTAKrL7M9k9QcgI/3oVaYqFgsQgGFB7toRwz\n37mL9+Etqr3ayOLUplYGmG3lRT2MyUctC8894KmFnER8hQCzTbYBaw==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_0__map_recipient=age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns +sops_age__list_1__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCTWNiRi9objhVNDh2VHFL\nM25VdXZXeHdmd0hEcjhWbGpSYlNyUlovOXpJCkM3VTFXWGVFeW5oUitJcURQSjNn\ndHloNVJubVRRSnNMYTBpTFJYakJ3N1EKLS0tIHo1SW1oZXBRZWVxMVlWVk1HVmxw\nSnd0NHc4NklUa1FrdGZSMUJjR1BvT0EKxRriwZQefLrbIiG+RCUMjWee/C1cxF4f\nPU8ojWlxkzzNvZvydtUzLJtUSRZw9wH955Sk60yVtzlB0nczmQOZCA==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_1__map_recipient=age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6 +sops_lastmodified=2025-03-02T03:46:13Z +sops_mac=ENC[AES256_GCM,data:j/JqiPLHw6a21iJV/qNhAr+4kVkCnXG0uYGEJ4m5K5UerN/nXLzVafa7ciaMzBC1k6KBZwSyuKcQxJt3Q5+R733AD97VgrClSAU8w1pQhlWAUpzD959PwW5dTX8N9G+gih0xcJ5RsMALfWppeTImAAyAoKo1mtxE2MtfQZw1DU4=,iv:jYM3YfA2cbDjKVLHhQ8Rzv90Rg2R4iiY6zFL1N8knv0=,tag:8wRhD2XDZXI9v2j5XHKtqQ==,type:str] +sops_unencrypted_suffix=_unencrypted +sops_version=3.9.4 diff --git a/secrets/frp.env b/secrets/frp.env new file mode 100644 index 0000000..e322a68 --- /dev/null +++ b/secrets/frp.env @@ -0,0 +1,9 @@ +FRP_AUTH_TOKEN=ENC[AES256_GCM,data:CXFJwOOHEbtn1PI0TQc=,iv:yItYliwZGxZs8YAWksV7BqJP3TUBadxXpf99J5nXR3A=,tag:9earTQfuoLO132UZnTjlWQ==,type:str] +sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3aDUrd1g5eEdDVjVIWDZr\naXFGM2VIdzBwT3UvTG91aVYzWXNPb2FINkhNCjN5eUtUZVdmOHk0aFZHeXhEckRR\nakx6VVo1TE1XaHhNei83YTJsaTFSQ2sKLS0tIEx5Y1QzS0lvZW10YnRidjNaNnND\neWxBaDlibUJhWWl3YXJGWko5a1RUb3MKQkQfg4pBD/hXbtpF5z8Q5Ue0hKF2GywE\nuhWfdHHsjoMWaJWtHY3QQt2yEW8ETOD4wMbL97gJ27ELyiihbYt9MQ==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_0__map_recipient=age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns +sops_age__list_1__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpRStZVjRYYjBYRTl0SUht\nc05acS81VHlFZllPZGdjTzZtRmlXTHRCOFNJCjY5Z2hjZjV0Y1hUZHVCMjQ0TFhT\nSVBKNHA0Zm9jTjJRMHVoNWIxY3dTb1kKLS0tIHYwWUxWZWZYV0VrMmVEZ3BNRk9i\nZGI5NVRFTFpmbE9HemtSUFhQR2F6WTAKd+AFLCRq1aszC3wbN5BQYNxxiXAnVFl1\nOZXsqSOvzQMcBD/NIE9Qz7aNGp5KT2Igx2MkPLQ7PxF9gt5F1T/v0w==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_1__map_recipient=age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6 +sops_lastmodified=2025-04-13T06:57:07Z +sops_mac=ENC[AES256_GCM,data:WJ9FCO78LRFbU7o9uEZ70s/OJIHN5/UQVKrgt/Zve6x9yVChaRtHmvk7kF/SoRsheLIbeYoY8RI0rUn3Sx7Y7o/ib/u9dMAec0xGt0K6+yde0DUO/uH1KpjXd6WHRPjoMERld6xA1fWVRu7G+gXrEZA1dN5Jbs8ZWVYGF6IBw2A=,iv:r4eYeCDJOw40hK7cyIEbEW+Pq+VFgUOJr1ydkSyjaEg=,tag:ucFH1pNqAHg7eWm1tYYi/g==,type:str] +sops_unencrypted_suffix=_unencrypted +sops_version=3.10.1 diff --git a/secrets/imxyy-nix-hashed-password.txt b/secrets/imxyy-nix-hashed-password.txt new file mode 100644 index 0000000..226b77b --- /dev/null +++ b/secrets/imxyy-nix-hashed-password.txt @@ -0,0 +1,19 @@ +{ + "data": "ENC[AES256_GCM,data:vq2ezKQE7Flae7h59qskI7N3pwCQFQCdADeRppBBOhlzXcfMbf7hquJ4XO/xCztvBM01GkcdiSL/imcL83q+zRXKhAcOiV/M//s=,iv:QPiFKMrX+7X9wwMHghXNN2X0dCAGTN85dsmJibZognk=,tag:EabTMy1YcklDvLr0WmtP7Q==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJVXdjRGN5MU0vb0VoK3p6\nUnBZSWNJYkZEM0plZDM3NFdPcGtKV0ZWaGlZCmNVcXRhSXJqY3BUYjdhMUhaQUtU\nYUxjNlY4RFdrd1FwTldLM2xUZ0ZtOGcKLS0tIGx1TlVXYjQ4UVQ5K2hvV1RKaUtG\nZ1AyelhjanI5bFF1d0tLdFRLQmdaLzgKCom4ycxuvZfTjPVwyJDUAHBUf2tEXNHT\nwyehXEA/4t3JRZc1J/uKZWIpsrIkJ7+ObfNMGgjK8aEXhmzaVXGQKw==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwbHhUUFplTDhsck56SjB1\nMmxIRHFZWERpWmxIaU51VlRvenFZMlJHQzJvClU5UFFTTVhtZjYxT0Q2amlUaDBz\nTU9mLzI3aTVRNFJ1NEdmL1lIS1hEQ1kKLS0tIFc3bzNHN1dPQjJodEx5bHNPS3RH\neU1pdk51UjV0aEVsazhNNGtCYmlHQkEKdr18o6/f7NGLy5ge8hjzZ4rk71pWhs2c\nAv02eyNNV/d0ZSgqg1xp1uZUyU6u6Gflog/klgLbeGtuUz0EWqnZFw==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-04-13T06:45:42Z", + "mac": "ENC[AES256_GCM,data:pVo1se/bQsIFLru+AL5JMEzqm05uU3Ei4gSKuAW94cV8nLGze8kDqVt5HY5JQIyPg/5HQjMhnozdn3u8YkG5NPMMAOVxSm79yeAjLjHhH9xj+mWB+z1uHq+zUK2omF2UuQO/jt6juGDQCUscjdQL2EY2UubdNV0xYexagXEbwSs=,iv:2ic3sGINuLfqDlfWAq5JlDlYA9PG1pTpBCbYffZqcjI=,tag:G2Y8y8YM6hiTBQB/eDjpNw==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.1" + } +} diff --git a/secrets/imxyy-nix-server-hashed-password.txt b/secrets/imxyy-nix-server-hashed-password.txt new file mode 100644 index 0000000..5a084b1 --- /dev/null +++ b/secrets/imxyy-nix-server-hashed-password.txt @@ -0,0 +1,19 @@ +{ + "data": "ENC[AES256_GCM,data:3FRwUs3qmYisK4GL2WbLAkejvbUDyKsYCAxs8QNU5rkrzMFVaHS83/zOK3eGmEFkMVm7Hri+uMW6fyNIuKVxsYo7+xmKhmw4TXk=,iv:dM8hgg086DjjRPIsThIYqWfRKfuJpI1JXsdx+WOxtoY=,tag:BO1G1r4o4QHuDeB+OrydPw==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNeFkxSFVvSytmUWVCVWl4\ncC9lcHc1ak5tTm5wMHUrSVZvUWN4ZXl4UkJVClA5WGl0MzhjY3kxNnJWV2NSQ1Bv\nc2xFK2w2R0FQdE8wbVVpN2Z2TXRxTDQKLS0tIDZmN1VJUDhJSks5VHFwdVVXMmFD\nd3RWeks5bXo4a3BMWXdWazR5UmtDV3cKMKLuxkAtMKSak9ELgJj+tjZiqCkFu4J/\nbok89bqSV5/eC+hw2yTjFf8ArgPtDfqMgyeQ8wqBQiPgDScU14LI5Q==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4b3lzUDUrQnpXUHdEa01Y\nMWd0Q0VmcFpSS1Y1Rno5TFVTUWlIdmpCeFJRCmgyYVhPQ3MzeVlnN0VOaEloVTNV\neGRlRUVmOENxVHJkSXJJckFTWFR5UTAKLS0tIEpJSTRqV2hiRkw2SE0reTgzTzFa\ncUZRWkczTGttZ05BcitxdldueGNtOUEKLeDCU1sP657TX5QRQJucTDRZnIIgb/wo\nzhOYehzTKmKj5m5hOjlrIC6dt7G30J+JTkhiyxP6Invd+5dDjuabeA==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-04-13T06:45:59Z", + "mac": "ENC[AES256_GCM,data:QRncQXUWxoafT8yTqnJLEaWGWPxPNNnga8IyE4JuYIOXTHg1NqDQoCRwxJYVBfcYJyF/P3L1hrhQ+lSJPKGD0ediXsIW+ClDMyZ6w0vknDCcHJ1fy/GAyKJGHUbtlEzlcXknwIOsNrCfkNB75wHhWTRH7yLqovedyp+VYFuEbig=,iv:eB3YrskOHboHGcPZRdGVp+bAKqsqI6lsmTsXCkkNgF0=,tag:bNFfloM5PbtQ8rpba7h4sA==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.1" + } +} diff --git a/secrets/mihomo.yaml b/secrets/mihomo.yaml new file mode 100644 index 0000000..611c2e4 --- /dev/null +++ b/secrets/mihomo.yaml @@ -0,0 +1,119 @@ +allow-lan: ENC[AES256_GCM,data:/NS2lg==,iv:rdjmAyJ5hQZsaqf9xLTuu9103mlBrJ5rRpWcRg4unfA=,tag:wIjPvBgmBZ4U6HRnAyZmzw==,type:bool] +bind-address: ENC[AES256_GCM,data:lQ==,iv:Il8zZQY8bkOQq82n9FfEJxfllYkL0XSz3w8fIQF5nLg=,tag:Um/lxN3hrQP/ojS3tvkh0A==,type:str] +mixed-port: ENC[AES256_GCM,data:3pO+YQ==,iv:d5fQRnaXwELshI267IRhNrBi+lrkE1tAVQtGWbTTL58=,tag:bjvnJGc/ot0mwWJlXZdAGg==,type:int] +mode: ENC[AES256_GCM,data:tLvZMA==,iv:ZTHCuf/fGBrqXKy1U8FqCPOPk/xhwXH+d+LCeuU1YN0=,tag:XSvkAx/HGQInFcxod6p7ag==,type:str] +log-level: ENC[AES256_GCM,data:GjK0SA==,iv:p3B73kKmAklWWsrQZJYT8KnH5I4SyGHaFWo6fqr57V0=,tag:LvOxkFkNOBo3GAj9Gx1l8g==,type:str] +ipv6: ENC[AES256_GCM,data:TkqT508=,iv:vYn61sFKuKeDqC3pCBMvn/SZaxTmuUA1Dp5r+Wyjl0c=,tag:iT6e7MPvLtMVntqZrdVWfA==,type:bool] +external-controller: ENC[AES256_GCM,data:DuI/L1mDF5soS5aS,iv:1U5msjsK1kLCUEWmhRp3poKFnTa4T2wgq08WtLn+NDs=,tag:iqQF8LHCAWGvMuKrf2ieYA==,type:str] +external-controller-cors: + allow-origins: + - ENC[AES256_GCM,data:Ow==,iv:C2R4gooPGj4lranMXP6Uu+nCbGhVk1S37dBKbYgdsRU=,tag:onXhjT4c/qMoayForPKwEQ==,type:str] + allow-private-network: ENC[AES256_GCM,data:mxDrog==,iv:L4hT2zLieK7nQnp5GvdHTsnSkeTz61v77nr281lAcag=,tag:jCQgs+0aDrl7BSZYxI7qUw==,type:bool] +proxies: + - name: ENC[AES256_GCM,data:pQGaACaf,iv:bK1kKEgyHJYmDtWHj2S6j8cL7hEpnESjQ/8sRY6G6es=,tag:uPp6zJSybNvWgJvG86oPvQ==,type:str] + type: ENC[AES256_GCM,data:8+AmvsqSRHH4,iv:57lTFwNf0ONXc2oz2MDXCUFcowvGumUpMQD2TYvHlH8=,tag:KLPNDQ8W9b53gdIiCVEKRg==,type:str] + server: ENC[AES256_GCM,data:bNVo+H91vMIZcCKA,iv:eK//i47MM9OWmWoftn7Zy4zpXrnok79JTYryFHafRrU=,tag:amC+xL1uHMjvSIMNog7M9A==,type:str] + port: ENC[AES256_GCM,data:ixny,iv:NRPp+pUW0cf0b3BAHS/XtUvlsTg5V1HxJVADYlkNqig=,tag:3M1WgBTFiTg4R/9uft/zSA==,type:int] + ports: ENC[AES256_GCM,data:+3U9QYPG4AKOJjM=,iv:z4vHcfk1+rAVOGcglY+E+iyBYTOL1ci7GrhZn5Ncb5Q=,tag:doMqBjWKhwXclftNEFlZkw==,type:str] + password: ENC[AES256_GCM,data:t07Stcs90BGXiTn8w/CdZgXK3g==,iv:N6gNmJr+1EUWmdLknrL7tMEOlghbKMtN4ayn/3rpobo=,tag:Bii1waY1RPbZelSvVU+g2w==,type:str] + up: ENC[AES256_GCM,data:I3dQyGfeBNg=,iv:8XjU1MKwOg1uuOHOfVu8xcY8xZkyDLC3DsvCYCwFFJs=,tag:6V9KL5QeDfPgCNjAK/kgdA==,type:str] + down: ENC[AES256_GCM,data:kphfKaQrBVTK,iv:cQbLYAjgID9T2wi51vAhw/+oUFfu2BiGMqfqTEf2vbI=,tag:WGIMzBb8UcAEEKJHbOmeww==,type:str] + sni: ENC[AES256_GCM,data:N1XYBkWZHcokCAwNav0=,iv:wZMb9ufI15orsbjfWPpnR70jJ3AhUuI+9h9NnTzZr5E=,tag:N4vbN0+8QDe3yN5bit3F4w==,type:str] + skip-cert-verify: ENC[AES256_GCM,data:fD9uBNM=,iv:pvP1qVsK4I2ROB92Pv0Ed8byH7DMfR3EM6VdKwDnd6g=,tag:PWgu06W/JHIeI+OHNq9P4Q==,type:bool] + alpn: + - ENC[AES256_GCM,data:ndU=,iv:tFarTtgPNIYfy/N9AvBBB/fOr296amxj7Qa8VcjHLJ4=,tag:gIRrF/wnqfNlk1jDXazqZw==,type:str] + - name: ENC[AES256_GCM,data:gtGCyojeJWGc,iv:BKuY0sT5+/BTIscjY5/Pc3aoFywfzjeDlSXL5D/7v6k=,tag:GSn7HpLCj29LsJy7nJc5UA==,type:str] + type: ENC[AES256_GCM,data:UlGHyiA8,iv:upAc7GudOgPttF/4dhGmAYdzEP8+ZzRomV4JN15E2QE=,tag:5FEijyNGuuGeK4TRZVEg6A==,type:str] + server: ENC[AES256_GCM,data:eZFNt+Mf6da4CPxi,iv:u0Q/0Ls65Ivj+GtZ1P0BficN+nqjD98vF0NlUpwAZLg=,tag:xQ+OsGqXQJBRXJl2D+MG3Q==,type:str] + port: ENC[AES256_GCM,data:5E4+,iv:0WbTukVgJTBPX/ued9q3QOVpixpiqAca/C2NDFt67Jc=,tag:FmPrhBqt28u8aQceShZV/w==,type:int] + password: ENC[AES256_GCM,data:v930O72DIdvPT/0upp+VC8Q=,iv:pjxwmn8qGSC1KvjN5ylPaxm9S4jgKnEOqDiOm+FYQis=,tag:CoTfVWuVPcpTTaF5Ao63yg==,type:str] + sni: ENC[AES256_GCM,data:Sktawi48qWO8mt471QI=,iv:6PgDBNRFxvW0m/FTyGxkbnDiCMztWR3AKS0k6BxAmLY=,tag:oK7d8iQ58Hbah7cYjJMSyg==,type:str] + skip-cert-verify: ENC[AES256_GCM,data:RcrZX3s=,iv:4iPFYNYbcaW/j/R74F+QEeqEO3c6nH7bWnIoLIswuOI=,tag:fGNdK9AUQk5uiuKHVN4ZxA==,type:bool] + alpn: + - ENC[AES256_GCM,data:GZM=,iv:hqg4s+F1gz24LtsvIbdzFPXYrPUmSnAdLQAnoQs1u9M=,tag:XHjVFT9ZMcD3NnGdpkgi+Q==,type:str] + - name: ENC[AES256_GCM,data:CoSf2ETY,iv:stqOA3auCgfdMF5dtHrxUtM1fmrjpBzF++Oq4CaaxDw=,tag:Ep8+Do2KSGyyI3htJMyO+Q==,type:str] + type: ENC[AES256_GCM,data:877YbphMkl2Y,iv:+cJj8y9Ka3ep1n6XhNwC6M2i16K9iS5wlygbow2UJ1w=,tag:upp5Zm1BsKQufd337VOYgw==,type:str] + server: ENC[AES256_GCM,data:mOElD+p3kc7ruxlj,iv:Eo3ov/rQWp85ZVa6xZDeWEoj4NJNWlFbVoaJhn5akCk=,tag:YQGlqfbF6NWfJw96Sm6tng==,type:str] + port: ENC[AES256_GCM,data:44XQ,iv:DEViWVfJp0vnsHkwVrRJs++ggL3AMoPDC8Yo6HhJ4sw=,tag:E9iWzUejhTZy8zKGepZyDg==,type:int] + ports: ENC[AES256_GCM,data:rMksYDt5l/YeYuc=,iv:+YptxhLuilsfEdGdqb+p6lLtCFaEIwKm34oLYdcIBAI=,tag:fMi0NDJr4bBILmjdZ1So+A==,type:str] + password: ENC[AES256_GCM,data:Ogt0q3YMVBDc0DRvHqYp2hsIOA==,iv:jd5YgMd2YhbqcLTEh6veJPJ/ai0tZORmzPN9qSLMFNs=,tag:FfuVqcU5KsHQvqo5I7OzPw==,type:str] + up: ENC[AES256_GCM,data:nMRroxyPEz4=,iv:KGsbO5+u10vTnlCgURiHB9zEakP9EPoWdhfnAmoWtXk=,tag:KyZGxpFroNRaQO+yeVFEhw==,type:str] + down: ENC[AES256_GCM,data:I1yX5yspLcq2,iv:HbzlrJo0ZdZHI9/CSBgXlwkX41R/buS8JeQjBem4yKg=,tag:lfuIiVFIlst3wGidiMsovA==,type:str] + sni: ENC[AES256_GCM,data:1gvAU3CPOGg3gw4z,iv:Y7zCLWIZ8/DR1ZY2IE91zcvadfj5PejHw1T8wANzfhY=,tag:JcLhVi6t6TEXCsY/YZgj/Q==,type:str] + skip-cert-verify: ENC[AES256_GCM,data:GcVZ3dU=,iv:d3DCIr2IC+qMSNLOY9+8cUoq8MdfqXcU1DG7paLax/A=,tag:qlIpBwhLmF5bGoVIyD4ntg==,type:bool] + alpn: + - ENC[AES256_GCM,data:nrY=,iv:Qz5nEor8miCh62x1zGt4iCjtUX3znyRolrrvx3c2suM=,tag:tC0goZP6J9gMS28+KhZiEw==,type:str] + - name: ENC[AES256_GCM,data:I/gOScJ4PYyG,iv:Wi3x1D25WX/m28FYenmU+g/laqosIHe0YpFQGYTIAAI=,tag:Vg/KqSIhxVetaloyeEp2FA==,type:str] + type: ENC[AES256_GCM,data:fhOmk50v,iv:FZMGVkmWXTXAXiihFugdRejKAPbSQx7MIzgh0QJGutA=,tag:4Kjq2vdiAnaWWmw9RNPTqg==,type:str] + server: ENC[AES256_GCM,data:fByASUq0i6vl00aT,iv:m7iykG0sJnyjBSuu9qD78bS918FD3fj9Gak0cBSidJw=,tag:U0y1WHvOmQ6f3qnz1Qs+Ag==,type:str] + port: ENC[AES256_GCM,data:rYzd,iv:KBxUqU2JXzA9OluogH65swYrKaNMR9M1ShaqWHclBUw=,tag:mAH5gXlzSvi4aDZRy2xQOg==,type:int] + password: ENC[AES256_GCM,data:KOllQ4ZjM2EhxPMVqePDp6Y=,iv:iW5nzdvAzXpUR4zyDkwBGYqrHQCTtFYmyO+AlMaTioE=,tag:gKM49pwUCukSOFY9Ugchag==,type:str] + sni: ENC[AES256_GCM,data:p7XIiaPEC5UUe0Hc,iv:CgLd9lQ9ivfouzxihzR/OX8KgvIvyj0DktI5YYZ6epE=,tag:EzBxiAuEeEz2jyF0M5Ee6A==,type:str] + skip-cert-verify: ENC[AES256_GCM,data:OWZySck=,iv:NdhxmrbSxrL0qIt5NOCon/l97t85ZcOhE/sodDSnU/8=,tag:2QGDQwfnpB+gpSShGL1NLQ==,type:bool] + alpn: + - ENC[AES256_GCM,data:4i8=,iv:U2ZC7f9uBtzps4q2QGFlw7rEeVk3HYwBtcQ9T4gJXdc=,tag:2dt177AuAxkuVAw9nG7gBg==,type:str] + - name: ENC[AES256_GCM,data:M1xh1A7B,iv:fmajJEeiZ6g9QCzmX9dAqJxcWgNKd17nDqQW+DVHAXI=,tag:2k+lMI4SgUFOYYN561NDaw==,type:str] + type: ENC[AES256_GCM,data:h0grklnXHcch,iv:iyAYk+ozaR+lFYgqPU/7HN5zXhphBnGNu6boqwbGhwM=,tag:Jjh/GrkKo/Vw9OUshTz+aw==,type:str] + server: ENC[AES256_GCM,data:0yK3vD4CaVC6S3/e,iv:sc+YknJF5JG4xTu64bJJuJI7vGLoRc4rhWzqgFlYWms=,tag:OtWL9YBMOrkCnyBT0Z/YbA==,type:str] + port: ENC[AES256_GCM,data:VGeZ,iv:NXVEFcNZINpibZ8K6Q++vqva4ywHn8jth57lEOc5hSg=,tag:QGqt8/fG1S3sIT6ACiVYow==,type:int] + ports: ENC[AES256_GCM,data:Y/HnLKFSNVJC3WM=,iv:kiQw+GKtY3n0+mP2Tt7HiQTALs+6sTWpFdsygWy+1S4=,tag:/C7yfaEWV01rJ5y0kifs5A==,type:str] + password: ENC[AES256_GCM,data:41qnTwmzIWiGA8eVCWs7sq6gpg==,iv:6G8Zxi8P9h9wCF303ADTuOAV830NErok1bN2neFx8jM=,tag:6JxLB9sSF+2MzZAnTz7qsw==,type:str] + up: ENC[AES256_GCM,data:d6L+m9ArMrM=,iv:EqD8slVt/Wf8Edj6qTKt2qFovgGDDBEUN+YFPF8ug7M=,tag:8FIxAgkKF4fu4Z8Zauar2Q==,type:str] + down: ENC[AES256_GCM,data:RM5qROOyjsvf,iv:ESOrGbRPijJ9ptQrEduG3PW3CsuqCbneUxZg05lRcq4=,tag:FT/s5TYu+54byvfxv7eKvQ==,type:str] + sni: ENC[AES256_GCM,data:VwyqEXvRmkPZ528v,iv:mTw8lFBDeXAFnGLqRnnIDvxenvka3W6cFG8UMcct2Ys=,tag:tjjies51Zlpz7U8g3EUeUg==,type:str] + skip-cert-verify: ENC[AES256_GCM,data:O9ZyzxI=,iv:PIQPeY0PAMe/lAQN+9YWZl/ZY68jaFEJ/zVjpnihFKc=,tag:Ep0cuaBXa47F3yZo/MjqOg==,type:bool] + alpn: + - ENC[AES256_GCM,data:g/k=,iv:qa2hxVd5zH/bA0dL3QUezhkohhyOfISGzDjRPQ/gdRo=,tag:ljXzdUP2jaSV1PUvo0MYbQ==,type:str] + - name: ENC[AES256_GCM,data:524kL2VUV/Zr,iv:up5Map4oTAPmalvdpiZAob4wrxMAPu9w3Nk8VclDPOI=,tag:9FKxdoiHzUI9LBpt9QOy4g==,type:str] + type: ENC[AES256_GCM,data:C7hjfARP,iv:r+5/qimlashka+qMjrtlsOEMBFuN8/4SDrzzW/WM+KE=,tag:VVpvomQxVFxh/GTRW59p6g==,type:str] + server: ENC[AES256_GCM,data:UlqxHe1H1J1OH4Ld,iv:um1xP8HAqMTv8sqZewFBFaIoKq5MaVqultx7q9A9v4A=,tag:gGR1Uxwcap2gZYBmPuG76A==,type:str] + port: ENC[AES256_GCM,data:D/2Y,iv:/TOva98IWHrSeNHeFPkMq/GzkRu5k7RgddR0V5fp1mw=,tag:rS/kTisQ5Im4mcczmYpK/g==,type:int] + password: ENC[AES256_GCM,data:SoxJyZJLwxRQoErQ1ZHObnM=,iv:YVDRtTb0P15vA67ZUQgCBX1s16iqjrtG0oodE9RPDMI=,tag:zsKj2mwEWwDtJ9QGtbix2g==,type:str] + sni: ENC[AES256_GCM,data:rkDSKvEwqgNZE4Yh,iv:Nfi9j5/IKygbSDgBAvAzHrqEYFMQPXjdI3aKHNiFdFs=,tag:N7MZw4nUOGlo4RIo08DAmA==,type:str] + skip-cert-verify: ENC[AES256_GCM,data:uea1ExU=,iv:z7oRGpeLjzXA1RB5E3ucJu/bPo110v81AFR+4dDQYwA=,tag:AsorLzyJfwJNsJShlXQBtw==,type:bool] + alpn: + - ENC[AES256_GCM,data:0HY=,iv:I1stdmbZ2wKbYBN7bRLtz+4Ma7j8xect4HS9g0PKl0o=,tag:vI+jTgZWJSyag0dhXi0MKw==,type:str] +proxy-providers: + ykk: + type: ENC[AES256_GCM,data:QFH7Kw==,iv:uBwdbVdfQuoJ4wIxT9lAS/b0C167IwJbD2KhrB1VzkM=,tag:8ogC9VITAOfeMtceq20Wtw==,type:str] + url: ENC[AES256_GCM,data:lYAOja6fBCLlroGfOM6SNsz1iPEc62rCJocFbn+jcS0UHifYXq/EDRr7sFeNQ1kIzZF3U3QkQr3B1DEtciuiJkIOZ/uJniuHo1OzZoSx+PhYjorAtDA=,iv:yV/WRHPJDlYvKkwK3Q4AOjorBW3IprSksa9e/Pw6yJk=,tag:8xamIMGTqDeYuJTHF+PFeQ==,type:str] + proxy: ENC[AES256_GCM,data:BIEXrZQ=,iv:ZzEEJmLgbOhBTcZEgPfsL0AC72GpydlFTKhJ4+fgTec=,tag:v8URxwAU5wSHD5GPr/sTfw==,type:str] + exclude-filter: ENC[AES256_GCM,data:Uc9L0zm7TWGAgIQq6thwK4evIuYoEJyRJ2M=,iv:CbJp7BcobOfkxyY7/fvaECif57yhPZ1/IuPjLwYUwUQ=,tag:xtGissYFtBX3OVinstWRug==,type:str] +proxy-groups: + - name: ENC[AES256_GCM,data:O6LAzFQ=,iv:a+dfdy14adLlYbJQ5wAQLsD5hxuEXKW8Y/erhBVAREE=,tag:79++dpg2E2Mtc8y63nRcHw==,type:str] + type: ENC[AES256_GCM,data:JR3d3D1p,iv:n0u8vayA0PVDM7yvh2pk36S8EeqMnZRN8TZlwNnEC3U=,tag:ZmxXOralviL2xyd8+hN3ZA==,type:str] + proxies: + - ENC[AES256_GCM,data:W2Edq917,iv:JYOZXBOTW324WKslU8/BQv/+mcuvfipbvFU77e+mHJQ=,tag:ynazg1UWRbYsejv0fpgPtQ==,type:str] + - ENC[AES256_GCM,data:bc6mdrU795wv,iv:KsaxAFooTwb6r5sLYxnKAokIsE6/sZn0e5izwowHZQQ=,tag:wrHQl5yI44V40ESI3KQOSA==,type:str] + - ENC[AES256_GCM,data:IEFd/SNk,iv:JFLQaa5nk02nXesGC1fcyV7LexOa4dHjjqNKlttwp4Y=,tag:DeP4oT3xcfOEzff8RwoZyQ==,type:str] + - ENC[AES256_GCM,data:W4BYLRg/tYN3,iv:QfLjSOm/tVDihmgUaFAI3fp2+c0kSil34pdR2pZobLw=,tag:aLvSMitNmxbgFU/mapYgwg==,type:str] + - ENC[AES256_GCM,data:heJ5CLaS,iv:yF6YaM4UmxcwgPMgbi5shzLC4fv+yNX15rVLRCos6c4=,tag:+0EKyuEHx2hu7BEXZEdJew==,type:str] + - ENC[AES256_GCM,data:fDVLR0770KUF,iv:prsxi6lcvMg6I+2o4rlAYuepUdjAPHpFfzCf6LyXj3M=,tag:rXMVs9EBOq5oCWHYtesZXQ==,type:str] + use: + - ENC[AES256_GCM,data:hGy4,iv:LS9vHmdXUMuy0Na1z5YMpB+vEwKFLfezsftdWcWjTv0=,tag:lueXcksvaPC1yKpHT2zUag==,type:str] +rules: + - ENC[AES256_GCM,data:S6yGMmG4UUUWE04=,iv:FWz0kNu0hhQ+PyIMSxl6NPX/INluS7jAO9loX+E+jlE=,tag:tXK35hMiYDU8X0yl+0PRuQ==,type:str] +sops: + age: + - recipient: age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWQXJ6NEtxcVdJMVpNdFFR + ZzNzUkxCbVVHdXM2N1pMcTdVNmkwajg5TGxzCk1oVnB1ZXhORS9GWlFIVE84Mmlr + bDBHUGp1MkM1dkQ5d053YlRRaXFsZjgKLS0tIG10VnRtS0F1bmduQmIwMEcvQ1pm + Ry9hVGpwaEFVZTFSSnBEN2ZHTzdzT1UKcHlNVcfl2Mbyje3ITxzDKGGmsnik+MoY + Vs/Xo4kkYOHdzuZfsPsrxMC/TkGfTwya0taoLz4ktNd6AqlBwfn2uQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEdGxreUx5em9sTkt2Z2NY + eEFkYUcraVVwT0FXaWs5Q0dwL0I5V3V1UEdNClNiTlF2MjJYMHhQcE04NHluNmxC + ZTY4MDZtUlM4RWNXVTh0RlJGVlZDQmsKLS0tIGlnT002aWh5eW5ROW5HQ1pnZ2lN + cW9pK3k0YW5TQ3Q5eFRPU1NJRUcreEkKFNyc3hp+2U+/w5KU7kL7D7xkwIpdoT8F + m3mv7/2Jq0rr6c0w4aRdmms/6lD/gWbA5ae2o+AHPUDjyaLAtDVeeQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-04-12T10:27:08Z" + mac: ENC[AES256_GCM,data:7FgE9wuRKFPNCXD+g+38mMSizBWwIoLyhEO9uIm4zz2mt9xKgECA3P+IBR0tYa7DmPl8SYNm9visBSZCX9GZX0TfhAA001c1ees6gdhR9NvqvNSboyrXa7FMIyWREsDavMigIrSfBhsfHG/4s1Q/QwE72xntMKYTtjAnmP59/M4=,iv:50g6MyVcWeT38Wr+E9xj9OU8WGku3ThPTgD7W7g953s=,tag:1+nliqmuacDog5p4M3nBbQ==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.1 diff --git a/secrets/minio.env b/secrets/minio.env new file mode 100644 index 0000000..321a615 --- /dev/null +++ b/secrets/minio.env @@ -0,0 +1,10 @@ +MINIO_ROOT_USER=ENC[AES256_GCM,data:sBnNpnA=,iv:Z2K8Cg/4DW+MxcKIFVMRWlFj2/qqFLCDnzJF6Uq8eLE=,tag:Y+A/FZm/3k35+bNgl89xPQ==,type:str] +MINIO_ROOT_PASSWORD=ENC[AES256_GCM,data:sgYwUxp2Ao6nlUJ8RE7V9Bz1ZG4=,iv:LJJg62vCiguOp8aHCSYOTMtW3vjvXy+RnwghKJmaTR4=,tag:TnyxLzshfe53e2vav1QblQ==,type:str] +sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOOWdNNC9UWXpvNHFFdm5G\nUU5jUmZFRU8rMlhqMGw5RnR1cE5wMm5OS0hJCndBcjRlN0xuWDA4dGdLYVhaemFV\nZ3ppZzE0REtQcG1oU0VQdm42aHlFc0EKLS0tIDAvNlp1RkhUZ2ZFSFJxazJ1emJD\nclJJMmt3RTA0eEU0OTN0RmRYQkVFY0EKbE7ybooQJuwoZ3Ba0ZHDvN4FCNvZi3bt\nFidoXkuUNQ1y96PmFvsJ0mOqfDcDQsXo66nFgQEuiEQl8OU2l1uxfw==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_0__map_recipient=age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns +sops_age__list_1__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkdVc5UkxWcnZ6L2dJNFRr\nbUtYdDE3VHprWXRTLzBUQzdoK1RaUGlEOUc0CmJ5RXhKTzhzaVhra3dublc5c0ts\nQlJaRS81QTQ4b3JPeHN0cEk4MW5XNEEKLS0tIDFnKzJGeXZTdWYwMlN1UVYyWUdZ\nTTd1WGx6QkxuRXVta3pLM0poSE9JcjAK4Jo1gCs14ynajOKQI3xpO6pnMkM0eXuB\nq6cOyk7crjC5qoOKi+2N4Yoh9X1edZn4LbfFs/yXFaPftIuZqBiXzw==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_1__map_recipient=age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6 +sops_lastmodified=2025-03-09T02:24:31Z +sops_mac=ENC[AES256_GCM,data:ium37/C2+zybZDnSlhr6RmB3RiGmjVx4BbHXsfdZ6T+5/DFtkvduhuu0QxLReVBIZ/yYJgttTJq4wIqbUWMvsy2OafCB2piqISe0FAk2KfcM8kqfKFbLFghjkn6Nu1l331MKt/PMLy47ilS5i0Sh3QyD28/pe/tw4vpF3Vz8VjQ=,iv:vLoax3u4RCsisoSUIxy0EA+d2P/WfcPxfXM27QqmVpU=,tag:oCiXH1E9a9NBNbUikNvuBg==,type:str] +sops_unencrypted_suffix=_unencrypted +sops_version=3.9.4 diff --git a/secrets/sing-box-outbounds.json.txt b/secrets/sing-box-outbounds.json.txt new file mode 100644 index 0000000..26c1a33 --- /dev/null +++ b/secrets/sing-box-outbounds.json.txt @@ -0,0 +1,24 @@ +{ + "data": "ENC[AES256_GCM,data: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,iv:Nihe/dyJnoYjWfwktmMYLzJ5iWnv31R+Qg77Kgw8CCw=,tag:gFPT7ClRs+qDqUSABU1O5A==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPbTEvNmtma2dTV056cEtG\nWTJVaGp2cHd1ZHNkbk56NFhkODVDaW1jZEVZClR0bmR4N0JHWUFiR3hvS2xBa2M1\nU0JzTCtSM1BWN3huRjEvdEJ5djFwNXMKLS0tIHRCVHlIc1JDVFNXZkwxYldlVGgv\naE1QZXY3RmduTTE3NSthMG9ycTdXYnMKf3EQM56fWrPiNWpcirBoRy9UyLj0+IwH\nN66t7u/7wk0cSkHnngtnwEpiBRdpZ8/pseXTOzjq7F1rsV3cdWfUkA==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3TWJEcVNRSnpFclh0bVFk\nQXowbjNuN3dRUkppcXNUUWxuSzVHaXUvK2dVCnUwajFrVzBEVmNxSGJXQzkwazVL\nWDQ2UVNDb01SWkdvRUJJRUVUSno4ZDgKLS0tIGhIdjM0SjNkSDF4WGFub3ZyZ1A1\nZ3lOd3h4MXUxaGVLTVJraTVNdTltemsKlahWtratvptTrthjBniZFPZxqPDjfchF\nc7Sa9X6XtY/4G5BIMnmUWURdYgGJf4BydqyyeOgAdE+Cpke9SKRdhA==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-03-29T14:41:58Z", + "mac": "ENC[AES256_GCM,data:xXGXtzSUKY5kMh3zEuXTuzP8POn5JJhjRozaeI91SgpMFMJxJ0fAFV5Ez3F1XOnn0sg2Tstk6f5Fcv/7x0xrgtVBxfYSPWL7tuqWTvMmD53apenrj0JNh+Dojr80FyTTl7PQuA6t5flrwt+KR09HlIm2vFOqwqXJSekaZa9y9XA=,iv:oEfEMCpMY50ArLvve3vJxupmvWTQsX2+iOQqEpFD1yc=,tag:PTlO1mP512FBxakIZjxBsA==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/secrets/siyuan.env b/secrets/siyuan.env new file mode 100644 index 0000000..7171ea2 --- /dev/null +++ b/secrets/siyuan.env @@ -0,0 +1,9 @@ +SIYUAN_ACCESS_AUTH_CODE=ENC[AES256_GCM,data:/8/nxcZ6Yo8eqOeGoAAXLzcZ,iv:bjBBXR2/vQnN4aT+vxgzOHayyJkbi8bgvGIHjGiwaAI=,tag:1FrcJ+q2Z69lvfnZlSyRlg==,type:str] +sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0eUNaSWdtSWlkZTQyZklT\nM3IrNUZ3U2RPc2ljQWxvcFc2SERrRXIyNlFVCnlGeVlrVmJ5eVNqM3owZWM0Qm41\nbnRMeXFKc25uNW5tcVNIaDZ4UjZRUDQKLS0tIFN5MzFYVUUyNHVWUmlkcWhCZkJX\nUEVKYklzTDA0bUdRVzlsZXhKUUNHWWsKubaXhMRekUJfBroTtdnDF6++RIVAz9B2\nAO0bU69lp5yq4mrkoZ/Y9Wvlcx158Qh3CjS08rU76cY77gwanqNuBg==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_0__map_recipient=age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns +sops_age__list_1__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQQUtIcnR4aXZiUEZQcUFB\nUEorSjdNZzhBK3krdzFTRGhZcXBndXZxbUJnCjJtZDRwM1c5RzA4bWVzcGZNK1NL\ndDJGWjNwSE1ONHNwdEZWQktrdWVsdjAKLS0tIDl2TDVnc0VuMFZvdmRxam9JcC9l\nSHJENDNrOURHczh5ZzNHUWtuQi9QdTgK5xRi5CcfEl5ADFcWPtLUwDZ5jm1aEcNh\nCnR3l7drUkxmKl2ZBHKPcrxZMf0qauhBFFXVZhi8ruZ8mbDF/eoEzg==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_1__map_recipient=age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6 +sops_lastmodified=2025-03-08T15:05:21Z +sops_mac=ENC[AES256_GCM,data:9AEY6o2bHCgPqvxSwwf+5K7Cdj7jV14BdnhoA+k8YeW/kD6j/F99a2YiTP5MivnDwUH7Jm1PmdB2F2UKcMgmExUmcqTnAodTlZ+5IZnNENvCRsIbtF8QbHwDsbduRvLhrITfOT68Axug+/T9c46SDKw9608FD7zAC/3XILZXqnM=,iv:qpwGAv6aXTnMW4l4kuuGeOogtRQqhywzOigP/1RaviM=,tag:hQXuLGNBgMhBchqdMlRm7w==,type:str] +sops_unencrypted_suffix=_unencrypted +sops_version=3.9.4 diff --git a/secrets/vaultwarden.env b/secrets/vaultwarden.env new file mode 100644 index 0000000..e08bf0c --- /dev/null +++ b/secrets/vaultwarden.env @@ -0,0 +1,10 @@ +ADMIN_TOKEN=ENC[AES256_GCM,data:w1d4chazl81k15vMjKn14ADXjxgNyxs3D4W7tXJPebrcULzXw+0=,iv:l/sujGySuvcmOh1UgL8Tpg4ENLFIlKhhhAh1xRwx+5c=,tag:IAfeV/SCzehr/URjRoyzmg==,type:str] +DATABASE_URL=ENC[AES256_GCM,data:T39yeAxPOcnoKGO6OAJ+g3cr8AZywKsTDAhJnOhc4SQMcvx0HMVJpUAn6yA4yOlAAH//kKAY5uXHqKpig9c=,iv:ONoUo52LcBZmj+wYdZYofGPeS2GtKfhlrj8IQE77VrQ=,tag:u09irmLyYcU2kHRBOp5aBA==,type:str] +sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQR1V5YjN1S3RJSDN4R1Nv\nbmttQStJc2Fha2NFaFlHZUpyY1RvY0JHUG04Ci96eU9PbUxod01FQzBLQ0QwalFk\nWDVBL1pJV3BxSGJHTjRGRWk3U01aZFUKLS0tIDQ4YWNISU4rc0VqNzdtZHJHbk1Y\nUnlUaG92dmpCdWZMd1VYWTRtT0x5VHcKeEPLOmU6ER0Cvp1OpWb+BEfq1FC1Mv6Y\ntzuUZP6o/4tocNv6iQjr+xjW0X5pAzATUhkumhaAMryT6tCCMWu3ig==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_0__map_recipient=age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns +sops_age__list_1__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0Y3hFRndPc0VyK0dtWWFi\naVRBb01TdVVPQzErT2ExM0VFYitPWlR4OURNCkQ0TlJUYVpzWlZrMjZTM09uRWsy\nTGZiUGlGdEFRMTNuTnBHelZTeGQ4MVEKLS0tIHM5ZGtHZ01pdzdpZ3crdlhrUnpX\nTXVBN0JNWlM5RTMwajhRWi90dTlJeEkKEZBRsr+hZ82/kDojREvPY5+ZNXDHCISu\nW6ICh4Fy7ljP1eKrIysGdUj62f7CoPFpb1HgQ7iyyX4i5eKqeY+uzA==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_1__map_recipient=age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6 +sops_lastmodified=2025-03-02T03:51:32Z +sops_mac=ENC[AES256_GCM,data:PDUG8KdcLG+U3FY+9qdo+EfMl3RXDdRKIguu/WHpOmgysCOwLwFXrzk1783czKFb/K9tPisIJGj0Luak9FI/4nYqE0RwfdShcw0aRQnjoWFPtNFS6YbRI8T8av2OKnvKGM4Xdmnv+ivaXpQar+reIeW9THXmKkVfmmZa01ZlJa8=,iv:t71dpAMC88KnF+EeR1ryf0UAfY4FEdxiUB8L2q1p5Tk=,tag:vwTFzv6IUEuBcZjym/eeFA==,type:str] +sops_unencrypted_suffix=_unencrypted +sops_version=3.9.4 diff --git a/variables.nix b/variables.nix new file mode 100644 index 0000000..19a737b --- /dev/null +++ b/variables.nix @@ -0,0 +1,38 @@ +rec { + username = "imxyy"; + userfullname = "imxyy_soope_"; + userdesc = userfullname; + useremail = "imxyy1soope1@gmail.com"; + arch = { + aarch64 = { + linux = "aarch64-linux"; + darwin = "aarch64-darwin"; + }; + i686 = { + linux = "i686-linux"; + }; + x86_64 = { + linux = "x86_64-linux"; + darwin = "x86_64-darwin"; + }; + }; + hosts = + with arch; + let + hostprefix = "imxyy-nix"; + in + [ + { + hostname = "${hostprefix}"; + system = x86_64.linux; + } + { + hostname = "${hostprefix}-server"; + system = x86_64.linux; + } + { + hostname = "${hostprefix}-wsl"; + system = x86_64.linux; + } + ]; +} diff --git a/wslproxy.sh b/wslproxy.sh new file mode 100755 index 0000000..a57f7fe --- /dev/null +++ b/wslproxy.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +sudo mkdir -p /run/systemd/system/nix-daemon.service.d +sudo su -c 'cat << EOF >/run/systemd/system/nix-daemon.service.d/override.conf +[Service] +Environment="http_proxy=http://192.168.128.1:7890" +Environment="https_proxy=http://192.168.128.1:7890" +Environment="all_proxy=socks5h://192.168.128.1:7890" +EOF' +sudo systemctl daemon-reload +sudo systemctl restart nix-daemon