Compare commits

..

1 Commits

Author SHA1 Message Date
7388e3635f
WIP 2024-08-16 12:37:58 +02:00
191 changed files with 2370 additions and 5944 deletions
.sops.yamlREADME.mdflake.lockflake.nix
home

@ -2,10 +2,9 @@ keys:
- &gpg_h7x4 F7D37890228A907440E1FD4846B9228E814A2AAC
- &host_tsuki age1c92j4w0gqh32hwssl5m2mfrggssxax9pge8qxwytv9lmrnfttcvqdrgsst
- &host_kasei age1eu2a6m3adakfzelfa9pqpl74a5dz0wkyr0v7gegm5ajnx7aqmqcqsp2ftc
- &host_dosei age1s6s4w7cdfgajm30z9gy8va8pvs2lrzk5gnsg0hmn5z2sl8z36seqej406r
- &host_xps16 age1np3fg9ue2tp4l47x7waapvjxh5zcaye2j54laapy7uklamve2c4qv3gytm
- &host_dosei age179y7apa80p9unvyjtsphpzyhve90ex986vlxkx43xt9n6m7en3csqnug7c
- &host_europa age14mer45e52r2q4uz8n3fmv69tvk8gvwany4m4ndudud8ajv3jm4nqdj9m6a
- &home age10f4a5acpar8vwz3v298r3nv7gggfpmyh4wxpkc2hwq9paq0scf8qee8lau
- &home_dosei age17acs5lw7npma4sughxq3wj3cs5gjkenqdzscyvaks0er33n8gupsce7jlp
creation_rules:
- path_regex: secrets/common.yaml
@ -16,9 +15,8 @@ creation_rules:
- *host_tsuki
- *host_kasei
- *host_dosei
- *host_xps16
- *host_europa
- *home
- *home_dosei
- path_regex: secrets/home.yaml
key_groups:
@ -26,14 +24,6 @@ creation_rules:
- *gpg_h7x4
age:
- *home
- *home_dosei
- path_regex: secrets/xps16.yaml
key_groups:
- pgp:
- *gpg_h7x4
age:
- *host_xps16
- path_regex: secrets/kasei.yaml
key_groups:
@ -55,3 +45,10 @@ creation_rules:
- *gpg_h7x4
age:
- *host_dosei
- path_regex: secrets/europa.yaml
key_groups:
- pgp:
- *gpg_h7x4
age:
- *host_europa

@ -1,6 +1,5 @@
[![built with nix](https://builtwithnix.org/badge.svg)](https://builtwithnix.org)
# Nix Dotfiles
These are my dotfiles for several nix machines.
@ -17,7 +16,6 @@ Here are some of the interesting files and dirs:
| `/secrets` | Encrypted [sops-nix][sops-nix] secrets. |
| `flake.nix` | The root of everyting. Defines the inputs and outputs of the project. Also applies misc overlays and adds config-wide modules. See [Nix Flakes][nix-flakes] for more information. |
## Hosts
| Host | Machine type | Purpose |
@ -25,7 +23,7 @@ Here are some of the interesting files and dirs:
| `Tsuki` | Dell Poweredge r710 server | Data storage / Build server / Selfhosted services. This server hosts a wide variety of services, including websites, matrix server, git repos, CI/CD and more. **This is probably the most interesting machine to pick config from** |
| `Kasei` | AMD Zen 2 CPU / AMD GPU - desktop computer | Semi-daily driver. This is my main computer at home. |
| `Dosei` | Dell Optiplex | Work computer, mostly used for development and testing. |
| `Europa` | Dell Optiplex | Other work computer, used as nix builder for `Dosei`. |
## home-manager configuration
@ -38,74 +36,6 @@ Here are some of the interesting files and dirs:
| `/home/services` | Configuration for services/daemons that are user-specific. |
| `/home/shell.nix` | Shell-agnostic configuration. This includes aliases, envvars, functions, etc. |
## Some useful long commands
Build configuration without switching:
```
nix build .#nixosConfigurations.tsuki.config.system.build.toplevel -L
```
Check why configuration depends on package:
```
NIXPKGS_ALLOW_INSECURE=1 nix why-depends .#nixosConfigurations.tsuki.config.system.build.toplevel .#pkgs.suspiciousPackage
```
Re-encrypt sops secrets with new key:
```
sops updatekeys secrets/hosts/file.yml
```
## Setting up a new machine
### 1. Move gpg keys to
```console
# Export on some machine
gpg --export-secret-keys --armor nani.wtf > ~/SD/gpg_keys.pem
# Import
gpg --import ~/SD/gpg_keys.pem
```
### 2. Generating host keys, and converting to age keys for nix-sops host secrets
```console
# Create host keys
ssh-keygen -A
# Convert public key to age format
nix-shell -p ssh-to-age --run 'cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age'
# Register this key in `.sops.yaml`
$EDITOR .sops.yaml
# Update keys
sops updatekeys secrets/common.yaml
sops updatekeys secrets/$(hostname).yaml # if present
```
### 3. Creating new ssh key for nix-sops home secrets
```console
# Create new key
ssh-keygen -t ed25519 -b 4096 -C "sops-nix home key" -f ~/.ssh/id_ed25519_home_sops -N ''
# Convert public key to age format
nix-shell -p ssh-to-age --run 'cat ~/.ssh/id_ed25519_home_sops.pub | ssh-to-age'
# Register this key in `.sops.yaml`
$EDITOR .sops.yaml
# Update keys
sops updatekeys secrets/common.yaml
sops updatekeys secrets/home.yaml
```
[home-manager]: https://github.com/nix-community/home-manager
[nixos-search]: https://search.nixos.org/options
[sops-nix]: https://github.com/Mic92/sops-nix

248
flake.lock generated

@ -1,13 +1,30 @@
{
"nodes": {
"dotfiles": {
"flake": false,
"locked": {
"lastModified": 1654179945,
"narHash": "sha256-vnD7vu/hRBPoqL6Wse9CELitW30a9P++QTPnNm1qHjE=",
"ref": "master",
"rev": "37bdd48de4bfa8e03a8ab5ef840b2509e193e6a1",
"revCount": 96,
"type": "git",
"url": "https://git.pvv.ntnu.no/oysteikt/dotfiles"
},
"original": {
"ref": "master",
"type": "git",
"url": "https://git.pvv.ntnu.no/oysteikt/dotfiles"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1733328505,
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
@ -21,11 +38,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
@ -34,6 +51,37 @@
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"fonts": {
"flake": false,
"locked": {
"lastModified": 1668957008,
"narHash": "sha256-er2eUfNSG9qdBh0JvtxtftQjFfTFjRqqD8dnk5nZ1qw=",
"path": "/home/h7x4/git/fonts",
"type": "path"
},
"original": {
"path": "/home/h7x4/git/fonts",
"type": "path"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@ -41,20 +89,40 @@
]
},
"locked": {
"lastModified": 1747556831,
"narHash": "sha256-Qb84nbYFFk0DzFeqVoHltS2RodAYY5/HZQKE8WnBDsc=",
"lastModified": 1718530513,
"narHash": "sha256-BmO8d0r+BVlwWtMLQEYnwmngqdXIuyFzMwvmTcLMee8=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "d0bbd221482c2713cccb80220f3c9d16a6e20a33",
"rev": "a1fddf0967c33754271761d91a3d921772b30d0e",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-25.05",
"ref": "release-24.05",
"repo": "home-manager",
"type": "github"
}
},
"home-manager-local": {
"inputs": {
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1719170506,
"narHash": "sha256-AROqng7/S3mTByq8DBVR6r0iW1yZH+otJkqOwLHvELE=",
"ref": "refs/heads/fix-stalonetrayrc-path",
"rev": "0e5656163c2f9ac6e2cc4de3b44beb7a137abbe6",
"revCount": 3588,
"type": "git",
"url": "file:///home/h7x4/git/home-manager"
},
"original": {
"type": "git",
"url": "file:///home/h7x4/git/home-manager"
}
},
"matrix-synapse-next": {
"inputs": {
"nixpkgs": [
@ -62,16 +130,16 @@
]
},
"locked": {
"lastModified": 1735857245,
"narHash": "sha256-AKLLPrgXTxgzll3DqVUMa4QlPlRN3QceutgFBmEf8Nk=",
"lastModified": 1717234745,
"narHash": "sha256-MFyKRdw4WQD6V3vRGbP6MYbtJhZp712zwzjW6YiOBYM=",
"owner": "dali99",
"repo": "nixos-matrix-modules",
"rev": "da9dc0479ffe22362793c87dc089035facf6ec4d",
"rev": "d7dc42c9bbb155c5e4aa2f0985d0df75ce978456",
"type": "github"
},
"original": {
"owner": "dali99",
"ref": "0.7.0",
"ref": "v0.6.0",
"repo": "nixos-matrix-modules",
"type": "github"
}
@ -123,82 +191,65 @@
]
},
"locked": {
"lastModified": 1747706637,
"narHash": "sha256-NKQVKIVuF0PfI03ear6jW29KaM91IBR0eo8NxrOF+70=",
"lastModified": 1719278718,
"narHash": "sha256-gWQb4P9CZgKzTn4F4eWMYeUv2AQOXFlcFmFXh2apoyA=",
"owner": "infinidoge",
"repo": "nix-minecraft",
"rev": "5f921cf5b1230b392c69154152ff9198de9bb625",
"rev": "b6ff85f3b416a700ac35e33c214d7c9f4fe071fa",
"type": "github"
},
"original": {
"owner": "infinidoge",
"ref": "master",
"repo": "nix-minecraft",
"type": "github"
}
},
"nixos-hardware": {
"locked": {
"lastModified": 1747723695,
"narHash": "sha256-lSXzv33yv1O9r9Ai1MtYFDX3OKhWsZMn/5FFb4Rni/k=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "6ac6ec6fcb410e15a60ef5ec94b8a2b35b5dd282",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "master",
"repo": "nixos-hardware",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1747610100,
"narHash": "sha256-rpR5ZPMkWzcnCcYYo3lScqfuzEw5Uyfh+R0EKZfroAc=",
"lastModified": 1719145550,
"narHash": "sha256-K0i/coxxTEl30tgt4oALaylQfxqbotTSNb1/+g+mKMQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ca49c4304acf0973078db0a9d200fd2bae75676d",
"rev": "e4509b3a560c87a8d4cb6f9992b8915abf9e36d8",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-25.05",
"ref": "nixos-24.05",
"type": "indirect"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1719099622,
"narHash": "sha256-YzJECAxFt+U5LPYf/pCwW/e1iUd2PF21WITHY9B/BAs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5e8e3b89adbd0be63192f6e645e0a54080004924",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1747696584,
"narHash": "sha256-TvJjbLlQ5aAHS3ZdP8mztNs28cMGWdT3J9g/6li3/4I=",
"lastModified": 1719254875,
"narHash": "sha256-ECni+IkwXjusHsm9Sexdtq8weAq/yUyt1TWIemXt3Ko=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "359c442b7d1f6229c1dc978116d32d6c07fe8440",
"rev": "2893f56de08021cffd9b6b6dfc70fd9ccd51eb60",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixpkgs-unstable",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"nixpkgs-yet-unstabler": {
"locked": {
"lastModified": 1747762468,
"narHash": "sha256-I8l6r639PrDpEpAFgY64GmuQ+4NK+nxqAoSUnAEKw9E=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6bd7ba77ef6015853d67a89bd59f01b2880e9050",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "master",
"repo": "nixpkgs",
"type": "github"
}
},
"osuchan": {
"inputs": {
"nixpkgs": [
@ -206,11 +257,11 @@
]
},
"locked": {
"lastModified": 1684092181,
"narHash": "sha256-Oi6G8Jx2RkEMi3UndtAnZw61hfgKGEe7l/ILdB9ump4=",
"lastModified": 1672838459,
"narHash": "sha256-SIXzj9fbSvr/jfhhil+0cS7I6KONijdH80PFGxJi+CA=",
"ref": "refs/heads/master",
"rev": "028ed8774d1cf4650fc15253146cf14451eb608c",
"revCount": 43,
"rev": "392fb541ce39f1f52908eee336d5ed409cd798ed",
"revCount": 42,
"type": "git",
"url": "file:///home/h7x4/git/osuchan-line-bot"
},
@ -221,30 +272,53 @@
},
"root": {
"inputs": {
"dotfiles": "dotfiles",
"fonts": "fonts",
"home-manager": "home-manager",
"home-manager-local": "home-manager-local",
"matrix-synapse-next": "matrix-synapse-next",
"maunium-stickerpicker": "maunium-stickerpicker",
"minecraft": "minecraft",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs",
"nixpkgs-unstable": "nixpkgs-unstable",
"nixpkgs-yet-unstabler": "nixpkgs-yet-unstabler",
"osuchan": "osuchan",
"sops-nix": "sops-nix"
"secrets": "secrets",
"sops-nix": "sops-nix",
"vscode-server": "vscode-server"
}
},
"sops-nix": {
"secrets": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1747603214,
"narHash": "sha256-lAblXm0VwifYCJ/ILPXJwlz0qNY07DDYdLD+9H+Wc8o=",
"dirtyRev": "1d1e3c1a3293e22be504749eb92ac3b050cd8622-dirty",
"dirtyShortRev": "1d1e3c1-dirty",
"lastModified": 1683506783,
"narHash": "sha256-iwnpd6v4tKXFDTRomzJxwYPr2mm2JR9DCCnkqsofX5c=",
"type": "git",
"url": "file:///home/h7x4/git/nix-secrets"
},
"original": {
"type": "git",
"url": "file:///home/h7x4/git/nix-secrets"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1719268571,
"narHash": "sha256-pcUk2Fg5vPXLUEnFI97qaB8hto/IToRfqskFqsjvjb8=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "8d215e1c981be3aa37e47aeabd4e61bb069548fd",
"rev": "c2ea1186c0cbfa4d06d406ae50f3e4b085ddc9b3",
"type": "github"
},
"original": {
@ -267,6 +341,42 @@
"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"
}
},
"vscode-server": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1713958148,
"narHash": "sha256-8PDNi/dgoI2kyM7uSiU4eoLBqUKoA+3TXuz+VWmuCOc=",
"owner": "nix-community",
"repo": "nixos-vscode-server",
"rev": "fc900c16efc6a5ed972fb6be87df018bcf3035bc",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixos-vscode-server",
"type": "github"
}
}
},
"root": "root",

201
flake.nix

@ -1,15 +1,17 @@
{
inputs = {
nixpkgs.url = "nixpkgs/nixos-25.05";
nixpkgs-unstable.url = "nixpkgs/nixpkgs-unstable";
nixpkgs-yet-unstabler.url = "github:NixOS/nixpkgs/master";
nixpkgs.url = "nixpkgs/nixos-24.05";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager/release-25.05";
url = "github:nix-community/home-manager/release-24.05";
inputs.nixpkgs.follows = "nixpkgs";
};
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
dotfiles = {
url = "git+https://git.pvv.ntnu.no/oysteikt/dotfiles?ref=master";
flake = false;
};
sops-nix = {
url = "github:Mic92/sops-nix";
@ -21,18 +23,45 @@
inputs.nixpkgs.follows = "nixpkgs";
};
# TODO: fix website
# website = {
# url = "git+https://git.pvv.ntnu.no/oysteikt/nani.wtf?ref=main";
# url = "path:/home/h7x4/git/nani.wtf";
# inputs.nixpkgs.follows = "nixpkgs";
# };
maunium-stickerpicker = {
url = "github:h7x4/maunium-stickerpicker-nix/0.1.0";
inputs.nixpkgs.follows = "nixpkgs";
};
minecraft = {
url = "github:infinidoge/nix-minecraft/master";
url = "github:infinidoge/nix-minecraft";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
matrix-synapse-next = {
url = "github:dali99/nixos-matrix-modules/0.7.0";
url = "github:dali99/nixos-matrix-modules/v0.6.0";
inputs.nixpkgs.follows = "nixpkgs";
};
vscode-server = {
url = "github:nix-community/nixos-vscode-server";
inputs.nixpkgs.follows = "nixpkgs";
};
ra-multiplex = {
url = "github:pr2502/ra-multiplex";
inputs.nixpkgs.follows = "nixpkgs";
};
# Nix expressions and keys (TODO: move keys to another solution like agenix)
# which should be kept from the main repo for privacy reasons.
#
# Includes stuff like usernames, emails, ports, other server users, ssh hosts, etc.
secrets = {
# TODO: Push this to a remote.
url = "git+file:///home/h7x4/git/nix-secrets";
inputs.nixpkgs.follows = "nixpkgs";
};
};
@ -41,16 +70,18 @@
self,
nixpkgs,
nixpkgs-unstable,
nixpkgs-yet-unstabler,
home-manager,
nixos-hardware,
dotfiles,
matrix-synapse-next,
maunium-stickerpicker,
minecraft,
osuchan,
secrets,
sops-nix,
# anyrun,
vscode-server,
ra-multiplex
# website
}: let
system = "x86_64-linux";
@ -62,96 +93,51 @@
android_sdk.accept_license = true;
segger-jlink.acceptLicense = true;
permittedInsecurePackages = [
"segger-jlink-qt4-810"
"segger-jlink-qt4-794l"
];
};
overlays = [
self.overlays.pcloud
self.overlays.unstableLinuxPackages
self.overlays.waylandImeIntegration
self.overlays.gitoxide
overlays = let
nonrecursive-unstable-pkgs = import nixpkgs-unstable {
inherit system;
config.allowUnfree = true;
};
in [
(self: super: {
inherit (nonrecursive-unstable-pkgs) atuin wstunnel;
})
minecraft.overlays.default
osuchan.overlays.default
(self: super: {
ra-multiplex = ra-multiplex.packages.${system}.default;
})
# https://github.com/NixOS/nixpkgs/pull/251706
(self: super: {
mozc = self.qt6Packages.callPackage ./package-overrides/mozc.nix { };
fcitx5-mozc = self.callPackage ./package-overrides/fcitx5-mozc.nix { };
})
(self: super: {
mpv-unwrapped = super.mpv-unwrapped.override {
ffmpeg = super.ffmpeg_6-full;
};
})
];
};
pkgs = import nixpkgs pkgs-config;
unstable-pkgs = import nixpkgs-unstable pkgs-config;
yet-unstabler-pkgs = import nixpkgs-yet-unstabler pkgs-config;
in {
inherit pkgs;
inherit (nixpkgs) lib;
extendedLib = import ./lib { stdlib = pkgs.lib; };
inputs = pkgs.lib.mapAttrs (_: src: src.outPath) inputs;
devShells.${system}.default = pkgs.mkShellNoCC {
packages = with pkgs; [ sops ];
};
inherit pkgs;
packages.${system} = {
bcachefsInstallerIso = let
nixosSystem = nixpkgs.lib.nixosSystem {
inherit system;
modules = [
"${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal-new-kernel-no-zfs.nix"
({ lib, pkgs, ... }: {
boot.supportedFilesystems = [ "bcachefs" ];
boot.kernelPackages = lib.mkOverride 0 pkgs.linuxPackages_latest;
})
];
};
in nixosSystem.config.system.build.isoImage;
inherit (pkgs) kanidm pcloud;
};
overlays = let
nonrecursive-unstable-pkgs = import nixpkgs-unstable {
inherit system;
config.allowUnfree = true;
config.segger-jlink.acceptLicense = true;
config.permittedInsecurePackages = [
"segger-jlink-qt4-796s"
];
};
in {
pcloud = import ./overlays/pcloud.nix {
inherit (nixpkgs) lib;
pkgs = nonrecursive-unstable-pkgs;
};
gitoxide = _: _: {
gitoxide = nonrecursive-unstable-pkgs.gitoxide;
};
unstableLinuxPackages = _: _: {
linuxPackages_latest = nonrecursive-unstable-pkgs.linuxPackages_latest;
};
waylandImeIntegration = import ./overlays/wayland-ime-integration.nix;
};
nixosModules = {
machineVars = ./modules/machineVars.nix;
socketActivation = ./modules/socketActivation.nix;
};
homeModules = {
cargo = ./home/modules/programs/cargo;
colors = ./home/modules/colors.nix;
direnv-auto-prune = ./home/modules/programs/direnv/auto-prune.nix;
downloads-sorter = ./home/modules/services/downloads-sorter.nix;
gpg = ./home/modules/programs/gpg;
mpd-auto-updater = ./home/modules/services/mpd.nix;
neovim-auto-clean-swapfiles = ./home/modules/programs/neovim/auto-clean-swapfiles.nix;
newsboat = ./home/modules/programs/newsboat;
nix-index-auto-update-database = ./home/modules/programs/nix-index/auto-update-database.nix;
prism-launcher = ./home/modules/programs/prism-launcher;
shellAliases = ./home/modules/shellAliases.nix;
systemd-tmpfiles = ./home/modules/systemd-tmpfiles.nix;
uidGid = ./home/modules/uidGid.nix;
devShells.${system}.default = pkgs.mkShell {
packages = with pkgs; [ sops ];
};
homeConfigurations = {
@ -161,12 +147,12 @@
username = "h7x4";
homeDirectory = "/home/h7x4";
stateVersion = "25.05";
stateVersion = "22.05";
configuration = {
imports = [
./home/home.nix
./modules/machineVars.nix
] ++ (builtins.attrValues self.homeModules);
];
machineVars = {
headless = false;
@ -190,8 +176,8 @@
specialArgs = {
inherit inputs;
inherit unstable-pkgs;
inherit yet-unstabler-pkgs;
inherit (self) extendedLib;
secrets = secrets.outputs.settings;
} // (extraConfig.specialArgs or { });
modules = [
@ -203,6 +189,7 @@
./modules/machineVars.nix
./modules/socketActivation.nix
secrets.outputs.nixos-config
sops-nix.nixosModules.sops
({ config, ... }:
@ -211,16 +198,14 @@
useGlobalPkgs = true;
extraSpecialArgs = {
inherit inputs;
inherit unstable-pkgs;
inherit yet-unstabler-pkgs;
inherit (self) extendedLib;
inherit (config) machineVars;
machineName = name;
secrets = secrets.outputs.settings;
};
sharedModules = [
inputs.sops-nix.homeManagerModules.sops
] ++ (builtins.attrValues self.homeModules);
];
users.h7x4.imports = [
./home/home.nix
@ -236,40 +221,14 @@
"specialArgs"
]));
in {
dosei = nixSys "dosei" {
modules = [
{
home-manager.users.h7x4.home.uid = 1000;
}
nixos-hardware.nixosModules.common-pc
nixos-hardware.nixosModules.common-pc-ssd
nixos-hardware.nixosModules.common-cpu-intel
nixos-hardware.nixosModules.common-gpu-intel
];
};
kasei = nixSys "kasei" {
modules = [
nixos-hardware.nixosModules.common-pc
nixos-hardware.nixosModules.common-pc-ssd
nixos-hardware.nixosModules.common-cpu-amd
nixos-hardware.nixosModules.common-cpu-amd-pstate
nixos-hardware.nixosModules.common-gpu-nvidia-nonprime
];
};
xps16 = nixSys "xps16" {
modules = [
nixos-hardware.nixosModules.common-hidpi
nixos-hardware.nixosModules.common-pc-laptop
nixos-hardware.nixosModules.common-pc-laptop-ssd
nixos-hardware.nixosModules.common-cpu-intel
nixos-hardware.nixosModules.common-gpu-intel
];
};
dosei = nixSys "dosei" { };
kasei = nixSys "kasei" { };
europa = nixSys "europa" { };
tsuki = nixSys "tsuki" {
modules = [
matrix-synapse-next.nixosModules.default
osuchan.outputs.nixosModules.default
vscode-server.nixosModules.default
maunium-stickerpicker.nixosModules.default
(args: import minecraft.outputs.nixosModules.minecraft-servers (args // {

@ -1,105 +0,0 @@
{ config, lib, ... }:
let
cfg = config.services.downloads-sorter;
in
{
services.downloads-sorter = {
enable = true;
mappings = {
"archives" = [
"*.rar"
"*.tar.*"
"*.tgz"
"*.zip"
"*.gz"
"*.xz"
"*.bz2"
];
"pictures" = {
createDirIfNotExists = false;
globs = [
"*.gif"
"*.jpeg"
"*.jpg"
"*.png"
"*.svg"
"*.webp"
];
};
"docs" = {
createDirIfNotExists = false;
globs = [
"*.md"
"*.pdf"
"*.PDF" # why do people do this
"*.docx"
"*.doc"
"*.xlsx"
"*.xls"
"*.ppt"
"*.pptx"
"*.odt"
"*.ods"
"*.odp"
"*.odg"
"*.odf"
];
};
"books" = {
createDirIfNotExists = false;
globs = [ "*.epub" ];
};
"videos" = {
createDirIfNotExists = false;
globs = [
"*.mp4"
"*.webm"
"*.mov"
];
};
"isos" = [
"*.iso"
"*.img"
];
"jars" = [ "*.jar" ];
"txt" = [ "*.txt" ];
"patches" = [
"*.patch"
"*.diff"
];
};
};
systemd.user.tmpfiles.settings."10-downloads-sorter-service" = let
inherit (cfg) downloadsDirectory;
inherit (config.xdg) userDirs;
symlink = link: target: {
"${link}".L = {
user = config.home.username;
mode = "0770";
argument = "${target}";
};
"${target}".d = {
user = config.home.username;
mode = "0770";
};
};
in lib.mkMerge [
(symlink "${downloadsDirectory}/books" "${userDirs.documents}/books/downloads")
(symlink "${downloadsDirectory}/docs" "${userDirs.documents}/downloads")
(symlink "${downloadsDirectory}/pictures" "${userDirs.pictures}/downloads")
(symlink "${downloadsDirectory}/videos" "${userDirs.videos}/downloads")
];
}

@ -1,46 +0,0 @@
{ config, ... }:
{
systemd.user.tmpfiles.settings."05-homedir" = let
home = config.home.homeDirectory;
user = config.home.username;
defaultDirConf = {
d = {
inherit user;
mode = "0700";
};
};
symlink = target: {
L = {
inherit user;
argument = target;
mode = "0600";
};
};
in {
"${home}/SD" = defaultDirConf;
"${home}/ctf" = defaultDirConf;
"${home}/git" = defaultDirConf;
"${home}/pvv" = defaultDirConf;
"${home}/tmp" = defaultDirConf;
"${home}/work" = defaultDirConf;
"${home}/pictures/icons" = defaultDirConf;
"${home}/pictures/photos" = defaultDirConf;
"${home}/pictures/screenshots" = defaultDirConf;
"${home}/pictures/stickers" = defaultDirConf;
"${home}/pictures/wallpapers" = defaultDirConf;
"${home}/documents/books" = defaultDirConf;
"${home}/documents/manuals" = defaultDirConf;
"${home}/documents/music-sheets" = defaultDirConf;
"${home}/documents/scans" = defaultDirConf;
"${home}/documents/schematics" = defaultDirConf;
"${home}/Downloads" = symlink "${home}/downloads";
"${config.xdg.dataHome}/wallpapers" = symlink "${home}/pictures/wallpapers";
"${config.home.sessionVariables.TEXMFHOME}" = symlink "${home}/git/texmf";
};
}

@ -2,18 +2,17 @@
{
gtk = pkgs.lib.mkIf (!machineVars.headless) {
enable = true;
font.name = "Droid Sans";
font = {
name = "Droid Sans";
};
iconTheme = {
name = "Papirus";
package = pkgs.papirus-icon-theme;
name = "Papirus";
};
theme = {
name = "Adwaita-dark";
package = pkgs.gnome-themes-extra;
package = pkgs.vimix-gtk-themes;
name = "VimixDark";
};
gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc";
gtk3.bookmarks = map (s: "file://${config.home.homeDirectory}/${s}") [
@ -23,12 +22,10 @@
"music"
".config"
".local/share"
"SD"
# "Dropbox"
"git"
"pvv"
"git/pvv"
"nix"
"work"
"ctf"
];
};
}

@ -1,44 +1,21 @@
{ config, lib, ... }:
let
cfg = config.xdg.userDirs;
in
{ config, ... }:
{
imports = [
./mimetypes.nix
./directory-spec-overrides.nix
];
xdg = {
enable = true;
userDirs = {
enable = true;
desktop = lib.mkDefault "${config.home.homeDirectory}/Desktop";
documents = lib.mkDefault "${config.home.homeDirectory}/documents";
download = lib.mkDefault "${config.home.homeDirectory}/downloads";
music = lib.mkDefault "${config.home.homeDirectory}/music";
pictures = lib.mkDefault "${config.home.homeDirectory}/pictures";
publicShare = lib.mkDefault "${config.home.homeDirectory}/public";
templates = lib.mkDefault "${config.home.homeDirectory}/templates";
videos = lib.mkDefault "${config.home.homeDirectory}/videos";
desktop = "${config.home.homeDirectory}/Desktop";
documents = "${config.home.homeDirectory}/documents";
download = "${config.home.homeDirectory}/Downloads";
music = "${config.home.homeDirectory}/music";
pictures = "${config.home.homeDirectory}/pictures";
publicShare = "${config.home.homeDirectory}/public";
templates = "${config.home.homeDirectory}/templates";
videos = "${config.home.homeDirectory}/videos";
};
};
systemd.user.tmpfiles.settings."05-xdg-userdirs" = let
dirCfg = {
d = {
user = config.home.username;
mode = "0700";
};
};
in {
"${cfg.desktop}" = dirCfg;
"${cfg.documents}" = dirCfg;
"${cfg.download}" = dirCfg;
"${cfg.music}" = dirCfg;
"${cfg.pictures}" = dirCfg;
"${cfg.publicShare}" = dirCfg;
"${cfg.templates}" = dirCfg;
"${cfg.videos}" = dirCfg;
};
}

@ -2,86 +2,46 @@
{
nix.settings.use-xdg-base-directories = true;
home.preferXdgDirectories = true;
home.sessionVariables = let
inherit (config.xdg) dataHome cacheHome configHome userDirs;
runtimeDir = "/run/user/${toString config.home.uid}";
in {
TEXMFHOME = "${dataHome}/texmf";
TEXMFVAR = "${cacheHome}/texlive";
TEXMFCONFIG = "${configHome}/texlive";
EM_CONFIG = "${configHome}/emscripten/config";
EM_CACHE = "${cacheHome}/emscripten/cache";
EM_PORTS = "${dataHome}/emscripten/cache";
PSQL_HISTORY = "${dataHome}/psql_history";
SQLITE_HISTORY= "${dataHome}/sqlite_history";
MYSQL_HISTFILE = "${dataHome}/mysql_history";
NODE_REPL_HISTORY = "${dataHome}/node_repl_history";
GDB_HISTFILE = "${dataHome}/gdb_history";
HISTFILE = "${dataHome}/bash_history";
CALCHISTFILE = "${dataHome}/calc_history";
PYTHON_HISTORY = "${dataHome}/python_history";
GHCUP_USE_XDG_DIRS = "true";
MIX_XDG = "true";
__GL_SHADER_DISK_CACHE_PATH = "${cacheHome}/nv";
_JAVA_OPTIONS = "-Djava.util.prefs.userRoot=${configHome}/java";
ANDROID_USER_HOME = "${dataHome}/android";
AZURE_CONFIG_DIR = "${dataHome}/azure";
BZRPATH = "${configHome}/bazaar";
BZR_PLUGIN_PATH = "${dataHome}/bazaar";
BZR_HOME = "${cacheHome}/bazaar";
CARGO_HOME = "${dataHome}/cargo";
CUDA_CACHE_PATH = "${cacheHome}/nv";
DISCORD_USER_DATA_DIR = "${dataHome}/discord";
DOCKER_CONFIG = "${configHome}/docker";
DOTNET_CLI_HOME = "${dataHome}/dotnet";
DOT_SAGE = "${configHome}/sagemath";
ELM_HOME = "${configHome}/";
FFMPEG_DATADIR = "${configHome}/ffmpeg";
GOCACHE = "${cacheHome}/go/build";
GOMODCACHE = "${cacheHome}/go/mod";
GOPATH = "${dataHome}/go";
GRIPHOME = "${configHome}/grip";
GRADLE_USER_HOME = "${dataHome}/gradle";
ICEAUTHORITY = "${cacheHome}/ICEauthority";
NIMBLE_DIR = "${dataHome}/nimble";
NLTK_DATA = "${dataHome}/nltk_data";
NPM_CONFIG_CACHE = "${cacheHome}/npm";
NPM_CONFIG_INIT_MODULE = "${configHome}/npm/config/npm-init.js";
NPM_CONFIG_TMP = "${runtimeDir}/npm";
NODE_COMPILE_CACHE = "${cacheHome}/node-compile-cache";
NRFUTIL_HOME = "${dataHome}/nrfutil";
NUGET_PACKAGES = "${cacheHome}/nuget-packages";
PARALLEL_HOME = "${configHome}/parallel";
PGPASSFILE = "${configHome}/pg/pgpass";
PSQLRC = "${configHome}/pg/psqlrc";
PYENV_ROOT = "${dataHome}/pyenv";
RUFF_CACHE_DIR = "${cacheHome}/ruff";
RUSTUP_HOME = "${dataHome}/rustup";
RYE_HOME = "${dataHome}/rye";
STACK_ROOT = "${dataHome}/stack";
W3M_DIR = "${dataHome}/w3m";
WINEPREFIX = "${dataHome}/wine";
SBT_OPTS = lib.concatStringsSep " " [
"-Dsbt.ivy.home=${cacheHome}/ivy"
"-Dsbt.boot.directory=${cacheHome}/sbt/boot"
"-Dsbt.preloaded=${cacheHome}/sbt/preloaded"
"-Dsbt.global.base=${cacheHome}/sbt"
"-Dsbt.global.staging=${cacheHome}/sbt/staging"
"-Dsbt.global.zinc=${cacheHome}/sbt/zinc"
"-Dsbt.dependency.base=${cacheHome}/sbt/dependency"
"-Dsbt.repository.config=${configHome}/sbt/repositories"
"-Dsbt.global.settings=${configHome}/sbt/global"
"-Dsbt.global.plugins=${configHome}/sbt/plugins"
"-Dmaven.repo.local=${cacheHome}/maven/repository"
"-Divy.settings.dir=${configHome}/ivy2"
"-Divy.home=${cacheHome}/ivy2"
"-Divy.cache.dir=${cacheHome}/ivy2/cache"
];
# TODO: these needs to be set before the user session has fully initialized
# XINITRC = "$XDG_CONFIG_HOME/x11/initrc";
# XAUTHORITY

@ -61,26 +61,6 @@ let
woff2 = "font/woff2";
};
archive = {
"7z" = "application/x-7z-compressed";
ar = "application/x-archive";
bz2 = "application/x-bzip2";
deb = "application/x-debian-package";
gzip = "application/gzip";
lz = "application/x-lzip";
lzma = "application/x-lzma";
lzo = "application/x-lzop";
rar = "application/vnd.rar";
rar-compressed = "application/x-rar-compressed";
tar = "application/x-tar";
tar-compressed = "application/x-gtar";
x-zip = "multipart/x-zip";
xz = "application/x-xz";
zip = "application/zip";
zip-compressed = "application/x-zip-compressed";
zst = "application/zstd";
};
documents = {
azv = "application/vnd.amazon.ebook";
cbr = "application/vnd.comicbook+rar";
@ -92,98 +72,31 @@ let
pdf = "application/pdf";
};
office = {
doc = "application/msword";
docm = "application/vnd.ms-word.document.macroEnabled.12";
docx = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
dot = "application/msword";
dotm = "application/vnd.ms-word.template.macroEnabled.12";
dotx = "application/vnd.openxmlformats-officedocument.wordprocessingml.template";
mdb = "application/vnd.ms-access";
pot = "application/vnd.ms-powerpoint";
potm = "application/vnd.ms-powerpoint.template.macroEnabled.12";
potx = "application/vnd.openxmlformats-officedocument.presentationml.template";
ppa = "application/vnd.ms-powerpoint";
ppam = "application/vnd.ms-powerpoint.addin.macroEnabled.12";
pps = "application/vnd.ms-powerpoint";
ppsm = "application/vnd.ms-powerpoint.slideshow.macroEnabled.12";
ppsx = "application/vnd.openxmlformats-officedocument.presentationml.slideshow";
ppt = "application/vnd.ms-powerpoint";
pptm = "application/vnd.ms-powerpoint.presentation.macroEnabled.12";
pptx = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
xla = "application/vnd.ms-excel";
xlam = "application/vnd.ms-excel.addin.macroEnabled.12";
xls = "application/vnd.ms-excel";
xlsb = "application/vnd.ms-excel.sheet.binary.macroEnabled.12";
xlsm = "application/vnd.ms-excel.sheet.macroEnabled.12";
xlsx = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
xlt = "application/vnd.ms-excel";
xltm = "application/vnd.ms-excel.template.macroEnabled.12";
xltx = "application/vnd.openxmlformats-officedocument.spreadsheetml.template";
odc = "application/vnd.oasis.opendocument.chart";
odf = "application/vnd.oasis.opendocument.formula";
odg = "application/vnd.oasis.opendocument.graphics";
odi = "application/vnd.oasis.opendocument.image";
odm = "application/vnd.oasis.opendocument.text-master";
odp = "application/vnd.oasis.opendocument.presentation";
odt = "application/vnd.oasis.opendocument.text";
otg = "application/vnd.oasis.opendocument.graphics-template";
oth = "application/vnd.oasis.opendocument.text-web";
otm = "application/vnd.oasis.opendocument.text-master-template";
otp = "application/vnd.oasis.opendocument.presentation-template";
ots = "application/vnd.oasis.opendocument.spreadsheet-template";
ott = "application/vnd.oasis.opendocument.text-template";
};
code = {
css = "text/css";
csv = "text/csv";
html = "text/html";
js = "application/x-javascript";
latex = "application/x-latex";
php = "application/x-httpd-php";
pl = "application/x-perl";
rtf = "application/rtf";
sh = "application/x-sh";
tex = "application/x-tex";
txt = "text/plain";
xhtml = "application/xhtml+xml";
xml = "text/xml";
};
web = {
about = "x-scheme-handler/about";
chrome = "x-scheme-handler/chrome";
html = "text/html";
misc = {
http = "x-scheme-handler/http";
https = "x-scheme-handler/https";
mxwinurl = "application/x-mswinurl";
unknown = "x-scheme-handler/unknown";
x-htm = "application/x-extension-htm";
x-html = "application/x-extension-html";
x-shtml = "application/x-extension-shtml";
x-xht = "application/x-extension-xht";
x-xhtml = "application/x-extension-xhtml";
xhtml-xml = "application/xhtml+xml";
};
misc = {
ics = "text/calendar";
wine-ini = "application/x-wine-extension-ini";
wine-osz = "application/x-wine-extension-osz";
ics = "text/calendar";
url = "application/x-mswinurl";
};
};
# Applications
ark = "org.kde.ark.desktop";
firefox = "firefox.desktop";
zed = "dev.zed.Zed.desktop";
vscode = "code.desktop";
mpv = "mpv.desktop";
zathura = "org.pwmt.zathura.desktop";
nsxiv = "nsxiv.desktop";
sxiv = "sxiv.desktop";
font-viewer = "org.gnome.font-viewer.desktop";
libreoffice = "startcenter.desktop";
in {
xdg.configFile."mimeapps.list".force = true;
xdg.mimeApps = {
@ -191,18 +104,18 @@ in {
# associations.added = {};
# associations.removed = {};
defaultApplications =
(lib.mapAttrs' (_: v: lib.nameValuePair v nsxiv) mime.image)
(lib.mapAttrs' (_: v: lib.nameValuePair v sxiv) mime.image)
// (lib.mapAttrs' (_: v: lib.nameValuePair v mpv) mime.audio)
// (lib.mapAttrs' (_: v: lib.nameValuePair v mpv) mime.video)
// (lib.mapAttrs' (_: v: lib.nameValuePair v font-viewer) mime.font)
// (lib.mapAttrs' (_: v: lib.nameValuePair v libreoffice) mime.office)
// (lib.mapAttrs' (_: v: lib.nameValuePair v zathura) mime.documents)
// (lib.mapAttrs' (_: v: lib.nameValuePair v zed) mime.code)
// (lib.mapAttrs' (_: v: lib.nameValuePair v ark) mime.archive)
// (lib.mapAttrs' (_: v: lib.nameValuePair v firefox) mime.web)
// (lib.mapAttrs' (_: v: lib.nameValuePair v vscode) mime.code)
// {
${mime.misc.wine-ini} = zed;
${mime.misc.ics} = zed;
${mime.misc.http} = firefox;
${mime.misc.https} = firefox;
${mime.misc.wine-ini} = vscode;
${mime.misc.ics} = vscode;
${mime.misc.url} = firefox;
};
};
}

@ -7,97 +7,71 @@ in {
./packages.nix
./config/xdg
./config/ensure-homedir-structure.nix
./config/downloads-sorter.nix
./programs/aria2.nix
./programs/atuin.nix
./programs/bash.nix
./programs/bat.nix
./programs/beets.nix
./programs/bottom.nix
./programs/cargo.nix
./programs/comma.nix
./programs/direnv
./programs/eza.nix
./programs/fzf.nix
./programs/gdb.nix
./programs/gh-dash.nix
./programs/gh.nix
./programs/git
./programs/gpg.nix
./programs/home-manager.nix
./programs/jq.nix
./programs/gpg
./programs/less.nix
./programs/man.nix
./programs/neovim
./programs/nix-index
./programs/nix.nix
./programs/nushell.nix
./programs/pandoc.nix
./programs/python.nix
./programs/ripgrep.nix
./programs/skim.nix
./programs/sqlite.nix
./programs/ssh
./programs/tealdeer
./programs/texlive.nix
./programs/thunderbird.nix
./programs/tmux
./programs/uv.nix
./programs/yt-dlp.nix
./programs/zoxide.nix
./programs/tmux.nix
./programs/zsh
./services/nix-channel-update.nix
./services/pueue.nix
] ++ (optionals graphics [
./modules/colors.nix
./modules/shellAliases.nix
] ++ optionals graphics [
./config/gtk.nix
./programs/alacritty.nix
./programs/emacs
./programs/feh.nix
./programs/firefox.nix
./programs/mpv.nix
./programs/ncmpcpp.nix
./programs/newsboat
./programs/obs-studio.nix
./programs/prism-launcher.nix
./programs/qutebrowser.nix
./programs/rofi
./programs/rofi.nix
./programs/taskwarrior.nix
./programs/vscode
# ./programs/xmobar
./programs/xmonad
./programs/zathura.nix
./programs/zed
./services/copyq.nix
./services/dunst.nix
./services/fcitx5.nix
./services/gnome-keyring.nix
./services/keybase.nix
./services/mpd.nix
./services/mpris-proxy.nix
./services/network-manager.nix
./services/psd.nix
./services/tumblerd.nix
]) ++ (optionals machineVars.wayland [
./programs/hyprland.nix
./programs/waybar.nix
./programs/anyrun
]) ++ (optionals (!machineVars.wayland) [
./programs/xmonad
# ./programs/xmobar
./services/picom.nix
./services/polybar.nix
./services/ra-multiplex.nix
./services/screen-locker.nix
# ./services/stalonetray.nix
./services/sxhkd.nix
]);
./services/tumblerd.nix
];
sops.defaultSopsFile = ../secrets/home.yaml;
sops.age.sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519_home_sops" ];
sops.secrets."nix/access-tokens" = {
sopsFile = ../secrets/common.yaml;
};
nix = {
settings.use-xdg-base-directories = true;
extraOptions = ''
!include ${config.sops.secrets."nix/access-tokens".path}
'';
};
home = {
username = "h7x4";
homeDirectory = "/home/h7x4";
@ -116,41 +90,81 @@ in {
package = pkgs.capitaine-cursors;
name = "capitaine-cursors";
size = 16;
# TODO: enable in 25.05
# dotIcons = false;
};
keyboard.options = [ "caps:escape" ];
sessionVariables = {
DO_NOT_TRACK = "1";
_JAVA_AWT_WM_NONREPARENTING = "1";
CARGO_NET_GIT_FETCH_WITH_CLI = "true";
PYTHONSTARTUP = "${config.xdg.configHome}/python/pyrc";
};
};
dconf.settings = mkIf graphics {
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
};
};
xsession = {
enable = !machineVars.wayland;
# TODO: declare using xdg config home
scriptPath = ".config/X11/xsession";
profilePath = ".config/X11/xprofile";
};
xdg.configFile = {
"ghc/ghci.conf".text = ''
:set prompt "${extendedLib.termColors.front.magenta "[GHCi]λ"} "
'';
"python/pyrc".text = ''
#!/usr/bin/env python3
import sys
# You also need \x01 and \x02 to separate escape sequence, due to:
# https://stackoverflow.com/a/9468954/1147688
sys.ps1='\x01\x1b${extendedLib.termColors.front.blue "[Python]> "}\x02>>>\x01\x1b[0m\x02 ' # bright yellow
sys.ps2='\x01\x1b[1;49;31m\x02...\x01\x1b[0m\x02 ' # bright red
'';
};
news.display = "silent";
fonts.fontconfig.enable = mkForce true;
programs = {
home-manager.enable = true;
bash = {
enable = true;
historyFile = "${config.xdg.dataHome}/bash_history";
historySize = 100000;
bashrcExtra = ''
source "${config.xdg.configHome}/mutable_env.sh"
'';
};
bat.enable = true;
bottom = {
enable = true;
settings.flags.enable_gpu = true;
};
eza.enable = true;
feh.enable = mkIf graphics true;
fzf = {
enable = true;
defaultCommand = "fd --type f";
};
man = {
enable = true;
generateCaches = true;
};
mpv.enable = mkIf graphics true;
obs-studio.enable = mkIf graphics true;
ssh = {
enable = true;
includes = [ "mutable_config" ];
};
texlive = {
enable = true;
# packageSet = pkgs.texlive.combined.scheme-medium;
};
zoxide.enable = true;
};
services = {
gnome-keyring.enable = mkIf graphics true;
network-manager-applet.enable = mkIf graphics true;
};
manual = {
html.enable = true;
manpages.enable = true;
@ -159,7 +173,10 @@ in {
qt = mkIf graphics {
enable = true;
platformTheme.name = "adwaita";
style.name = "adwaita-dark";
platformTheme.name = "gtk";
style = {
name = "adwaita-dark";
package = pkgs.adwaita-qt;
};
};
}

@ -1,40 +0,0 @@
{ config, pkgs, lib, ... }:
let
cfg = config.programs.cargo;
format = pkgs.formats.toml { };
cargoHome = config.home.sessionVariables.CARGO_HOME or "${config.home.homeDirectory}/.cargo";
relativeCargoHome = lib.strings.removePrefix config.home.homeDirectory cargoHome;
in
{
options.programs.cargo = {
enable = lib.mkEnableOption "cargo, the rust package manager and build tool";
package = lib.mkPackageOption pkgs "cargo" { };
addPackageToEnvironment = lib.mkOption {
description = "Whether to add cargo to the user's environment.";
type = lib.types.bool;
default = true;
example = false;
};
settings = lib.mkOption {
description = "cargo settings";
type = lib.types.submodule {
freeformType = format.type;
};
};
};
config = lib.mkIf cfg.enable {
home = {
sessionVariables.CARGO_HOME = lib.mkIf config.home.preferXdgDirectories (lib.mkDefault "${config.xdg.dataHome}/cargo");
packages = lib.mkIf cfg.addPackageToEnvironment [ cfg.package ];
file."${relativeCargoHome}/config.toml" = lib.mkIf (cfg.settings != { }) {
source = format.generate "cargo-config.toml" cfg.settings;
};
};
};
}

@ -1,51 +0,0 @@
{ config, pkgs, lib, ... }:
let
cfg = config.programs.direnv;
in
{
options.programs.direnv.auto-prune-allowed-dirs = {
enable = lib.mkEnableOption "automatic pruning of direnv dirs";
onCalendar = lib.mkOption {
type = lib.types.str;
default = "daily";
example = "weekly";
# TODO: link to systemd manpage for format.
description = "How often to prune dirs.";
};
};
config = lib.mkIf cfg.auto-prune-allowed-dirs.enable {
systemd.user.services.direnv-auto-prune-allowed-dirs = {
Unit = {
Description = "Prune unused allowed directories for direnv";
Documentation = [ "man:direnv(1)" ];
ConditionPathExists = "${config.xdg.dataHome}/direnv/allow";
};
Service = {
Type = "oneshot";
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
ExecStart = "${lib.getExe cfg.package} prune";
};
};
systemd.user.timers.direnv-auto-prune-allowed-dirs = {
Unit = {
Description = "Prune unused allowed directories for direnv";
Documentation = [ "man:direnv(1)" ];
};
Timer = {
Unit = "direnv-auto-prune-allowed-dirs.service";
OnCalendar = cfg.auto-prune-allowed-dirs.onCalendar;
Persistent = true;
};
Install = {
WantedBy = [ "timers.target" ];
};
};
};
}

@ -1,10 +0,0 @@
{ ... }:
{
imports = [
./auto-refresh-keys.nix
./auto-update-trust-db.nix
# ./key-fetchers/declarative-github-key-fetcher.nix # WIP
./key-fetchers/declarative-keyserver-key-fetcher.nix
];
}

@ -1,93 +0,0 @@
{ config, pkgs, lib, ... }:
let
cfg = config.programs.gpg;
in
{
# TODO: Create proper descriptions
options = {
programs.gpg.key-fetchers.github = {
enable = lib.mkEnableOption "auto fetching of gpg keys by github username";
useGh = lib.mkEnableOption "" // {
description = "Whether to use the GitHub API through the gh tools to fetch GPG keys";
default = config.programs.gh.enable;
defaultText = lib.literalExpression "config.programs.gh.enable";
};
keys = lib.mkOption {
description = "";
default = { };
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
options = {
# id = lib.mkOption {
# description = "";
# default = name;
# example = "";
# type = lib.types.str;
# };
username = lib.mkOption {
description = "";
default = name;
type = lib.types.nonEmptyStr;
};
trust = lib.mkOption {
description = "If marked as null, it's mutable";
default = null;
example = 4;
type = with lib.types; nullOr (ints.between 1 5);
};
};
}));
};
};
};
config = lib.mkIf cfg.key-fetchers.github.enable {
systemd.user.services."gpg-fetch-github-key@" = {
description = "Fetch GPG keys for GitHub user %i";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
# TODO: warn if user or key does not exist
ExecStart = let
ghScript = pkgs.writeShellApplication {
name = "fetch-github-gpg-keys";
runtimeInputs = [
config.programs.gh.package
pkgs.jq
cfg.package
];
text = ''
gh api users/''${1}/gpg_keys | jq -r '.[].raw_key' | gpg --import
'';
};
curlScript = pkgs.writeShellApplication {
name = "fetch-github-gpg-keys";
runtimeInputs = [
pkgs.curl
pkgs.jq
cfg.package
];
text = ''
curl -s https://api.github.com/users/''${1}/gpg_keys | jq -r '.[].raw_key' | gpg --import
'';
};
in if cfg.key-fetchers.github.useGh then ghScript else curlScript;
Restart = "on-failure";
RestartSec = "10s";
Environment = [
"GNUPGHOME=${cfg.homedir}"
];
};
};
# systemd.user.timers =
};
}

@ -1,6 +0,0 @@
{
imports = [
./vacuum.nix
./fetch-articles.nix
];
}

@ -1,53 +0,0 @@
{ config, pkgs, lib, ... }:
let
cfg = config.programs.newsboat;
package = pkgs.newsboat;
in
{
options.programs.newsboat.fetch-articles = {
enable = lib.mkEnableOption "automatic article fetcher for newsboat";
onCalendar = lib.mkOption {
type = lib.types.str;
default = "daily";
example = "weekly";
# TODO: link to systemd manpage for format.
description = "How often to fetch new articles.";
};
};
config = lib.mkIf cfg.fetch-articles.enable {
# TODO: wait for internet
systemd.user.services.newsboat-fetch-articles = {
Unit = {
Description = "Automatically fetch new articles for newsboat";
Documentation = [ "man:newsboat(1)" ];
};
Service = {
Type = "oneshot";
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
ExecStart = "${lib.getExe pkgs.flock} %t/newsboat.lock ${lib.getExe package} --execute=reload";
};
};
systemd.user.timers.newsboat-fetch-articles = {
Unit = {
Description = "Automatically fetch new articles for newsboat";
Documentation = [ "man:newsboat(1)" ];
After = [ "network.target" ];
};
Timer = {
Unit = "newsboat-fetch-articles.service";
OnCalendar = cfg.fetch-articles.onCalendar;
Persistent = true;
};
Install = {
WantedBy = [ "timers.target" ];
};
};
};
}

@ -1,51 +0,0 @@
{ config, pkgs, lib, ... }:
let
cfg = config.programs.newsboat;
package = pkgs.newsboat;
in
{
options.programs.newsboat.vacuum = {
enable = lib.mkEnableOption "automatic cleaning of the newsboat cache";
onCalendar = lib.mkOption {
type = lib.types.str;
default = "weekly";
example = "monthly";
# TODO: link to systemd manpage for format.
description = "How often to run the cleaning.";
};
};
config = lib.mkIf cfg.vacuum.enable {
systemd.user.services.newsboat-vacuum = {
Unit = {
Description = "Automatically clean newsboat cache";
Documentation = [ "man:newsboat(1)" ];
};
Service = {
Type = "oneshot";
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
ExecStart = "${lib.getExe pkgs.flock} %t/newsboat.lock ${lib.getExe package} --vacuum";
};
};
systemd.user.timers.newsboat-vacuum = {
Unit = {
Description = "Automatically clean newsboat cache";
Documentation = [ "man:newsboat(1)" ];
};
Timer = {
Unit = "newsboat-vacuum.service";
OnCalendar = cfg.vacuum.onCalendar;
Persistent = true;
};
Install = {
WantedBy = [ "timers.target" ];
};
};
};
}

@ -1,109 +0,0 @@
{ config, pkgs, lib, ... }:
let
cfg = config.programs.prism-launcher;
in
{
imports = [
../../systemd-tmpfiles.nix
];
options.programs.prism-launcher = {
enable = lib.mkEnableOption "PrismLauncher, an open source minecraft launcher";
package = lib.mkPackageOption pkgs "prismlauncher" { };
stateDir = lib.mkOption {
description = "The directory where PrismLauncher stores it's state";
type = lib.types.path;
default = "${config.xdg.dataHome}/PrismLauncher";
defaultText = lib.literalExpression ''"''${config.xdg.dataHome}/PrismLauncher"'';
};
screenshotMover = {
enable = lib.mkEnableOption "a systemd unit that automatically moves screenshots from all minecraft instances into a common dir";
screenshotDir = lib.mkOption {
description = "Where to move the minecraft screenshots.";
type = lib.types.path;
default = if config.xdg.userDirs.pictures != null
then "${config.xdg.userDirs.pictures}/prismlauncher-screenshots"
else "${config.home.homeDirectory}/Pictures";
defaultText = lib.literalExpression ''
if config.xdg.userDirs.pictures != null
then "''${config.xdg.userDirs.pictures}/prismlauncher-screenshots"
else "''${config.home.homeDirectory}/Pictures"
'';
example = lib.literalExpression ''
"''${config.home.homeDirectory}/minecraft-screenshots"
'';
};
};
};
config = lib.mkIf cfg.enable {
home.packages = [ cfg.package ];
systemd.user.paths.prismlauncher-move-minecraft-screenshots = lib.mkIf cfg.screenshotMover.enable {
Install.WantedBy = [ "paths.target" ];
Unit.Description = "Watchdog that moves screenshots from all prismlauncher minecraft instances into a common dir";
Path = {
PathExistsGlob = [
"${cfg.stateDir}/instances/*/.minecraft/screenshots/*.png"
"${cfg.stateDir}/instances/*/minecraft/screenshots/*.png"
];
Unit = "prismlauncher-move-minecraft-screenshots.service";
TriggerLimitIntervalSec = "1s";
TriggerLimitBurst = "1";
};
};
systemd.user.services.prismlauncher-move-minecraft-screenshots = lib.mkIf cfg.screenshotMover.enable {
Unit.Description = "Watchdog that moves screenshots from all prismlauncher minecraft instances into a common dir";
Service = {
Type = "oneshot";
ExecStart = lib.getExe (pkgs.writeShellApplication {
name = "prismlauncher-move-minecraft-screenshots.sh";
runtimeInputs = with pkgs; [ coreutils findutils ];
text = let
instancesDir = "${cfg.stateDir}/instances";
in ''
shopt -s nullglob
for idir in "${instancesDir}"/*/; do
INSTANCE_NAME="''${idir#${instancesDir}/}"
INSTANCE_NAME="''${INSTANCE_NAME%'/'}"
SCREENSHOT_TARGET_DIR="${cfg.screenshotMover.screenshotDir}/$INSTANCE_NAME"
mkdir -p "''${SCREENSHOT_TARGET_DIR}"
for variant in minecraft .minecraft; do
SCREENSHOT_SOURCE_DIR="${instancesDir}/$INSTANCE_NAME/$variant"/screenshots
if [ -d "$SCREENSHOT_SOURCE_DIR" ]; then
echo "Scanning for screenshots in $SCREENSHOT_SOURCE_DIR"
for screenshot in "$SCREENSHOT_SOURCE_DIR"/*.png; do
echo "Moving '$screenshot' -> '$SCREENSHOT_TARGET_DIR'"
cp --preserve=all "$screenshot" "$SCREENSHOT_TARGET_DIR"
rm "$screenshot"
done
fi
done
done
'';
});
PrivateUsers = true;
PrivateNetwork = true;
ProtectSystem = true;
NoNewPrivileges = true;
ProtectKernelTunables = true;
ProtectControlGroups = true;
RestrictAddressFamilies = [ ];
RestrictNamespaces = true;
};
};
systemd.user.tmpfiles.settings."10-prismlauncher" = lib.mkIf cfg.screenshotMover.enable {
${cfg.screenshotMover.screenshotDir}.d = {
user = config.home.username;
};
};
};
}

@ -1,9 +0,0 @@
{ ... }:
{
# TODO: create thingamajig that watches ~/Downloads and pulls all new files to
# directory specified by systemd %i
# systemd.services.
# systemd.paths
}

@ -1,159 +0,0 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.downloads-sorter;
in
{
imports = [
../systemd-tmpfiles.nix
];
options.services.downloads-sorter = {
enable = lib.mkEnableOption "downloads sorter units, path activated units to keep the download dir clean";
downloadsDirectory = lib.mkOption {
type = lib.types.path;
description = "Which directory to keep clean";
default = if config.xdg.userDirs.enable then config.xdg.userDirs.download else "${config.home.homeDirectory}/Downloads";
defaultText = ''
if config.xdg.userDirs.enable then config.xdg.userDirs.download else "''${config.home.homeDirectory}/Downloads"
'';
example = ''
"''${config.home.homeDirectory}/downloads"
'';
};
mappings = lib.mkOption {
type = let
mappingType = lib.types.submodule ({ name, ... }: {
options = {
unitName = lib.mkOption {
type = lib.types.str;
description = ''
The basename of the path/service unit responsible for this mapping
'';
default = "downloads-sorter@${name}";
example = "downloads-sorter@asdf";
};
dir = lib.mkOption {
type = lib.types.path;
description = ''
Absolute path to the directory where matching files should be moved.
'';
default = if builtins.substring 0 1 name == "/" then name else "${cfg.downloadsDirectory}/${name}";
defaultText = ''
if builtins.substring 0 1 name == "/" then name else "''${config.services.downloads-sorter.downloadsDirectory}/''${name}"
'';
};
globs = lib.mkOption {
type = with lib.types; listOf str;
description = ''
A list of globs that match the files that should be moved.
'';
example = [
"*.jpg"
"IMG_*_2020_*.png"
];
apply = map (g: "${cfg.downloadsDirectory}/${g}");
};
createDirIfNotExists = lib.mkOption {
type = lib.types.bool;
description = ''
Whether to create the target directory if it does not exist yet.
Turn this off if you'd like the target directory to be a symlink or similar.
'';
default = true;
example = false;
};
# TODO: allow specifying a dynamic filter together with a system path trigger in an attrset.
};
});
in with lib.types; attrsOf (coercedTo (listOf str) (globs: { inherit globs; }) mappingType);
description = ''
A mapping from a file pattern to the location where it should be moved.
By default, the output mapping is relative to the download dir.
If an absolute path is given, the sorter will move the files out of the downloads dir.
'';
default = { };
example = {
"pictures" = [
"*.png"
"*.jpg"
];
"documents" = {
createDirIfNotExists = false;
globs = [ "*.pdf" ];
};
"/home/<user>/archives" = [ "*.rar" ];
};
};
};
config = lib.mkIf cfg.enable {
systemd.user.paths = lib.mapAttrs' (dir: mapping: {
name = mapping.unitName;
value = {
Install.WantedBy = [ "paths.target" ];
Path = {
PathExistsGlob = mapping.globs;
Unit = "${mapping.unitName}.service";
TriggerLimitIntervalSec = "1s";
TriggerLimitBurst = "1";
};
};
}) cfg.mappings;
# TODO: deduplicate
systemd.user.services = lib.mapAttrs' (dir: mapping: {
name = mapping.unitName;
value = {
Unit.Description = "Downloads directory watchdog, sorts the downloads directory";
Service = {
Type = "oneshot";
SyslogIdentifier = mapping.unitName;
ExecStart = let
script = pkgs.writeShellApplication {
name = "downloads-sorter-${dir}.sh";
runtimeInputs = [ pkgs.coreutils ];
text = ''
shopt -s nullglob
FILES=(${builtins.concatStringsSep " " mapping.globs})
for file in "''${FILES[@]}"; do
echo "$file -> ${mapping.dir}"
mv "$file" '${mapping.dir}'
done
'';
};
in lib.getExe script;
PrivateUsers = true;
ProtectSystem = true;
NoNewPrivileges = true;
ProtectKernelTunables = true;
ProtectControlGroups = true;
PrivateNetwork = true;
RestrictNamespaces = true;
};
};
}) cfg.mappings;
systemd.user.tmpfiles.settings."10-downloads-sorter-service" = let
absolutePaths = lib.pipe cfg.mappings [
builtins.attrValues
(builtins.filter (m: m.createDirIfNotExists))
(map (m: m.dir))
];
in lib.genAttrs absolutePaths (_: {
d = {
user = config.home.username;
};
});
};
}

@ -1,54 +0,0 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.mpd;
in
{
options.services.mpd.autoUpdateDatabase = lib.mkEnableOption "watchdog that updates the mpd database upon file changes";
config = lib.mkIf cfg.autoUpdateDatabase {
systemd.user.paths.mpd-update-database = {
Install.WantedBy = [ "paths.target" ];
Unit = {
Description = "Watchdog that updates the mpd database upon file changes";
Documentation = [
"man:mpd(1)"
"man:mpd.conf(5)"
];
};
Path = {
PathChanged = [
cfg.musicDirectory
cfg.playlistDirectory
];
Unit = "mpd-update-database.service";
TriggerLimitIntervalSec = "1s";
TriggerLimitBurst = "1";
};
};
systemd.user.services.mpd-update-database = {
Unit = {
Description = "Watchdog that updates the mpd library whenever the files are modified";
Documentation = [
"man:mpd(1)"
"man:mpd.conf(5)"
];
};
Service = {
Type = "oneshot";
ExecStart = "${lib.getExe pkgs.mpc-cli} update --wait";
PrivateUsers = true;
ProtectSystem = true;
NoNewPrivileges = true;
ProtectKernelTunables = true;
ProtectControlGroups = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_UNIX"
];
RestrictNamespaces = true;
};
};
};
}

@ -1,161 +1,50 @@
{ config, pkgs, lib, extendedLib, ... }: let
{ pkgs, lib, extendedLib, inputs, config, ... }: let
inherit (lib) types mkEnableOption mkOption mdDoc;
cfg = config.local.shell;
shellAliasesFormat = let
formatLib = {
functors = let
inherit (extendedLib.termColors.front) blue;
in
{
"|" = {
apply = f: lib.concatStringsSep " | " f.alias;
stringify = f: lib.concatStringsSep (blue "\n| ") f.alias;
};
"&&" = {
apply = f: lib.concatStringsSep " && " f.alias;
stringify = f: lib.concatStringsSep (blue "\n&& ") f.alias;
};
";" = {
apply = f: lib.concatStringsSep "; " f.alias;
stringify = f: lib.concatStringsSep (blue ";\n ") f.alias;
};
" " = {
apply = f: lib.concatStringsSep " " f.alias;
stringify = f: lib.concatStringsSep " \\\n " f.alias;
};
};
# NOTE:
# This module is an over-engineered solution to a non-problem.
# It is a fun experiment in using the Nix language to create a
# shell alias system that organizes aliases into a tree structure,
# with categories and subcategories and subsubcategories and so on.
#
# It also has a lazy join function that will join a list of commands
# with a separator, but render it in a prettier way in a documentation
# file that you can print out and read.
isAlias = v: builtins.isAttrs v && v ? "alias" && v ? "type";
};
in {
lib = formatLib;
type = let
rawAliasType = lib.types.submodule {
options = {
type = lib.mkOption {
description = "If the alias is a list of commands, this is the kind of separator that will be used.";
type = lib.types.enum (lib.attrNames formatLib.functors);
default = ";";
example = "&&";
};
alias = lib.mkOption {
description = "List of commands that will be concatenated together.";
type = with lib.types; listOf str;
example = [
"ls"
"grep nix"
];
};
};
};
coercedAliasType = with lib.types; let
coerce = str: {
type = " ";
alias = [ str ];
};
in (coercedTo str coerce rawAliasType) // {
check = v: builtins.isString v || formatLib.isAlias v;
};
aliasTreeType = with lib.types; attrsOf (either coercedAliasType aliasTreeType);
in aliasTreeType;
# Alias Tree -> { :: Alias }
generateAttrs = let
inherit (lib) mapAttrs attrValues filterAttrs isAttrs
isString concatStringsSep foldr;
applyFunctor = attrset: formatLib.functors.${attrset.type}.apply attrset;
# TODO: better naming
allAttrValuesAreStrings = attrset: let
# [ {String} ]
filteredAliases = [(filterAttrs (_: isString) attrset)];
# [ {String} ]
remainingFunctors = let
functorSet = filterAttrs (_: formatLib.isAlias) attrset;
appliedFunctorSet = mapAttrs (_: applyFunctor) functorSet;
in [ appliedFunctorSet ];
# [ {AttrSet} ]
remainingAliasSets = attrValues (filterAttrs (_: v: isAttrs v && !formatLib.isAlias v) attrset);
# [ {String} ]
recursedAliasSets = filteredAliases
++ (remainingFunctors)
++ (map allAttrValuesAreStrings remainingAliasSets);
in foldr (a: b: a // b) {} recursedAliasSets;
in
allAttrValuesAreStrings;
# TODO:
# generateAttrs = pipe [
# collect leave nodes
# map apply functor
# ]
# Alias Tree -> String
generateText = aliases: let
inherit (extendedLib.termColors.front) red green blue;
# String -> Alias -> String
stringifyAlias = aliasName: alias: let
# String -> String
removeNixLinks = text: let
maybeMatches = lib.match "(|.*[^)])(/nix/store/.*/bin/).*" text;
matches = lib.mapNullable (lib.remove "") maybeMatches;
in
if (maybeMatches == null)
then text
else lib.replaceStrings matches (lib.replicate (lib.length matches) "") text;
# Alias -> String
applyFunctor = attrset: let
applied = formatLib.functors.${attrset.type}.stringify attrset;
indent' = lib.strings.replicate (lib.stringLength "${aliasName} -> ") " ";
in
lib.replaceStrings ["\n"] [("\n" + indent')] applied;
in "${red aliasName} -> ${blue "\""}${removeNixLinks (applyFunctor alias)}${blue "\""}";
# String -> String
indent = x: lib.pipe x [
(x: "\n" + x)
(lib.replaceStrings ["\n"] [("\n" + (lib.strings.replicate 2 " "))])
(lib.removePrefix "\n")
];
# String -> { :: Alias | Category } -> String
stringifyCategory = categoryName: category: lib.pipe category [
(category: let
aliases = lib.filterAttrs (_: formatLib.isAlias) category;
in {
inherit aliases;
subcategories = lib.removeAttrs category (lib.attrNames aliases);
})
({ aliases, subcategories }: {
aliases = lib.mapAttrsToList stringifyAlias aliases;
subcategories = lib.mapAttrsToList stringifyCategory subcategories;
})
({ aliases, subcategories }:
lib.concatStringsSep "\n" (lib.filter (x: lib.trim x != "") [
"[${green categoryName}]"
(indent (lib.concatStringsSep "\n" aliases) + "\n")
(indent (lib.concatStringsSep "\n" subcategories) + "\n")
])
)
];
in (stringifyCategory "Aliases" aliases);
};
isAlias = v: builtins.isAttrs v && v ? "alias" && v ? "type";
in {
options.local.shell = {
aliases = lib.mkOption {
# TODO: freeformType
type = shellAliasesFormat.type;
aliases = let
coerceStrToAlias = str: {
type = " ";
alias = [ str ];
};
aliasType = (types.coercedTo types.str coerceStrToAlias (types.submodule {
options = {
type = mkOption {
type = types.enum [ "|" "&&" ";" " " ];
default = ";";
description = ''
If the alias is a list of commands, this is the kind of separator that will be used.
'';
};
alias = mkOption {
type = types.listOf types.str;
};
};
})) // {
# NOTE: this check is necessary, because nix will recurse on types.either,
# and report that the option does not exist.
# See https://discourse.nixos.org/t/problems-with-types-oneof-and-submodules/15197
check = v: builtins.isString v || isAlias v;
};
recursingAliasTreeType = types.attrsOf (types.either aliasType recursingAliasTreeType);
in mkOption {
type = recursingAliasTreeType;
description = "A tree of aliases";
default = { };
example = {
@ -182,8 +71,8 @@ in {
};
};
variables = lib.mkOption {
type = with lib.types; attrsOf str;
variables = mkOption {
type = types.attrsOf types.str;
description = "Environment variables";
default = { };
};
@ -193,19 +82,129 @@ in {
# };
enablePackageManagerLecture = lib.mkEnableOption "distro reminder messages, aliased to common package manager commands";
enableAliasOverview = lib.mkEnableOption "`aliases` command that prints out a list of all aliases" // {
enablePackageManagerLecture = mkEnableOption "distro reminder messages, aliased to common package manager commands";
enableAliasOverview = mkEnableOption "`aliases` command that prints out a list of all aliases" // {
default = true;
example = false;
};
};
config = {
xdg.dataFile = {
"aliases".text = shellAliasesFormat.generateText cfg.aliases;
config = let
sedColor =
color:
inputPattern:
outputPattern:
"-e \"s|${inputPattern}|${outputPattern.before or ""}$(tput setaf ${toString color})${outputPattern.middle}$(tput op)${outputPattern.after or ""}|g\"";
"packageManagerLecture" = lib.mkIf cfg.enablePackageManagerLecture {
colorRed = sedColor 1;
colorSlashes = colorRed "/" {middle = "/";};
# Alias type functors
# These will help pretty print the commands
functors = let
inherit (lib.strings) concatStringsSep;
inherit (extendedLib.termColors.front) blue;
in
{
"|" = {
apply = f: concatStringsSep " | " f.alias;
stringify = f: concatStringsSep (blue "\n| ") f.alias;
};
"&&" = {
apply = f: concatStringsSep " && " f.alias;
stringify = f: concatStringsSep (blue "\n&& ") f.alias;
};
";" = {
apply = f: concatStringsSep "; " f.alias;
stringify = f: concatStringsSep (blue ";\n ") f.alias;
};
" " = {
apply = f: concatStringsSep " " f.alias;
stringify = f: concatStringsSep " \\\n " f.alias;
};
};
aliasTextOverview = let
inherit (lib) stringLength length concatStringsSep replaceStrings
attrValues mapAttrs isAttrs remove replicate mapNullable;
inherit (extendedLib.termColors.front) red green blue;
# String -> String -> String
wrap' = wrapper: str: wrapper + str + wrapper;
# [String] -> String -> String -> String
replaceStrings' = from: to: replaceStrings from (replicate (length from) to);
# String -> Int -> String
repeatString = string: times: concatStringsSep "" (replicate times string);
# int -> String -> AttrSet -> String
stringifyCategory = level: name: category: let
title = "${repeatString " " level}[${green name}]";
commands = attrValues ((lib.flip mapAttrs) category (n: v: let
# String
indent = repeatString " " level;
# String -> String
removeNixLinks = text: let
maybeMatches = builtins.match "(|.*[^)])(/nix/store/.*/bin/).*" text;
matches = mapNullable (remove "") maybeMatches;
in
if (maybeMatches == null)
then text
else replaceStrings' matches "" text;
applyFunctor = attrset: let
applied = functors.${attrset.type}.stringify attrset;
indent' = indent + (repeatString " " ((stringLength " -> \"") + (stringLength n))) + " ";
in
replaceStrings' ["\n"] ("\n" + indent') applied;
recurse = stringifyCategory (level + 1) n v;
in if isAlias v
then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks (applyFunctor v))}"
else recurse
));
in concatStringsSep "\n" ([title] ++ commands) + "\n";
in (stringifyCategory 0 "Aliases" cfg.aliases) + "\n";
flattenedAliases = let
inherit (lib) mapAttrs attrValues filterAttrs isAttrs
isString concatStringsSep foldr;
applyFunctor = attrset: functors.${attrset.type}.apply attrset;
# TODO: better naming
allAttrValuesAreStrings = attrset: let
# [ {String} ]
filteredAliases = [(filterAttrs (n: v: isString v) attrset)];
# [ {String} ]
remainingFunctors = let
functorSet = filterAttrs (_: v: isAlias v) attrset;
appliedFunctorSet = mapAttrs (n: v: applyFunctor v) functorSet;
in [ appliedFunctorSet ];
# [ {AttrSet} ]
remainingAliasSets = attrValues (filterAttrs (_: v: isAttrs v && !isAlias v) attrset);
# [ {String} ]
recursedAliasSets = filteredAliases
++ (remainingFunctors)
++ (map allAttrValuesAreStrings remainingAliasSets);
in foldr (a: b: a // b) {} recursedAliasSets;
in
allAttrValuesAreStrings cfg.aliases;
in {
xdg.dataFile = {
aliases.text = aliasTextOverview;
packageManagerLecture = lib.mkIf cfg.enablePackageManagerLecture {
target = "package-manager.lecture";
text = let
inherit (extendedLib.termColors.front) red blue;
@ -243,22 +242,18 @@ in {
programs = {
zsh = {
shellAliases = shellAliasesFormat.generateAttrs cfg.aliases;
shellAliases = flattenedAliases;
sessionVariables = cfg.variables;
};
bash = {
shellAliases = shellAliasesFormat.generateAttrs cfg.aliases;
shellAliases = flattenedAliases;
sessionVariables = cfg.variables;
};
fish = {
shellAliases = shellAliasesFormat.generateAttrs cfg.aliases;
shellAliases = flattenedAliases;
# TODO: fish does not support session variables?
# localVariables = cfg.variables;
};
nushell = {
shellAliases = shellAliasesFormat.generateAttrs cfg.aliases;
environmentVariables = cfg.variables;
};
};
};
}

@ -1,168 +0,0 @@
# Taken from nixpkgs: nixos/modules/system/boot/systemd/tmpfiles.nix
{ config, pkgs, lib, unstable-pkgs, ... }:
let
# TODO: 24.05, year of the types.attrsWith
inherit (unstable-pkgs.lib) types mkOption;
cfg = config.systemd.user.tmpfiles;
attrsWith' =
placeholder: elemType:
types.attrsWith {
inherit elemType;
inherit (lib) placeholder;
};
escapeArgument = lib.strings.escapeC [
"\t"
"\n"
"\r"
" "
"\\"
];
settingsOption = {
description = ''
Declare systemd-tmpfiles rules to create, delete, and clean up volatile
and temporary files and directories.
Even though the service is called `*tmp*files` you can also create
persistent files.
'';
example = {
"10-mypackage" = {
"/var/lib/my-service/statefolder".d = {
mode = "0755";
user = "root";
group = "root";
};
};
};
default = { };
type = attrsWith' "config-name" (
attrsWith' "path" (
attrsWith' "tmpfiles-type" (
lib.types.submodule (
{ name, config, ... }:
{
options.type = mkOption {
type = types.str;
default = name;
defaultText = "tmpfiles-type";
example = "d";
description = ''
The type of operation to perform on the file.
The type consists of a single letter and optionally one or more
modifier characters.
Please see the upstream documentation for the available types and
more details:
{manpage}`tmpfiles.d(5)`
'';
};
options.mode = mkOption {
type = types.str;
default = "-";
example = "0755";
description = ''
The file access mode to use when creating this file or directory.
'';
};
options.user = mkOption {
type = types.str;
default = "-";
example = "root";
description = ''
The user of the file.
This may either be a numeric ID or a user/group name.
If omitted or when set to `"-"`, the user and group of the user who
invokes systemd-tmpfiles is used.
'';
};
options.group = mkOption {
type = types.str;
default = "-";
example = "root";
description = ''
The group of the file.
This may either be a numeric ID or a user/group name.
If omitted or when set to `"-"`, the user and group of the user who
invokes systemd-tmpfiles is used.
'';
};
options.age = mkOption {
type = types.str;
default = "-";
example = "10d";
description = ''
Delete a file when it reaches a certain age.
If a file or directory is older than the current time minus the age
field, it is deleted.
If set to `"-"` no automatic clean-up is done.
'';
};
options.argument = mkOption {
type = types.str;
default = "";
example = "";
description = ''
An argument whose meaning depends on the type of operation.
Please see the upstream documentation for the meaning of this
parameter in different situations:
{manpage}`tmpfiles.d(5)`
'';
};
}
)
)
)
);
};
# generates a single entry for a tmpfiles.d rule
settingsEntryToRule = path: entry: ''
'${entry.type}' '${path}' '${entry.mode}' '${entry.user}' '${entry.group}' '${entry.age}' ${escapeArgument entry.argument}
'';
# generates a list of tmpfiles.d rules from the attrs (paths) under tmpfiles.settings.<name>
pathsToRules = lib.mapAttrsToList (
path: types: lib.concatStrings (lib.mapAttrsToList (_type: settingsEntryToRule path) types)
);
mkRuleFileContent = paths: lib.concatStrings (pathsToRules paths);
in
{
options.systemd.user.tmpfiles.settings = lib.mkOption settingsOption;
config = lib.mkIf (cfg.settings != { }) {
assertions = [
(lib.hm.assertions.assertPlatform "systemd.user.tmpfiles" pkgs
lib.platforms.linux)
];
xdg.configFile = {
"systemd/user/basic.target.wants/systemd-tmpfiles-setup.service".source =
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service";
"systemd/user/systemd-tmpfiles-setup.service".source =
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service";
"systemd/user/timers.target.wants/systemd-tmpfiles-clean.timer".source =
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.timer";
"systemd/user/systemd-tmpfiles-clean.service".source =
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.service";
} // (lib.mapAttrs' (name: paths: {
name = "user-tmpfiles.d/${name}.conf";
value = {
text = mkRuleFileContent paths;
onChange = "${pkgs.systemd}/bin/systemd-tmpfiles --user --create";
};
}) cfg.settings);
};
}

@ -1,13 +0,0 @@
{ lib, ... }:
{
options.home = {
uid = lib.mkOption {
default = 1000;
type = lib.types.ints.between 0 60000;
};
gid = lib.mkOption {
default = 1000;
type = lib.types.ints.between 0 60000;
};
};
}

@ -1,38 +1,30 @@
{ pkgs, config, machineVars, machineName, ... }:
{ pkgs, config, machineVars, ... }:
{
home.packages = with pkgs; [
bandwhich
beets
binutils
cloc
cyme
czkawka
difftastic
# diskonaut
delta
diskonaut
duf
duff
fclones
ffmpeg
file
fselect
gitoxide
gh-dash
glances
gpauth
gpclient
gpg-tui
gping
graphviz
hexyl
htmlq
httpie
huniq
hyperfine
imagemagick
jq
kepubify
# keybase
keymapviz
libwebp
lnav
lolcat
lurk
mdcat
mediainfo
meli
@ -41,6 +33,7 @@
mtr
neofetch
nix-diff
nix-index
nix-output-monitor
nix-tree
nix-update
@ -48,31 +41,29 @@
# nixops
nmap
ouch
pandoc
parallel
pipr
progress
pwntools
python3
rclone
rip2
rnr
ripgrep
rsync
# sc-im
skim
slack-term
tea
tealdeer
terminal-parrot
termtosvg
toilet
tokei
trippy
unpaper
unzip
usbutils
uutils-coreutils-noprefix
uutils-coreutils
waifu2x-converter-cpp
watchexec
wavemon
wiki-tui
yt-dlp
yubico-pam
yubikey-agent
yubikey-manager
@ -90,53 +81,51 @@
ahoviewer
alsa-utils
anki
kdePackages.ark
ark
birdtray
calibre
cool-retro-term
darktable
discord
element-desktop
foliate
geogebra
ghidra
gimp
gnome-font-viewer
gnome.gnome-font-viewer
gnome.seahorse
google-chrome
imhex
imv
inkscape
insomnia
iwgtk
kid3
koreader
krita
# kdePackages.ktouch
ktouch
libnotify
libreoffice
light
mission-center
mopidy
mopidy-mpd
mopidy-soundcloud
mopidy-youtube
mpc_cli
naps2
nsxiv
nyxt
obsidian
# pcloud
pdfarranger
pwvucontrol
# scrcpy
seahorse
shellcheck
slack
# sublime3
# swiPrologWithGui
sxiv
tagainijisho
tenacity
thunderbird
# transcribe
webcamoid
wireshark
xcalib
xclip
xdotool
@ -158,15 +147,15 @@
touchegg
] ++ lib.optionals (machineVars.gaming) [
desmume
# osu-lazer
# retroarchFull
osu-lazer
(prismlauncher.override {
jdk17 = jdk21;
})
retroarchFull
steam
steam-tui
stepmania
taisei
] ++ lib.optionals (machineName != "dosei") [
# Source blocked by external firewall on dosei
pcloud
]
);
}

@ -43,9 +43,9 @@
duration = 20;
};
general.live_config_reload = true;
live_config_reload = true;
terminal.shell = {
shell = {
program = "${pkgs.zsh}/bin/zsh";
args = [ "--login" ];
};

@ -1,37 +0,0 @@
{ pkgs, lib, inputs, ... }:
{
programs.anyrun = {
enable = true;
config = {
y.fraction = 0.3;
width.fraction = 0.25;
plugins = [
"${pkgs.anyrun}/lib/libapplications.so"
];
hidePluginInfo = true;
closeOnClick = true;
showResultsImmediately = true;
};
extraCss = builtins.readFile (./. + "/style.css");
extraConfigFiles."applications.ron".text = let
preprocess_script = pkgs.writeShellApplication {
name = "anyrun-preprocess-application-exec";
runtimeInputs = [ ];
text = ''
shift # Remove term|no-term
echo "uwsm app -- $*"
'';
};
in ''
Config(
desktop_actions: false,
max_entries: 10,
preprocess_exec_script: Some("${lib.getExe preprocess_script}"),
terminal: Some("${lib.getExe pkgs.alacritty}"),
)
'';
};
}

@ -1,48 +0,0 @@
* {
all: unset;
font-size: 1.2rem;
}
#window,
#match,
#entry,
#plugin,
#main {
background: transparent;
}
#match.activatable {
border-radius: 8px;
margin: 4px 0;
padding: 4px;
/* transition: 100ms ease-out; */
}
#match.activatable:first-child {
margin-top: 12px;
}
#match.activatable:last-child {
margin-bottom: 0;
}
#match:hover {
background: rgba(255, 255, 255, 0.05);
}
#match:selected {
background: rgba(255, 255, 255, 0.1);
}
#entry {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 8px;
padding: 4px 8px;
}
box#main {
background: rgba(0, 0, 0, 0.5);
box-shadow:
inset 0 0 0 1px rgba(255, 255, 255, 0.1),
0 30px 30px 15px rgba(0, 0, 0, 0.5);
border-radius: 20px;
padding: 12px;
}

@ -1,4 +0,0 @@
{ ... }:
{
programs.aria2.enable = true;
}

@ -1,14 +1,15 @@
{ config, ... }:
let
cfg = config.programs.atuin;
xdg_runtime_dir = "/run/user/${toString config.home.uid}";
# TODO: retrieve this in a more dynamic and correct manner
xdg_runtime_dir = "/run/user/1000";
in
{
programs.atuin = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
enableNushellIntegration = config.programs.nushell.enable;
settings = {
db_path = "${config.xdg.dataHome}/atuin/history.db";

@ -1,16 +0,0 @@
{ config, ... }:
{
programs.bash = {
enable = true;
historyFile = "${config.xdg.dataHome}/bash_history";
historySize = 100000;
bashrcExtra = ''
source "${config.xdg.configHome}/mutable_env.sh"
'';
shellOptions = [
"histappend"
"checkwinsize"
"checkjobs"
];
};
}

@ -1,4 +0,0 @@
{ ... }:
{
programs.bat.enable = true;
}

@ -1,4 +0,0 @@
{ ... }:
{
programs.beets.enable = true;
}

@ -1,41 +0,0 @@
{ ... }:
{
programs.bottom = {
enable = true;
settings = {
flags.enable_gpu = true;
row = [
{
ratio = 30;
child = [{ type = "cpu"; }];
}
{
ratio = 40;
child = [
{
ratio = 4;
type = "mem";
}
{
ratio = 3;
type = "disk";
}
];
}
{
ratio = 30;
child = [
{
type = "net";
}
{
default = true;
type = "proc";
}
];
}
];
};
};
}

@ -9,7 +9,7 @@ in [
(link "GitHub" "http://github.com")
(short "/u/" "danger/u/" "https://dangeru.us/")
(link "PVV" "https://www.pvv.ntnu.no/")
(short "PVVM" "PVV Mail" "https://webmail.pvv.ntnu.no/roundcube/")
(short "PVVM" "PVV Mail" "https://webmail2.pvv.ntnu.no/roundcube/")
(short "ΩV" "Omega Verksted" "https://omegav.no/")
(dir "Nix" [
@ -31,34 +31,21 @@ in [
])
(dir "CTF" [
(link "Revshells" "https://revshells.com/")
(link "HackTheBox" "https://www.hackthebox.eu/")
(link "TryHackMe" "https://tryhackme.com/dashboard")
(link "OverTheWire" "https://overthewire.org/wargames/")
(link "NetGarage" "https://io.netgarage.org/")
(link "Exploit Education" "http://exploit.education/")
(link "Webhook" "https://webhook.site")
(link "CyberChef" "https://gchq.github.io/CyberChef/")
(link "Aperisolve" "https://www.aperisolve.com/")
(link "how2heap" "https://github.com/shellphish/how2heap")
(link "Heap Search" "https://kissprogramming.com/heap/heap-search")
(link "CrackStation" "https://crackstation.net/")
(link "FactorDB" "http://factordb.com/")
(link "Syscalls" "https://syscalls.w3challs.com/")
(link "DogBolt" "https://dogbolt.org/")
(link "HackTricks" "https://book.hacktricks.xyz/")
(dir "Practise" [
(link "S2G" "https://s2gctf.ncr.ntnu.no")
(link "Pico CTF" "https://play.picoctf.org/practice")
(link "Pwn college" "https://pwn.college/")
(link "HackTheBox" "https://www.hackthebox.eu")
(link "Crackmes" "https://crackmes.one")
(link "Nightmare" "https://guyinatuxedo.github.io/")
])
])
(dir "Misc & Tools" [
(link "ASCIIFlow" "https://asciiflow.com/#/")
(link "CopyChar" "https://copychar.cc/")
(link "CyberChef" "https://gchq.github.io/CyberChef/")
(link "Device Info" "https://www.deviceinfo.me/")
(link "Diagrams" "https://app.diagrams.net/")
(link "FakeMail" "http://www.fakemailgenerator.com/")
(link "FilePizza" "https://file.pizza/")
(link "IPLeak" "https://ipleak.net/")
(link "LaTeX" "https://www.codecogs.com/latex/eqneditor.php")
(link "ManualsLib" "https://www.manualslib.com/")

@ -1,10 +1,10 @@
{ pkgs, lib, ... }:
{ pkgs, ... }:
{
"amazondotcom-us".metaData.hidden = true;
"bing".metaData.hidden = true;
"wikipedia".metaData.hidden = true;
"google".metaData.alias = "gg";
"ddg".metaData.alias = "dd";
"Amazon.com".metaData.hidden = true;
"Bing".metaData.hidden = true;
"Wikipedia (en)".metaData.hidden = true;
"Google".metaData.alias = "gg";
"DuckDuckGo".metaData.alias = "dd";
"Arch Package Repository" = {
urls = [{
@ -57,29 +57,9 @@
definedAliases = [ "gh" ];
};
"GitHub Nix Configs" = {
urls = [{
template = "https://github.com/search";
params = [
{ name = "type"; value = "code"; }
{
name = "q";
value = lib.concatStringsSep " " [
"lang:nix"
"-is:fork"
"-repo:nixos/nixpkgs"
"{searchTerms}"
];
}
];
}];
icon = "${pkgs.super-tiny-icons}/share/icons/SuperTinyIcons/svg/github.svg";
definedAliases = [ "ghn" ];
};
"HomeManager Options" = {
urls = [{
template = "https://mipmip.github.io/home-manager-option-search/?query={searchTerms}";
template = "https://mipmip.github.io/home-manager-option-search/?{searchTerms}";
}];
icon = "${pkgs.super-tiny-icons}/share/icons/SuperTinyIcons/svg/nixos.svg";
definedAliases = [ "hms" ];
@ -166,7 +146,7 @@
definedAliases = [ "ut" ];
};
"youtube" = {
"YouTube" = {
urls = [{
template = "https://www.youtube.com/results";
params = [{ name = "search_query"; value = "{searchTerms}"; }];

@ -1,11 +0,0 @@
{ ... }:
{
programs.cargo = {
enable = true;
settings = {
cargo-new.vcs = "git";
};
};
home.sessionVariables.CARGO_NET_GIT_FETCH_WITH_CLI = "true";
}

@ -0,0 +1,38 @@
{ config, pkgs, lib, ... }:
let
cfg = config.programs.direnv;
in
{
config = {
systemd.user.services.prune-allowed-direnv-dirs = {
Unit = {
Description = "Prune unused allowed directories for direnv";
Documentation = [ "man:direnv(1)" ];
};
Service = {
Type = "oneshot";
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
ExecStart = "${lib.getExe cfg.package} prune";
};
};
systemd.user.timers.prune-allowed-direnv-dirs = {
Unit = {
Description = "Prune unused allowed directories for direnv";
Documentation = [ "man:direnv(1)" ];
};
Timer = {
Unit = "prune-allowed-direnv-dirs.service";
OnCalendar = "daily";
Persistent = true;
};
Install = {
WantedBy = [ "timers.target" ];
};
};
};
}

@ -1,14 +1,12 @@
{ config, ... }:
{ ... }:
{
imports = [
./auto-prune.nix
];
programs.direnv = {
enable = true;
silent = true;
nix-direnv.enable = true;
enableZshIntegration = true;
enableNushellIntegration = config.programs.nushell.enable;
auto-prune-allowed-dirs.enable = true;
nix-direnv.enable = true;
};
}

@ -1,8 +0,0 @@
{ config, ... }:
{
programs.eza = {
enable = true;
icons = "auto";
enableNushellIntegration = config.programs.nushell.enable;
};
}

@ -1,4 +0,0 @@
{ machineVars, ... }:
{
programs.feh.enable = !machineVars.headless;
}

@ -1,70 +1,18 @@
{ lib, pkgs, ... }:
{ pkgs, ... }:
{
programs.firefox = {
enable = true;
profiles.h7x4 = {
bookmarks = {
force = true;
settings = [{
toolbar = true;
bookmarks = import ./browser/bookmarks.nix;
}];
};
bookmarks = [{
toolbar = true;
bookmarks = import ./browser/bookmarks.nix;
}];
search = {
default = "google";
engines = import ./browser/engines.nix { inherit pkgs lib; };
default = "Google";
engines = import ./browser/engines.nix { inherit pkgs; };
force = true;
};
# TODO: make into structured attrs
settings = {
# TODO: collect more stuff from here
# https://github.com/arkenfox/user.js
"browser.aboutConfig.showWarning" = false;
"browser.newtabpage.activity-stream.showSponsored" = false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
"browser.newtabpage.activity-stream.feeds.telemetry" = false;
"browser.newtabpage.activity-stream.telemetry" = false;
"datareporting.policy.dataSubmissionEnabled" = false;
"datareporting.healthreport.uploadEnabled" = false;
"toolkit.telemetry.unified" = false;
"toolkit.telemetry.enabled" = false;
"toolkit.telemetry.server" = "data:,";
"toolkit.telemetry.archive.enabled" = false;
"toolkit.telemetry.newProfilePing.enabled" = false;
"toolkit.telemetry.shutdownPingSender.enabled" = false;
"toolkit.telemetry.updatePing.enabled" = false;
"toolkit.telemetry.bhrPing.enabled" = false;
"toolkit.telemetry.firstShutdownPing.enabled" = false;
"toolkit.telemetry.coverage.opt-out" = true;
"toolkit.coverage.opt-out" = true;
"toolkit.coverage.endpoint.base" = "";
"layout.css.prefers-color-scheme.content-override" = "dark";
"font.cjk_pref_fallback_order" = lib.concatStringsSep "," [
"ja"
"zh-cn"
"zh-hk"
"zh-tw"
"ko"
];
} // (lib.pipe null [
(_: {
"ja" = "JP";
"ko" = "KR";
"zh-CN" = "SC";
"zh-HK" = "HK";
"zh-TW" = "TC";
})
(lib.mapAttrsToList (lang: notoSuffix: {
"font.name.monospace.${lang}" = "Noto Sans Mono CJK ${notoSuffix}";
"font.name.sans-serif.${lang}" = "Noto Sans CJK ${notoSuffix}";
"font.name.serif.${lang}" = "Noto Serif CJK ${notoSuffix}";
}))
(lib.foldl lib.mergeAttrs { })
]);
settings = {};
};
};
}

@ -1,7 +0,0 @@
{ ... }:
{
programs.fzf = {
enable = true;
defaultCommand = "fd --type f";
};
}

@ -9,7 +9,7 @@
set print demangle on
set print sevenbit-strings off
set print asm-demangle on
set print elements 0
set print elements 0
# Assembly
set disassembly-flavor intel
@ -21,5 +21,5 @@
set prompt \001\033[1;36m\002(gdb) \001\033[0m\002
'';
# local.shell.aliases."System Tool Replacements".gdb = "${pkgs.pwndbg}/bin/pwndbg";
local.shell.aliases."System Tool Replacements".gdb = "${pkgs.pwndbg}/bin/pwndbg";
}

@ -1,4 +0,0 @@
{ ... }:
{
programs.gh-dash.enable = true;
}

@ -4,7 +4,7 @@
enable = true;
settings = {
gitProtocol = "ssh";
pager = "${pkgs.bat}/bin/bat";
pager = "${pkgs.bat}/git/bat";
aliases = {
co = "pr checkout";
pv = "pr view";

@ -14,6 +14,10 @@ let
];
in
{
imports = [
./maintenance-timers.nix
];
# TODO: convert to template once nix-sops supports it in hm module
sops.secrets."git/nordicsemi-config" = { };
@ -27,12 +31,9 @@ in
signing = {
key = "46B9228E814A2AAC";
# format = "openpgp";
signByDefault = true;
};
maintenance.enable = true;
lfs.enable = true;
delta = {
@ -46,82 +47,19 @@ in
aliases = {
aliases = "!git config --get-regexp alias | sed -re 's/alias\\.(\\S*)\\s(.*)$/\\1 = \\2/g'";
authors = "shortlog --summary --numbered --email";
delete-merged = "!git branch --merged | grep -v '\\*' | xargs -n 1 git branch -d";
ff = "fixup-fixup";
fi = "fixup-interactive";
graph = "log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all";
graphv = "log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all";
forcepush = "push --force-with-lease --force-if-includes";
git = "!git";
pp = "post-pr";
rebase-author = "rebase -i -x \"git commit --amend --reset-author -CHEAD\"";
reset-to-upstream = "!git reset --hard \"origin/$(git rev-parse --abbrev-ref HEAD)\"";
rf = "rebase-fixups";
authors = "shortlog --summary --numbered --email";
si = "switch-interactive";
subs = "submodule update --init --recursive";
} // (let
c = c: s: "%C(${c})${s}%C(reset)";
in {
graph = let
fmt = lib.concatStringsSep "" [
" - "
(c "bold blue" "%h")
" - "
(c "bold green" "(%ar)")
" "
(c "white" "> %s")
" "
(c "dim white" "- %an")
(c "bold yellow" "%d")
];
in "log --graph --abbrev-commit --decorate --format=format:'${fmt}' --all";
graphv = let
fmt = lib.concatStringsSep "" [
(c "bold blue" "%h")
" - "
(c "bold cyan" "%aD")
" "
(c "bold green" "(%ar)")
(c "bold yellow" "%d")
"%n"
" "
(c "white" "%s")
" "
(c "dim white" "- %an")
];
in "log --graph --abbrev-commit --decorate --format=format:'${fmt}' --all";
l = let
fmt = lib.concatStringsSep "%n" (map (x: if builtins.isList x then lib.concatStringsSep " " x else x) [
[ (c "bold yellow" "%H") (c "auto" "%d") ]
[ (c "bold white" "Author:") (c "bold cyan" "%aN <%aE>") (c "bold green" "(%ah)") ]
[ (c "bold white" "Committer:") (c "bold cyan" "%cN <%cE>") (c "bold green" "(%ah)") ]
[ (c "bold white" "GPG: (%G?)") (c "bold magenta" "%GF") "-" (c "bold cyan" "%GS") (c "bold blue" "(%GT) ") ]
""
(c "bold white" "# %s")
"%+b"
(c "dim yellow" "%+N")
]);
# sedExpressions = let
# colorExpr = "\\x1B\\[([0-9]{1,3}(;[0-9]{1,2};?)?)?[mGK]";
# colorEndExpr = "\\x1B\\[m";
# colored = x: "${colorExpr}${x}${colorEndExpr}";
# in lib.concatMapStringsSep " " (x: "-e '${x}'") [
# "s|${colored "GPG: \\(N\\)"} ${colored "F3CDA86CC55A9F10D7A069819F2F7D8250F35146"} - ${colored "h7x4 <h7x4@nani.wtf>"} ${colored "\\(ultimate\\)"}|GPG: h7x4|"
# "s|${colored "GPG: \\(N\\)"} ${colored ""} - ${colored ""} ${colored "\\(undefined\\)"}||"
# ];
in "log --decorate --format=tformat:'${fmt}'";
# in "!git log --color=always --format=format:'${fmt}' | sed -E ${sedExpressions} | $PAGER";
});
rebase-author = "rebase -i -x \"git commit --amend --reset-author -CHEAD\"";
git = "!git";
};
extraConfig = {
core = {
whitespace = lib.concatStringsSep "," [
"space-before-tab"
"-indent-with-non-tab"
"trailing-space"
"blank-at-eof"
];
whitespace = "space-before-tab,-indent-with-non-tab,trailing-space";
untrackedCache = true;
editor = "nvim";
};
@ -186,13 +124,10 @@ in
diff = {
mnemonicPrefix = true;
renames = true;
compactionHeuristic = true;
tool = "nvimdiff";
submodule = "log";
};
pager.show = lib.getExe pkgs.bat;
status = {
showUntrackedFiles = "all";
relativePaths = true;
@ -229,21 +164,6 @@ in
"url \"${lib.head github-uri-prefixes}\"".insteadOf = lib.tail github-uri-prefixes;
"url \"git@gist.github.com:\"".insteadOf = [
"git://gist.github.com/"
"https://gist.github.com/"
];
"url \"aur@aur.archlinux.org:\"".insteadOf = [
"aur:"
"https://aur.archlinux.org/"
];
gc = {
reflogExpire = "90 days";
reflogExpireUnreachable = "90 days";
};
web.browser = "google-chrome-stable";
"filter \"lfs\"" = {
@ -313,7 +233,7 @@ in
"nrfconnect"
"oysteintveit-nordicsemi"
];
in lib.genAttrs organizations (org: map (uri-prefix: "${uri-prefix}${org}") (github-uri-prefixes ++ [ "github-nordicsemi:" ]));
in lib.genAttrs organizations (org: map (uri-prefix: "${uri-prefix}${org}") github-uri-prefixes);
in {
extraConfig = lib.mergeAttrs
{
@ -333,87 +253,20 @@ in
})
];
systemd.user.services."git-maintenance@".Service = lib.mkIf cfg.maintenance.enable {
ExecStartPre = let
repoDirs = lib.escapeShellArgs [
"${config.home.homeDirectory}/git"
"${config.home.homeDirectory}/work"
"${config.home.homeDirectory}/pvv"
];
script = pkgs.writeShellApplication {
name = "discover-git-maintenance-repos";
text = ''
{
echo "[maintenance]"
for repoLocation in ${repoDirs}; do
for repo in "$repoLocation"/*/.git; do
echo "repo = $('${pkgs.coreutils}/bin/realpath' "''${repo%"/.git"}")"
done
done
} > "$1"
'';
};
in "${lib.getExe script} %t/maintenance-repos";
ExecStart = lib.mkForce ''
"${lib.getExe cfg.package}" -c include.path="%t/maintenance-repos" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%i
'';
};
home.packages = [
(pkgs.writeShellApplication {
name = "git-tcommit";
runtimeInputs = with pkgs; [ cfg.package coreutils ];
text = lib.fileContents ./scripts/git-tcommit.sh;
})
(pkgs.writeShellApplication {
name = "git-tmcommit";
runtimeInputs = with pkgs; [ cfg.package coreutils ];
text = lib.pipe ./scripts/git-tcommit.sh [
lib.fileContents
(builtins.replaceStrings ["hours" "tcommit"] ["minutes" "tmcommit"])
];
})
(pkgs.writeShellApplication {
name = "git-fixup-fixup";
runtimeInputs = with pkgs; [ cfg.package ];
text = lib.fileContents ./scripts/git-fixup-fixup.sh;
})
(pkgs.writeShellApplication {
name = "git-rebase-fixups";
runtimeInputs = with pkgs; [ cfg.package gnused ];
text = lib.fileContents ./scripts/git-rebase-fixups.sh;
})
(pkgs.writeShellApplication {
name = "git-fixup-interactive";
runtimeInputs = with pkgs; [ cfg.package gnused gnugrep skim ];
text = lib.fileContents ./scripts/git-fixup-interactive.sh;
})
(pkgs.writeShellApplication {
name = "git-switch-interactive";
runtimeInputs = with pkgs; [ cfg.package skim gnused gnugrep uutils-coreutils-noprefix ];
runtimeInputs = with pkgs; [ cfg.package fzf gnused coreutils ];
text = lib.fileContents ./scripts/git-switch-interactive.sh;
excludeShellChecks = [
"SC2001" # (style): See if you can use ${variable//search/replace} instead. (sed invocation)
];
})
((pkgs.writers.writePython3Bin "git-post-pr" {
libraries = with pkgs.python3Packages; [
tkinter
];
flakeIgnore = [
"E501" # I like long lines grr
];
} (lib.fileContents ./scripts/git-post-pr.py)).overrideAttrs (_: {
postFixup = ''
wrapProgram $out/bin/git-post-pr \
--prefix PATH : ${lib.makeBinPath [
pkgs.github-cli
]}
'';
}))
pkgs.git-absorb
];

@ -0,0 +1,56 @@
{ config, pkgs, lib, ... }:
let
cfg = config.programs.git;
in
{
systemd.user.services."git-maintenance@" = {
Unit = {
Description = "Optimize Git repositories data";
Documentation = [ "man:git-maintenance(1)" ];
};
Service = {
Type = "oneshot";
ExecStart = "${lib.getExe pkgs.git} for-each-repo --config=maintenance.repo maintenance run --no-quiet --schedule=%i";
Environment = [
"PATH=${lib.makeBinPath (with pkgs; [ cfg.package openssh ])}"
];
LockPersonality = "yes";
MemoryDenyWriteExecute = "yes";
NoNewPrivileges = "yes";
RestrictAddressFamilies = [
"AF_UNIX"
"AF_INET"
"AF_INET6"
"AF_VSOCK"
];
RestrictNamespaces = "yes";
RestrictRealtime = "yes";
RestrictSUIDSGID = "yes";
SystemCallArchitectures = "native";
SystemCallFilter = "@system-service";
};
};
systemd.user.timers."git-maintenance@" = {
Unit = {
Description = "Optimize Git repositories data";
Documentation = [ "man:git-maintenance(1)" ];
};
Timer = {
Persistent = true;
OnCalendar = "%i";
};
Install = {
WantedBy = [ "timers.target" ];
};
};
systemd.user.timers."git-maintenance@hourly".Timer.OnCalendar = "*-*-* 1..23:05:00";
systemd.user.timers."git-maintenance@daily".Timer.OnCalendar = "Tue..Sun *-*-* 0:05:00";
systemd.user.timers."git-maintenance@weekly".Timer.OnCalendar = "Mon 0:05:00";
}

@ -1,14 +0,0 @@
if [ -n "${1:-}" ]; then
TARGET_COMMIT="$1"
shift
else
TARGET_COMMIT="HEAD"
fi
COMMIT_MESSAGE=$(git log -1 --pretty=format:'%s' "$TARGET_COMMIT")
if [[ $COMMIT_MESSAGE =~ ^fixup!* ]]; then
git commit -m "$COMMIT_MESSAGE" "$@"
else
git commit --fixup "$TARGET_COMMIT" "$@"
fi

@ -1,18 +0,0 @@
if [ -n "${1:-}" ]; then
TARGET_BRANCH="$1"
shift
else
TARGET_BRANCH=$(git remote show origin | sed -n '/HEAD branch/s/.*: //p')
fi
FORK_POINT=$(git merge-base --fork-point "$TARGET_BRANCH")
COMMITS_SINCE_FORK_POINT=$(git log --format=format:'%s' "$FORK_POINT"..HEAD | grep -v -E '^fixup!')
RESULT=$(sk <<<"$COMMITS_SINCE_FORK_POINT")
if [ "$RESULT" == "" ]; then
echo "Doing nothing..."
else
git commit -m "fixup! $RESULT" "$@"
fi

@ -1,130 +0,0 @@
import argparse
import json
import subprocess
import tkinter
# TODO: add support for gitea, and maybe other git hosting options.
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
prog="post-pr",
description="Post links to PRs",
)
parser.add_argument("-n", "--no-clipboard", action="store_true", help="do not copy the message to the clipboard")
pr_id = parser.add_mutually_exclusive_group()
pr_id.add_argument("-c", "--current-branch", action="store_true", help="generate post for the PR for the current branch")
pr_id.add_argument("-l", "--latest", action="store_true", help="generate post for the latest PR for the current user")
pr_id.add_argument("pr_id", nargs="?", default=None, help="generate post for the PR with the given ID")
args = parser.parse_args()
if not any([args.current_branch, args.latest, args.pr_id,]):
args.current_branch = True
return args
def _gh(args: list[str]) -> str:
try:
return subprocess.check_output(["gh"] + args).decode("utf8")
except subprocess.CalledProcessError as e:
raise RuntimeError(f"GitHub CLI command failed: 'gh {' '.join(args)}'") from e
def _gh_retcode(args: list[str]) -> int:
return subprocess.run(["gh"] + args, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode
def ensure_gh_installed():
try:
if _gh_retcode(["--version"]) != 0:
raise RuntimeError("GitHub CLI (gh) is not installed, please install it")
except FileNotFoundError:
raise RuntimeError("GitHub CLI (gh) is not installed, please install it")
def ensure_gh_authenticated():
if _gh_retcode(["auth", "status"]) != 0:
raise RuntimeError("Failed to authenticate with GitHub, please run 'gh auth login'")
GH_PR_JSON_FIELDS = ",".join([
"additions",
"deletions",
"state",
"title",
"url",
])
def fetch_pr_data(current_branch: bool, latest: bool, pr_id: str | None) -> dict[str, any]:
if pr_id:
pr_data = _gh(["pr", "view", pr_id, "--json", GH_PR_JSON_FIELDS])
pr_data = json.loads(pr_data)
elif latest:
pr_list = _gh(["pr", "list", "--author", "@me", "--limit", "1", "--json", GH_PR_JSON_FIELDS])
pr_list = json.loads(pr_list)
if len(pr_list) == 0:
raise RuntimeError("Failed to find PR, are you sure you have any open PRs?")
pr_data = pr_list[0]
elif current_branch:
pr_data = _gh(["pr", "view", "--json", GH_PR_JSON_FIELDS])
pr_data = json.loads(pr_data)
return pr_data
def format_message(pr_data: dict[str, any]) -> str:
additions = pr_data["additions"]
deletions = pr_data["deletions"]
title = pr_data["title"]
pr_url = pr_data["url"]
pr_state = pr_data["state"]
state_html = f"({pr_state.lower()}) " if pr_state != "OPEN" else ""
additions_html = f"+{additions}" if additions > 0 else str(additions)
deletions_html = f"-{deletions}" if deletions > 0 else str(deletions)
return f"""{state_html}{pr_url} {title} [diff: {additions_html}/{deletions_html}]"""
def copy_to_clipboard(message: str):
r = tkinter.Tk()
r.withdraw()
r.clipboard_clear()
r.clipboard_append(message)
r.update()
r.destroy()
def main():
args = parse_args()
ensure_gh_installed()
ensure_gh_authenticated()
pr_data = fetch_pr_data(args.current_branch, args.latest, args.pr_id)
message = format_message(pr_data)
print("Message:\n")
print(f" {message}\n")
if not args.no_clipboard:
copy_to_clipboard(message)
print("Copied to clipboard")
if __name__ == "__main__":
try:
main()
except Exception as e:
print(f"Error: {e}")
exit(1)

@ -1,10 +0,0 @@
if [ -n "${1:-}" ]; then
TARGET_BRANCH="$1"
shift
else
TARGET_BRANCH=$(git remote show origin | sed -n '/HEAD branch/s/.*: //p')
fi
FORK_POINT=$(git merge-base --fork-point "$TARGET_BRANCH")
git rebase "$FORK_POINT" --autosquash "$@"

@ -6,7 +6,7 @@ if [ -n "${1:-}" ]; then
fi
BRANCHES=$(cat <(git branch) <(git branch --remotes) | grep --invert-match '^\*\|HEAD ->' | sed 's|^\s*||')
CHOSEN_BRANCH=$(sk --reverse --info=inline --preview 'git show --color {}' <<<"$BRANCHES")
CHOSEN_BRANCH=$(fzf --reverse --info=inline --preview 'git show --color {}' <<<"$BRANCHES")
CLEAN_BRANCH_NAME=$(sed 's|^\s*||' <<<"$CHOSEN_BRANCH")
for REMOTE in $(git remote); do

@ -1,10 +1,5 @@
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "Usage: git tcommit [-]<hours>"
exit 1
fi
HOUR_SHIFT="$1"
shift

@ -3,10 +3,9 @@ let
cfg = config.programs.gpg;
in
{
# TODO: per-key timers
# TODO: Create proper descriptions
options = {
programs.gpg.key-fetchers.keyserver = {
programs.gpg.fetch-keys = {
enable = lib.mkEnableOption "auto fetching of gpg keys by fingerprint";
keys = lib.mkOption {
description = "";
@ -24,7 +23,8 @@ in
description = "If marked as null, use config";
default = null;
example = "hkps://keys.openpgp.org";
type = with lib.types; coercedTo (nullOr str) (v: if v == null then "@NULL@" else v) str;
type = with lib.types; nullOr str;
apply = v: if v == null then "@NULL@" else v;
};
trust = lib.mkOption {
@ -43,7 +43,7 @@ in
# TODO: Fix the module so that this unit runs whenever something changes
systemd.user.services.gpg-fetch-keys = let
fetchKeysApplication = let
recvKeysByKeyserver = lib.pipe cfg.key-fetchers.keyserver.keys [
recvKeysByKeyserver = lib.pipe cfg.fetch-keys.keys [
lib.attrValues
(lib.foldl (acc: key: acc // {
${key.keyserver} = (acc.${key.keyserver} or []) ++ [ key.id ];
@ -69,7 +69,7 @@ in
}
'';
trustKeys = lib.pipe cfg.key-fetchers.keyserver.keys [
trustKeys = lib.pipe cfg.fetch-keys.keys [
lib.attrValues
(lib.filter (key: key.trust != null))
(map ({ id, trust, ... }: "importTrust '${id}' '${toString trust}'"))
@ -84,7 +84,7 @@ in
trustKeys
];
};
in lib.mkIf cfg.key-fetchers.keyserver.enable {
in lib.mkIf cfg.fetch-keys.enable {
Unit = {
Description = "Fetch declaratively listed gpg keys";
Documentation = [ "man:gpg(1)" ];

@ -1,5 +1,11 @@
{ config, pkgs, ... }:
{ pkgs, config, ... }:
{
imports = [
./auto-refresh-keys.nix
./auto-update-trust-db.nix
./declarative-key-fetcher.nix
];
programs.gpg = {
enable = true;
homedir = "${config.xdg.configHome}/gnupg";
@ -14,7 +20,7 @@
];
};
key-fetchers.keyserver = {
fetch-keys = {
enable = true;
keys = {
"495A898FC1A0276F51EA3155355E5D82B18F4E71" = { trust = 4; };
@ -26,11 +32,10 @@
services.gpg-agent = {
enable = true;
pinentry.package = pkgs.pinentry-curses;
pinentryPackage = pkgs.pinentry-curses;
enableExtraSocket = true;
enableSshSupport = true;
enableScDaemon = true;
enableNushellIntegration = config.programs.nushell.enable;
grabKeyboardAndMouse = false;
};
}

@ -1,4 +0,0 @@
{ ... }:
{
programs.home-manager.enable = true;
}

@ -1,380 +0,0 @@
{ config, pkgs, lib, ... }:
let
cfg = config.wayland.windowManager.hyprland;
in
{
home.sessionVariables = {
WLR_NO_HARDWARE_CURSORS = "1";
WLR_RENDERER_ALLOW_SOFTWARE = "1";
XDG_CURRENT_DESKTOP = "Hyprland";
XDG_SESSION_DESKTOP = "Hyprland";
XDG_SESSION_TYPE = "wayland";
GDK_BACKEND = "wayland,x11,*";
QT_QPA_PLATFORM = "wayland;xcb";
NIXOS_OZONE_WL = "1";
MOZ_ENABLE_WAYLAND = "1";
SDL_VIDEODRIVER = "wayland";
OZONE_PLATFORM = "wayland";
CLUTTER_BACKEND = "wayland";
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
# QT_QPA_PLATFORMTHEME = "qt6ct";
QT_AUTO_SCREEN_SCALE_FACTOR = "1";
# LIBVA_DRIVER_NAME = "nvidia";
# GBM_BACKEND = "nvidia-drm";
# __GLX_VENDOR_LIBRARY_NAME = "nvidia";
};
home.packages = with pkgs; [
hyprpolkitagent
wl-clipboard-rs
];
programs.hyprlock = {
enable = true;
settings = {
general = {
disable_loading_bar = true;
grace = 0;
hide_cursor = true;
no_fade_in = false;
};
background = [
{
path = "screenshot";
blur_passes = 3;
blur_size = 8;
}
];
input-field = [
{
size = "200, 50";
position = "0, -80";
monitor = "";
dots_center = true;
fade_on_empty = false;
font_color = "rgb(202, 211, 245)";
inner_color = "rgb(91, 96, 120)";
outer_color = "rgb(24, 25, 38)";
outline_thickness = 5;
placeholder_text = ''Password...'';
shadow_passes = 2;
}
];
auth = {
"pam:enabled" = true;
"pam:module" = "hyprlock";
};
};
};
services.hypridle = {
enable = true;
settings = {
general = {
ignore_dbus_inhibit = false;
lock_cmd = "pidof hyprlock || ${config.programs.hyprlock.package}/bin/hyprlock";
before_sleep_cmd = "${pkgs.systemd}/bin/loginctl lock-session";
after_sleep_cmd = "${cfg.finalPackage}/bin/hyprctl dispatch dpms on";
};
listener = [
{
timeout = 900;
on-timeout = "${config.programs.hyprlock.package}/bin/hyprlock";
}
{
timeout = 1200;
on-timeout = "${cfg.finalPackage}/bin/hyprctl dispatch dpms off";
on-resume = "${cfg.finalPackage}/bin/hyprctl dispatch dpms on";
}
];
};
};
wayland.windowManager.hyprland = {
enable = true;
systemd.enable = false;
systemd.enableXdgAutostart = false;
settings = let
exe = lib.getExe;
scratchpads = [
(rec {
title = "Floating terminal";
class = "floatingTerminal";
command = "uwsm app -- ${exe pkgs.alacritty} --class ${class} -e ${exe pkgs.tmux} new-session -A -s f";
size = { h = 90; w = 95; };
keys = [
"$mod, RETURN"
"$mod, SPACE"
];
})
(rec {
title = "Ncmpcpp";
class = "floatingNcmpcpp";
command = "uwsm app -- ${exe pkgs.alacritty} --class ${class} -e ${exe pkgs.ncmpcpp}";
size = { h = 95; w = 95; };
keys = [ "$mod, Q" ];
})
# "$mod, W, emacs"
# "$mod, E, filebrowser"
# "$mod, X, taskwarriortui"
];
in {
"$mod" = "SUPER";
# https://github.com/xkbcommon/libxkbcommon/blob/master/include/xkbcommon/xkbcommon-keysyms.h
bind = [
"$mod SHIFT, Q, exec, ${pkgs.systemd}/bin/loginctl terminate-user \"\""
"$mod ALT SHIFT, Q, exec, uwsm stop"
"$mod, R, exec, uwsm app -- ${exe config.programs.anyrun.package}"
"$mod, T, togglefloating"
"$mod, F, fullscreenstate, 1"
"$mod SHIFT, F, fullscreenstate, 3"
"$mod, C, exec, ${cfg.finalPackage}/bin/hyprctl reload"
"$mod, BACKSPACE, killactive"
"$mod SHIFT, RETURN, exec, uwsm app -- ${exe pkgs.alacritty} --class termTerminal -e ${exe pkgs.tmux} new-session -A -s term"
"$mod SHIFT, SPACE, exec, uwsm app -- ${exe pkgs.alacritty} --class termTerminal -e ${exe pkgs.tmux} new-session -A -s term"
"$mod, j, layoutmsg,cyclenext"
"$mod, k, layoutmsg,cycleprev"
"$mod SHIFT, j, layoutmsg, swapnext"
"$mod SHIFT, k, layoutmsg, swapprev"
"$mod, 1, focusworkspaceoncurrentmonitor, 1"
"$mod, 2, focusworkspaceoncurrentmonitor, 2"
"$mod, 3, focusworkspaceoncurrentmonitor, 3"
"$mod, 4, focusworkspaceoncurrentmonitor, 4"
"$mod, 5, focusworkspaceoncurrentmonitor, 5"
"$mod, 6, focusworkspaceoncurrentmonitor, 6"
"$mod, 7, focusworkspaceoncurrentmonitor, 7"
"$mod, 8, focusworkspaceoncurrentmonitor, 8"
"$mod, 9, focusworkspaceoncurrentmonitor, 9"
"$mod SHIFT, 1, movetoworkspacesilent, 1"
"$mod SHIFT, 2, movetoworkspacesilent, 2"
"$mod SHIFT, 3, movetoworkspacesilent, 3"
"$mod SHIFT, 4, movetoworkspacesilent, 4"
"$mod SHIFT, 5, movetoworkspacesilent, 5"
"$mod SHIFT, 6, movetoworkspacesilent, 6"
"$mod SHIFT, 7, movetoworkspacesilent, 7"
"$mod SHIFT, 8, movetoworkspacesilent, 8"
"$mod SHIFT, 9, movetoworkspacesilent, 9"
"$mod, b, exec, ${pkgs.fcitx5}/bin/fcitx5-remote -s mozc"
"$mod, n, exec, ${pkgs.fcitx5}/bin/fcitx5-remote -s keyboard-no"
"$mod, m, exec, ${pkgs.fcitx5}/bin/fcitx5-remote -s keyboard-us"
"$mod, l, exec, ${pkgs.systemd}/bin/loginctl lock-session"
# TODO: fix
# "super + minus" = "${pkgs.xcalib}/bin/xcalib -invert -alter"
", Print, exec, ${exe pkgs.grimblast} copy area"
# "SHIFT, Print, exec, ${lib.getExe pkgs.grimblast} copy area"
# "shift + @Print" = "${pkgs.maim}/bin/maim --hidecursor --nokeyboard $SCREENSHOT_DIR/$(date +%s).png"
"$mod, Print, exec, ${exe pkgs.woomer}"
]
++
(lib.pipe scratchpads [
(map ({ keys, command, class, ... }:
(map (key: let
# TODO: rewrite this to take arguments instead of creating n copies
invokeIfNotRunningAndToggleWorkspace = pkgs.writeShellApplication {
name = "hyprland-toggle-scratchpad-${class}";
runtimeInputs = [ cfg.finalPackage pkgs.jq ];
text = ''
SCRATCHPAD_PROGRAM_EXISTS=$(hyprctl clients -j | jq -r '[.[].class]|any(. == "${class}")')
CURRENT_WORKSPACE_ID=$(hyprctl activeworkspace -j | jq -r '.id')
if [ "$SCRATCHPAD_PROGRAM_EXISTS" != "true" ]; then
${command} &
hyprctl dispatch movetoworkspacesilent "''${CURRENT_WORKSPACE_ID},class:${class}"
hyprctl dispatch focuswindow "class:${class}"
else
SCRATCHPAD_PROGRAM_WORKSPACE_ID=$(hyprctl clients -j | jq '.[] | select( .class == "${class}") | .workspace.id')
if [ "$SCRATCHPAD_PROGRAM_WORKSPACE_ID" != "$CURRENT_WORKSPACE_ID" ]; then
hyprctl dispatch movetoworkspacesilent "''${CURRENT_WORKSPACE_ID},class:${class}"
hyprctl dispatch focuswindow "class:${class}"
else
hyprctl dispatch movetoworkspacesilent "special:${class}Ws,class:${class}"
fi
fi
'';
};
in "${key}, exec, ${lib.getExe invokeIfNotRunningAndToggleWorkspace}"
) keys)
))
lib.flatten
]);
bindm = [
"$mod, mouse:272, movewindow"
"$mod, Control_L, movewindow"
"$mod, mouse:273, resizewindow"
"$mod, ALT_L, resizewindow"
];
bindl = [
"$mod, p, exec, ${exe pkgs.mpc_cli} toggle"
",XF86AudioPlay, exec, ${exe pkgs.mpc_cli} toggle"
",XF86AudioPrev, exec, ${exe pkgs.mpc_cli} prev"
",XF86AudioNext, exec, ${exe pkgs.mpc_cli} next"
];
bindle = [
",XF86MonBrightnessUp, exec, ${exe pkgs.brightnessctl} s +5%"
",XF86MonBrightnessDown, exec, ${exe pkgs.brightnessctl} s 5%-"
",XF86AudioLowerVolume, exec, ${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%-"
",XF86AudioRaiseVolume, exec, ${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%+"
"$mod ,F7, exec, ${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%-"
"$mod ,F8, exec, ${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 2%+"
];
exec-once = [
"uwsm finalize"
];
windowrulev2 = [
"float, class:^(Rofi)$"
"float, class:^(xdg-desktop-portal-gtk)$"
"float, title:^(.*Bitwarden Password Manager.*)$"
"float, title:^(Picture-in-Picture)$"
"tile, class:^(Nsxiv)$"
"float, class: ^(Gimp-2.*)$, title:^(Open Image)$"
"size 70%, class: ^(Gimp-2.*)$, title:^(Open Image)$"
"center, class: ^(Gimp-2.*)$, title:^(Open Image)$"
"dimaround, class:^(xdg-desktop-portal-gtk)$"
"workspace special silent, title:^(Firefox Sharing Indicator)$"
"workspace special silent, title:^(Zen Sharing Indicator)$"
"workspace special silent, title:^(.*is sharing (your screen|a window)\.)$"
"workspace 2, class:^(firefox)$"
"workspace 2, class:^(google-chrome)$"
"workspace 3, class:^(Emacs)$"
"workspace 3, class:^(code)$"
"workspace 3, class:^(code-url-handler)$"
"workspace 3, class:^(dev.zed.Zed)$"
"workspace 5, class:^(discord)$"
"workspace 5, class:^(Element)$"
]
++
(lib.pipe scratchpads [
(map ({ class, size, ... }: [
"workspace special:${class}Ws, class:^${class}$"
"float, class:^${class}$"
"size ${toString size.w}% ${toString size.h}%, class:^${class}$"
"move ${toString ((100 - size.w) / 2)}% ${toString ((100 - size.h) / 2)}%, class:^${class}$"
]))
lib.flatten
]);
monitor = [
# TODO: host specific
"eDP-1, 3840x2400@90.00Hz, 0x0, 2"
# PVV Demiurgen
"desc:Hewlett Packard HP ZR24w CNT01711G6, 1920x1200, 0x-1200, 1"
"desc:Hewlett Packard HP ZR24w CNT018103H, 1920x1200, 1920x-1200, 1"
# PVV Eirin
"desc:Hewlett Packard HP ZR24w CNT01710L4, 1920x1200, 0x-1200, 1"
"desc:Hewlett Packard HP ZR24w CNT0181039, 1920x1200, 1920x-1200, 1"
",preferred,auto,1"
];
general = {
gaps_in = 5;
gaps_out = 15;
border_size = 2;
"col.active_border" = "rgba(33ccffee) rgba(00ff99ee) 45deg";
"col.inactive_border" = "rgba(595959aa)";
resize_on_border = false;
allow_tearing = false;
layout = "master";
};
decoration = {
rounding = 10;
# Change transparency of focused and unfocused windows
active_opacity = 1.0;
inactive_opacity = 1.0;
# drop_shadow = true;
# shadow_range = 4;
# shadow_render_power = 3;
# "col.shadow" = "rgba(1a1a1aee)";
# https://wiki.hyprland.org/Configuring/Variables/#blur
blur = {
enabled = true;
size = 3;
passes = 1;
vibrancy = 0.1696;
};
};
animations.enabled = false;
master = {
new_status = "slave";
};
misc = {
force_default_wallpaper = 0; # Set to 0 or 1 to disable the anime mascot wallpapers
disable_hyprland_logo = false; # If true disables the random hyprland logo / anime girl background. :(
};
input ={
kb_layout = "us";
kb_variant = "";
kb_model = "";
kb_options = "caps:escape";
kb_rules = "";
follow_mouse = 1;
sensitivity = 0; # -1.0 - 1.0, 0 means no modification.
touchpad = {
natural_scroll = false;
};
};
};
};
services.hyprpaper = {
enable = true;
settings.ipc = true;
};
# UWSM
systemd.user.services = {
hypridle.Unit.After = lib.mkForce "graphical-session.target";
waybar.Unit.After = lib.mkForce "graphical-session.target";
network-manager-applet.Unit.After = lib.mkForce "graphical-session.target";
fcitx5-daemon.Unit.After = lib.mkForce "graphical-session.target";
# hyprpaper.Unit.After = lib.mkForce "graphical-session.target";
};
}

@ -1,4 +0,0 @@
{ ... }:
{
programs.jq.enable = true;
}

@ -1,7 +0,0 @@
{ ... }:
{
programs.man = {
enable = true;
generateCaches = true;
};
}

@ -1,16 +0,0 @@
{ config, lib, machineVars, ... }:
{
programs.mpv = {
enable = !machineVars.headless;
config = {
screenshot-directory = "${config.xdg.userDirs.pictures}/mpv-screenshots";
#https://wiki.nixos.org/wiki/Accelerated_Video_Playback
hwdec = "auto-safe";
vo = "gpu";
profile = "gpu-hq";
gpu-context = lib.mkIf machineVars.wayland "wayland";
};
};
}

@ -1,4 +1,4 @@
{ config, pkgs, ... }:
{pkgs, ...}:
{
programs.ncmpcpp = {
enable = true;
@ -332,11 +332,11 @@
window_border_color = "green";
active_window_border = "red";
visualizer_data_source = "/run/user/${toString config.home.uid}/mpd/visualizer.fifo";
visualizer_data_source = "/tmp/mpd.fifo";
visualizer_output_name = "Visualizer feed";
visualizer_in_stereo = "no";
# visualizer_type = "spectrum"; # spectrum, ellipse, wave_filled, wave
# visualizer_look = "+█"; # wave | spectrum, ellipse, wave_filled
visualizer_type = "spectrum"; # spectrum, ellipse, wave_filled, wave
visualizer_look = "+"; # wave | spectrum, ellipse, wave_filled
};
};
}

@ -1,29 +1,9 @@
{ config, pkgs, lib, ... }:
let
daysBeforeDeletion = 2;
cfg = config.programs.neovim.auto-clean-swapfiles;
in
{
options.programs.neovim.auto-clean-swapfiles = {
enable = lib.mkEnableOption "automatic cleanup of neovim swapfiles";
daysBeforeDeletion = lib.mkOption {
type = lib.types.ints.positive;
default = 2;
example = 7;
description = "How long many days old the swapfile should be before it gets cleaned up";
};
onCalendar = lib.mkOption {
type = lib.types.str;
default = "daily";
example = "weekly";
# TODO: link to systemd manpage for format.
description = "How often to run the cleanup.";
};
};
config = lib.mkIf cfg.enable {
config = {
systemd.user.services.clean-neovim-swap-files = {
Unit = {
Description = "Clean old swap files for neovim";
@ -39,7 +19,7 @@ in
text = ''
echo "Cleaning old swap files for neovim"
OLD_SWAPFILES=$(find "${config.xdg.stateHome}/nvim/swap" -type f -name '*.swp' -mtime +${toString cfg.daysBeforeDeletion})
OLD_SWAPFILES=$(find "${config.xdg.stateHome}/nvim/swap" -type f -name '*.swp' -mtime +${toString daysBeforeDeletion})
if [ -z "$OLD_SWAPFILES" ]; then
echo "No old swap files found"
@ -64,7 +44,7 @@ in
Timer = {
Unit = "clean-neovim-swap-files.service";
OnCalendar = cfg.onCalendar;
OnCalendar = "daily";
Persistent = true;
};

@ -1,28 +1,26 @@
{ pkgs, lib, machineVars, ... }:
{ pkgs, home, ... }:
{
imports = [
./auto-clean-swapfiles.nix
];
programs.neovim = {
enable = true;
auto-clean-swapfiles.enable = true;
viAlias = true;
vimAlias = true;
vimdiffAlias = true;
plugins = with pkgs.vimPlugins; [
direnv-vim
fzf-vim
vim-commentary
vim-css-color
vim-fugitive
vim-gitgutter
fzf-vim
vim-which-key
vim-nix
vim-surround
vim-trailing-whitespace
vim-which-key
] ++ (lib.optionals machineVars.wayland [
vim-wayland-clipboard
]) ++ [
vim-fugitive
vim-css-color
semshi
{
plugin = goyo-vim;
@ -68,58 +66,25 @@
}
limelight-vim
vim-tmux-navigator
vim-polyglot
lightline-vim
vim-better-whitespace
{
plugin = nvim-treesitter.withAllGrammars;
plugin = rainbow;
config = ''
packadd! nvim-treesitter
lua << EOF
require'nvim-treesitter.configs'.setup {
highlight = {
enable = true,
},
}
EOF
'';
}
{
plugin = rainbow-delimiters-nvim;
config = ''
lua << EOF
local rainbow_delimiters = require 'rainbow-delimiters'
vim.g.rainbow_delimiters = {
["highlight"] = {
'RainbowDelimiterRed',
'RainbowDelimiterYellow',
'RainbowDelimiterBlue',
'RainbowDelimiterGreen',
'RainbowDelimiterViolet',
'RainbowDelimiterCyan',
},
}
EOF
let g:rainbow_active = 1
'';
}
{
plugin = vim-monokai;
config = ''
colorscheme monokai
autocmd ColorScheme monokai highlight Normal ctermbg=0
autocmd ColorScheme monokai highlight LineNr ctermbg=0
autocmd ColorScheme monokai highlight CursorLineNR ctermbg=0 ctermfg=208
autocmd ColorScheme monokai highlight SignColumn ctermbg=0
autocmd ColorScheme monokai highlight GitGutterAdd ctermbg=0
autocmd ColorScheme monokai highlight GitGutterChange ctermbg=0
autocmd ColorScheme monokai highlight GitGutterDelete ctermbg=0
autocmd ColorScheme monokai highlight RainbowDelimiterRed { fg = g:terminal_color_9 }
autocmd ColorScheme monokai highlight RainbowDelimiterYellow { fg = g:terminal_color_11 }
autocmd ColorScheme monokai highlight RainbowDelimiterBlue { fg = g:terminal_color_12 }
autocmd ColorScheme monokai highlight RainbowDelimiterGreen { fg = g:terminal_color_10 }
autocmd ColorScheme monokai highlight RainbowDelimiterViolet { fg = g:terminal_color_13 }
autocmd ColorScheme monokai highlight RainbowDelimiterCyan { fg = g:terminal_color_14 }
autocmd ColorScheme * highlight Normal ctermbg=0
autocmd ColorScheme * highlight LineNr ctermbg=0
autocmd ColorScheme * highlight CursorLineNR ctermbg=0 ctermfg=208
autocmd ColorScheme * highlight SignColumn ctermbg=0
autocmd ColorScheme * highlight GitGutterAdd ctermbg=0
autocmd ColorScheme * highlight GitGutterChange ctermbg=0
autocmd ColorScheme * highlight GitGutterDelete ctermbg=0
'';
}
];

@ -12,10 +12,6 @@ in {
programs.newsboat = {
enable = true;
fetch-articles.enable = true;
vacuum.enable = true;
autoReload = true;
maxItems = 50;
browser = ''"${defaultBrowser}"'';
@ -75,10 +71,76 @@ in {
];
};
# systemd.user.slices.app-newsboat = {
# Unit = {
# Description = "Newsboat automation";
# Documentation = [ "man:newsboat(1)" ];
# };
# };
systemd.user.slices.app-newsboat = {
Unit = {
Description = "Newsboat automation";
Documentation = [ "man:newsboat(1)" ];
};
};
# TODO: wait for internet
systemd.user.services.newsboat-fetch-articles = {
Unit = {
Description = "Automatically fetch new articles for newsboat";
Documentation = [ "man:newsboat(1)" ];
};
Service = {
Type = "oneshot";
Slice = "app-newsboat.slice";
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
ExecStart = "${lib.getExe pkgs.flock} %t/newsboat.lock ${lib.getExe package} --execute=reload";
};
};
systemd.user.timers.newsboat-fetch-articles = {
Unit = {
Description = "Automatically fetch new articles for newsboat";
Documentation = [ "man:newsboat(1)" ];
After = [ "network.target" ];
};
Timer = {
Unit = "newsboat-fetch-articles.service";
OnCalendar = lib.mkDefault "daily";
Persistent = true;
};
Install = {
WantedBy = [ "timers.target" ];
};
};
systemd.user.services.newsboat-vacuum = {
Unit = {
Description = "Automatically clean newsboat cache";
Documentation = [ "man:newsboat(1)" ];
};
Service = {
Type = "oneshot";
Slice = "app-newsboat.slice";
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
ExecStart = "${lib.getExe pkgs.flock} %t/newsboat.lock ${lib.getExe package} --vacuum";
};
};
systemd.user.timers.newsboat-vacuum = {
Unit = {
Description = "Automatically clean newsboat cache";
Documentation = [ "man:newsboat(1)" ];
};
Timer = {
Unit = "newsboat-vacuum.service";
OnCalendar = lib.mkDefault "weekly";
Persistent = true;
};
Install = {
WantedBy = [ "timers.target" ];
};
};
}

@ -3,46 +3,40 @@ let
mkSource = tags: url: { inherit tags url; };
in {
programs.newsboat.urls = [
(mkSource [ "tech" "linux" ] "https://archlinux.org/feeds/news/")
(mkSource [ "tech" "linux" "nixos" ] "https://nixos.org/blog/announcements-rss.xml")
(mkSource [ "tech" "ntnu" ] "https://omegav.no/newsrss")
(mkSource [ "ntnu" ] "https://varsel.it.ntnu.no/subscribe/rss/")
(mkSource [ "tech" ] "https://blog.hackeriet.no/feed.xml")
(mkSource [ "tech" ] "https://fribyte.no/rss.xml")
(mkSource [ "tech" ] "https://existentialtype.wordpress.com/feed/")
(mkSource [ "tech" "linux" "ntnu" ] "https://wiki.pvv.ntnu.no/w/api.php?hidebots=1&urlversion=1&days=90&limit=50&action=feedrecentchanges&format=xml")
(mkSource [ "tech" "linux" "nixos" ] "https://dandellion.xyz/atom.xml")
(mkSource [ "tech" "linux" ] "https://lukesmith.xyz/rss.xml")
(mkSource [ "tech" "vim" "old" ] "https://castel.dev/rss.xml")
(mkSource [ "tech" "linux" "nixos" ] "https://christine.website/blog.rss")
(mkSource [ "japanese" "language" "old" ] "http://feeds.feedburner.com/LocalizingJapan")
(mkSource [ "tech" "linux" ] "http://xahlee.info/comp/blog.xml")
(mkSource [ "tech" ] "https://branchfree.org/feed/")
(mkSource [ "tech" ] "https://search.marginalia.nu/news.xml")
(mkSource [ "japanese" "language" ] "https://www.outlier-linguistics.com/blogs/japanese.atom")
(mkSource [ "tech" "linux" ] "https://archlinux.org/feeds/news/")
(mkSource [ "tech" "linux" ] "https://bartoszmilewski.com/feed/")
(mkSource [ "tech" "linux" "nixos" ] "https://myme.no/atom-feed.xml")
(mkSource [ "tech" "linux" "nixos" ] "https://nixos.org//blog/announcements-rss.xml")
(mkSource [ "tech" "linux" ] "https://www.digitalneanderthal.com/index.xml")
(mkSource [ "tech" "ntnu" ] "https://omegav.no/newsrss")
(mkSource [ "tech" ] "https://code.visualstudio.com/feed.xml")
(mkSource [ "tech" "linux" "nixos" ] "https://blog.ysndr.de/atom.xml")
(mkSource [ "tech" "linux" "nixos" ] "https://kaushikc.org/atom.xml")
(mkSource [ "tech" "linux" "nixos" ] "https://ianthehenry.com/feed.xml")
(mkSource [ "tech" "linux" "ntnu" ] "https://www.pvv.ntnu.no/w/api.php?hidebots=1&urlversion=1&days=7&limit=50&action=feedrecentchanges&feedformat=atom")
(mkSource [ "ntnu" ] "https://varsel.it.ntnu.no/subscribe/rss/")
(mkSource [ "tech" "linux" "japanese" ] "https://www.ncaq.net/feed.atom")
(mkSource [ "tech" "linux" "nixos" "emacs" "japanese" ] "https://apribase.net/program/feed")
(mkSource [ "tech" "linux" "nixos" "functional-programming" ] "https://www.haskellforall.com/feeds/posts/default")
(mkSource [ "tech" "linux" "nixos" ] "https://christine.website/blog.rss")
(mkSource [ "tech" "functional-programming" "nixos" ] "https://markkarpov.com/feed.atom")
(mkSource [ "tech" "functional-programming" ] "https://williamyaoh.com/feed.atom")
(mkSource [ "tech" "functional-programming" ] "https://www.parsonsmatt.org/feed.xml")
(mkSource [ "tech" "functional-programming" "python" ] "http://blog.ezyang.com/feed/")
(mkSource [ "tech" "functional-programming" ] "https://lexi-lambda.github.io/feeds/all.rss.xml")
(mkSource [ "tech" "functional-programming" ] "https://www.stephendiehl.com/feed.rss")
(mkSource [ "tech" "functional-programming" "emacs" ] "https://chrisdone.com/rss.xml")
(mkSource [ "tech" ] "https://go.dev/blog/feed.atom")
(mkSource [ "tech" "linux" ] "https://jfx.ac/blog/index.xml")
(mkSource [ "tech" "linux" ] "https://lukesmith.xyz/rss.xml")
(mkSource [ "japanese" "language" ] "https://www.outlier-linguistics.com/blogs/japanese.atom")
(mkSource [ "tech" "linux" "haskell" "nixos" "functional-programming" ] "https://www.haskellforall.com/feeds/posts/default")
(mkSource [ "tech" "haskell" "functional-programming" ] "https://williamyaoh.com/feed.atom")
(mkSource [ "tech" "haskell" "functional-programming" ] "https://www.parsonsmatt.org/feed.xml")
(mkSource [ "tech" "haskell" "functional-programming" "python" ] "http://blog.ezyang.com/feed/")
(mkSource [ "tech" "haskell" "functional-programming" ] "https://lexi-lambda.github.io/feeds/all.rss.xml")
(mkSource [ "tech" "haskell" "functional-programming" ] "https://www.stephendiehl.com/feed.rss")
(mkSource [ "tech" "haskell" "functional-programming" "emacs" ] "https://chrisdone.com/rss.xml")
(mkSource [ "tech" "haskell" "functional-programming" "nixos" ] "https://markkarpov.com/feed.atom")
(mkSource [ "tech" "flutter" ] "https://resocoder.com/feed/")
(mkSource [ "tech" "compilers" ] "https://existentialtype.wordpress.com/feed/")
(mkSource [ "tech" "compilers" "haskell" "functional-programming" "old" ] "https://skilpat.tumblr.com/rss")
(mkSource [ "language" ] "https://feeds.feedburner.com/blogspot/Ckyi")
(mkSource [ "japanese" "language" "old" ] "http://feeds.feedburner.com/LocalizingJapan")
(mkSource [ "japanese" "language" ] "https://wesleycrobertson.wordpress.com/feed/")
(mkSource [ "tech" "vim" "old" ] "https://castel.dev/rss.xml")
(mkSource [ "tech" "functional-programming" "old" ] "https://skilpat.tumblr.com/rss")
(mkSource [ "tech" ] "https://resocoder.com/feed/")
# Broken?
(mkSource [ "tech" "linux" "nixos" ] "https://flyx.org/feed.xml")
(mkSource [ "tech" "compilers" ] "https://go.dev/blog/feed.atom")
(mkSource [ "tech" "linux" "nixos" ] "https://myme.no/feed.xml")
(mkSource [ "tech" "linux" "nixos" "compilers" ] "https://flyx.org/feed.xml")
(mkSource [ "tech" "linux" ] "https://blog.jfx.ac/feed.xml")
(mkSource [ "tech" "linux" "nixos" ] "https://dandellion.xyz/atom.xml")
];
}

@ -1,7 +1,9 @@
{ ... }:
{
imports = [ ./fetch-nix-index-database.nix ];
programs.nix-index = {
enable = true;
autoUpdateDatabase.enable = true;
enableDatabaseFetcher = true;
};
}
}

@ -1,25 +1,12 @@
{ config, pkgs, lib, ... }:
let
cfg = config.programs.nix-index.autoUpdateDatabase;
cfg = config.programs.nix-index;
in
{
options.programs.nix-index.autoUpdateDatabase = {
enable = lib.mkEnableOption "timed unit that fetches an updated database of nixpkgs outputs";
# TODO: let users specify forks and other sources
# url = "";
onCalendar = lib.mkOption {
type = lib.types.str;
default = "weekly";
example = "montly";
# TODO: link to systemd manpage for format.
description = "How often to update the database.";
};
};
options.programs.nix-index.enableDatabaseFetcher = lib.mkEnableOption "timed unit that fetches an updated database of nixpkgs outputs";
config = {
systemd.user.timers.fetch-nix-index-database = lib.mkIf cfg.enable {
systemd.user.timers.fetch-nix-index-database = lib.mkIf cfg.enableDatabaseFetcher {
Unit = {
Description = "Fetch nix-index database";
Documentation = [ "https://github.com/nix-community/nix-index-database" ];
@ -27,7 +14,7 @@ in
Timer = {
Unit = "fetch-nix-index-database.service";
OnCalendar = cfg.onCalendar;
OnCalendar = "weekly";
Persistent = true;
};
@ -36,7 +23,7 @@ in
};
};
systemd.user.services.fetch-nix-index-database = lib.mkIf cfg.enable {
systemd.user.services.fetch-nix-index-database = lib.mkIf cfg.enableDatabaseFetcher {
Unit = {
Description = "Fetch nix-index database";
Documentation = [ "https://github.com/nix-community/nix-index-database" ];
@ -52,8 +39,6 @@ in
wget
];
# TODO: allow fetching with gh + github token
# Source: https://github.com/nix-community/nix-index-database?tab=readme-ov-file#ad-hoc-download
# Slightly modified to satisfy shellcheck
text = ''

@ -1,38 +0,0 @@
{ config, lib, ... }:
{
sops = {
secrets = {
"nix/access-tokens/github" = { sopsFile = ./../../secrets/common.yaml; };
"nix/access-tokens/pvv-git" = { sopsFile = ./../../secrets/common.yaml; };
"nix/access-tokens/github-nordicsemi" = { sopsFile = ./../../secrets/common.yaml; };
"nix/access-tokens/bitbucket-nordicsemi" = { sopsFile = ./../../secrets/common.yaml; };
};
templates."nix-access-tokens.conf".content = let
inherit (config.sops) placeholder;
tokens = {
"github.com" = placeholder."nix/access-tokens/github";
"git.pvv.ntnu.no" = placeholder."nix/access-tokens/pvv-git";
"bitbucket.nordicsemi.no" = placeholder."nix/access-tokens/bitbucket-nordicsemi";
"github.com/NordicPlayground" = placeholder."nix/access-tokens/github-nordicsemi";
"github.com/NordicSemiconductor" = placeholder."nix/access-tokens/github-nordicsemi";
};
in "access-tokens = ${lib.pipe tokens [
lib.attrsToList
(builtins.sort (p: q: p.name > q.name))
(map ({ name, value }: "${name}=${value}"))
(builtins.concatStringsSep " ")
]}";
};
nix = {
settings.use-xdg-base-directories = true;
extraOptions = ''
!include ${config.sops.templates."nix-access-tokens.conf".path}
'';
};
}

@ -1,6 +0,0 @@
{ ... }:
{
programs.nushell = {
enable = true;
};
}

@ -1,4 +0,0 @@
{ machineVars, ... }:
{
programs.obs-studio.enable = !machineVars.headless;
}

@ -1,4 +0,0 @@
{ ... }:
{
programs.pandoc.enable = true;
}

@ -1,12 +0,0 @@
{ pkgs, ... }:
{
programs.prism-launcher = {
enable = true;
package = pkgs.prismlauncher.override {
jdk17 = pkgs.jdk21;
};
screenshotMover.enable = true;
};
}

@ -1,24 +0,0 @@
{ config, pkgs, extendedLib, ... }:
{
# Python for interactive use
home.packages = [
(pkgs.python3.withPackages (pypkgs: with pypkgs; [
requests
]))
];
xdg.configFile."python/pyrc".text = ''
#!/usr/bin/env python3
import sys
# You also need \x01 and \x02 to separate escape sequence, due to:
# https://stackoverflow.com/a/9468954/1147688
sys.ps1='\x01\x1b${extendedLib.termColors.front.blue "[Python]> "}\x02>>>\x01\x1b[0m\x02 ' # bright yellow
sys.ps2='\x01\x1b[1;49;31m\x02...\x01\x1b[0m\x02 ' # bright red
'';
home.sessionVariables = {
PYTHONSTARTUP = "${config.xdg.configHome}/python/pyrc";
PYTHON_HISTORY = "${config.xdg.dataHome}/python_history";
};
}

@ -1,4 +0,0 @@
{ ... }:
{
programs.ripgrep.enable = true;
}

@ -1,4 +1,4 @@
{ pkgs, ... }:
{pkgs, inputs, ...}:
{
programs.rofi = {
enable = true;
@ -14,7 +14,7 @@
# ];
font = "Droid Sans 12";
theme = ./blank.rasi;
theme = "${inputs.dotfiles}/general/.config/rofi/themes/blank.rasi";
extraConfig = {
modi = "window,run,drun,ssh,windowcd";

@ -1,145 +0,0 @@
// Based on the glorious dotfiles:
// https://github.com/manilarome/the-glorious-dotfiles/blob/master/config/awesome/surreal/configuration/rofi/global/rofi.rasi
* {
transparent: #00000000;
foreground: #F2F2F2EE;
background-selected: #F2F2F245;
background-active: #F2F2F230;
background-white: #F2F2F211;
background-black: #00000066;
urgent: #E91E6366;
urgent-selected: #E91E6377;
}
window {
transparency: "real";
background-color: @transparent;
location: center;
anchor: center;
x-offset: 0px;
height: 500px;
width: 750px;
orientation: vertical;
border-radius: 12px;
}
prompt {
enabled: false;
}
button {
action: "ok";
str: " ";
font: "Droid Sans 12";
expand: false;
text-color: @foreground;
background-color: @transparent;
vertical-align: 0.7;
horizontal-align: 0.5;
}
entry {
font: "Droid Sans 12";
background-color: @transparent;
text-color: @foreground;
expand: true;
vertical-align: 0.5;
horizontal-align: 0.5;
placeholder: "Type to search";
placeholder-color: @foreground;
blink: true;
}
case-indicator {
background-color: @transparent;
text-color: @foreground;
vertical-align: 0.5;
horizontal-align: 0.5;
}
entry-wrapper {
orientation: horizontal;
vertical-align: 0.5;
spacing: 4px;
background-color: @transparent;
children: [ button, entry, case-indicator ];
}
inputbar {
background-color: @background-white;
text-color: @foreground;
expand: false;
border-radius: 24px;
margin: 0px 225px 0px 225px;
padding: 10px 10px 10px 10px;
position: north;
children: [ entry-wrapper ];
}
listview {
background-color: @transparent;
columns: 2;
spacing: 5px;
cycle: false;
dynamic: true;
layout: vertical;
}
mainbox {
background-color: @background-black;
children: [ inputbar, listview ];
spacing: 25px;
padding: 40px 25px 25px 25px;
}
element {
background-color: @transparent;
text-color: @foreground;
orientation: horizontal;
border-radius: 6px;
padding: 5px 10px 5px 10px;
}
element-icon {
background-color: @transparent;
size: 46px;
border: 0;
}
element-text {
background-color: @transparent;
text-color: @foreground;
expand: true;
horizontal-align: 0;
vertical-align: 0.5;
margin: 0 10px 0 10px;
}
element normal.urgent,
element alternate.urgent {
background-color: @urgent;
text-color: @foreground;
border-radius: 9px;
}
element normal.active,
element alternate.active {
background-color: @background-active;
text-color: @foreground;
}
element selected {
background-color: @background-selected;
text-color: @foreground;
}
element selected.urgent {
background-color: @urgent-selected;
text-color: @foreground;
}
element selected.active {
background-color: @background-active;
color: @foreground-selected;
}

@ -1,7 +0,0 @@
{ ... }:
{
programs.skim = {
enable = true;
defaultCommand = "fd --type f";
};
}

@ -1,17 +0,0 @@
{ config, pkgs, ... }:
{
xdg.configFile."sqlite3/sqliterc".text = ''
.bail on
.changes on
.headers on
.mode box
.nullvalue '<NULL>'
.timer on
'';
home.packages = [
pkgs.sqlite-interactive
];
home.sessionVariables.SQLITE_HISTORY= "${config.xdg.dataHome}/sqlite_history";
}

@ -1,8 +1,4 @@
{ config, pkgs, ... }:
let
runtimeDir = "/run/user/${toString config.home.uid}";
controlMastersDir = "${runtimeDir}/ssh";
in
{ config, ... }:
{
imports = [
./home.nix
@ -14,26 +10,5 @@ in
mode = "0444";
};
programs.ssh = {
enable = true;
includes = [
config.sops.secrets."ssh/secret-config".path
"${config.home.homeDirectory}/.ssh/mutable_config"
];
controlMaster = "auto";
controlPersist = "10m";
controlPath = "${controlMastersDir}/%n%C";
};
systemd.user.tmpfiles.settings."10-ssh" = {
${controlMastersDir}.d = {
user = config.home.username;
mode = "0700";
};
"${config.home.homeDirectory}/.ssh/mutable_config".f = {
user = config.home.username;
mode = "0600";
};
};
programs.ssh.includes = [ config.sops.secrets."ssh/secret-config".path ];
}

@ -9,7 +9,7 @@
"github" = {
user = "git";
hostname = "github.com";
identityFile = [ "~/.ssh/id_rsa" ];
identityFile = [ "~/.ssh/id_ed25519" ];
};
"github-nordicsemi" = {
user = "git";
@ -31,15 +31,5 @@
hostname = "wiki.wackattack.eu";
port = 1337;
};
"garp" = {
user = "h7x4";
hostname = "garp.pbsds.net";
proxyJump = "pvv";
};
"bolle" = {
user = "h7x4";
hostname = "bolle.pbsds.net";
proxyJump = "pvv";
};
};
}

@ -1,89 +1,94 @@
{ pkgs, lib, ... }:
let # http://www.pvv.ntnu.no/pvv/Maskiner
{ pkgs, lib, extendedLib, ... }:
let
adminUser = "root";
normalUser = "oysteikt";
# http://www.pvv.ntnu.no/pvv/Maskiner
normalMachines = [
{
names = [ "hildring" "pvv-login" ];
names = [ "hildring" "pvv-login" "pvv" ];
proxyJump = lib.mkDefault null;
addressFamily = "inet";
}
{
names = [ "drolsum" "pvv-login2" "pvv" ];
proxyJump = lib.mkDefault null;
addressFamily = "inet";
}
[ "bekkalokk" "pvv-web" "pvv-wiki" "pvv-webmail" ]
[ "bicep" "pvv-databases" ]
"bob"
[ "brzeczyszczykiewicz" "brez" "bokhylle" ]
"buskerud"
"dagali"
"drolsum"
"demiurgen"
"eirin"
"georg"
[ "bekkalokk" "pvv-web" "pvv-wiki" "pvv-webmail" ]
"ildkule"
"isvegg"
"knutsen"
"kommode"
{
names = [ "microbel" "pvv-users" "pvv-mail" ];
proxyJump = lib.mkDefault null;
addressFamily = "inet";
}
"orchid"
"shark"
"tallulah"
"buskerud"
[ "bicep" "pvv-databases" ]
"bob"
"knutsen"
"isvegg"
"tom"
"ustetind"
"venture"
[ "microbel" "pvv-users" "pvv-mail" ]
];
rootMachines = [
[ "ameno" "pvv-dns" ]
[ "sleipner" "pvv-salt" ]
[ "balduzius" "pvv-krb" ]
[ "innovation" "pvv-minecraft" ]
"ludvigsen"
[ "principal" "pvv-backup" ]
[ "skrott" "dibbler" ]
{
names = [ "sleipner" "pvv-salt" ];
user = "oysteikt/admin";
}
];
overrideIfNotExists = b: a: a // (builtins.removeAttrs b (builtins.attrNames a));
# Either( String [String] AttrSet{String} ) -> AttrSet{String}
coerceToSSHMatchBlock =
machine:
if builtins.isString machine then { names = [machine]; }
else if builtins.isList machine then { names = machine; }
else machine;
coerce = user: machines: lib.pipe machines [
(m: if builtins.isString m then { names = [m]; } else m)
(m: if builtins.isList m then { names = m; } else m)
(overrideIfNotExists { inherit user; })
];
# ListOf(String) -> AttrSet
machineWithNames = let
inherit (lib.lists) head;
inherit (lib.strings) split;
in
names: { hostname = "${head names}.pvv.ntnu.no"; };
normalUser = "oysteikt";
# AttrSet -> AttrSet -> AttrSet
convertMachineWithDefaults = defaults: normalizedMachine: let
inherit (lib.attrsets) nameValuePair;
inherit (lib.strings) concatStringsSep;
inherit (normalizedMachine) names;
matchConfig = let
machines = (map (coerce normalUser) normalMachines) ++ (map (coerce "root") rootMachines);
setVars = orig@{ names, ... }: {
name = builtins.concatStringsSep " " names;
value = overrideIfNotExists {
hostname = "${builtins.head names}.pvv.ntnu.no";
proxyJump = "microbel";
addressFamily = "inet";
} (builtins.removeAttrs orig ["names"]);
};
in builtins.listToAttrs (map setVars machines);
name = concatStringsSep " " names;
value =
(machineWithNames names)
// defaults
// removeAttrs normalizedMachine ["names"];
in
nameValuePair name value;
# AttrSet -> AttrSet
convertNormalMachine = convertMachineWithDefaults { user = normalUser; proxyJump = "pvv"; };
# AttrSet -> AttrSet
convertAdminMachine =
convertMachineWithDefaults { user = adminUser; proxyJump = "pvv"; };
# ListOf (Either(String ListOf(String) AttrsOf(String))) -> (AttrSet -> AttrSet) -> AttrSet
convertMachinesWith = convertMachineFunction: let
inherit (lib.attrsets) listToAttrs;
inherit (lib.trivial) pipe;
pipeline = [
(map coerceToSSHMatchBlock)
(map convertMachineFunction)
listToAttrs
];
in
machines: pipe machines pipeline;
in
{
programs.ssh.matchBlocks = lib.mergeAttrsList [
matchConfig
{
"pvv-git git.pvv.ntnu.no" = {
hostname = "git.pvv.ntnu.no";
user = "gitea";
addressFamily = "inet";
port = 2222;
proxyJump = "microbel";
};
}
];
programs.ssh.matchBlocks = (extendedLib.attrsets.concatAttrs [
(convertMachinesWith convertNormalMachine normalMachines)
(convertMachinesWith convertAdminMachine rootMachines)
]) // {
"pvv-git git.pvv.ntnu.no" = {
hostname = "git.pvv.ntnu.no";
user = "gitea";
addressFamily = "inet";
port = 2222;
proxyJump = "pvv";
};
};
}

@ -1,7 +0,0 @@
{ ... }:
{
programs.texlive = {
enable = true;
# packageSet = pkgs.texlive.combined.scheme-medium;
};
}

@ -1,18 +0,0 @@
{ config, pkgs, lib, machineVars, ... }:
let
cfg = config.programs.thunderbird;
in
{
programs.thunderbird = {
enable = !machineVars.headless;
profiles.h7x4 = {
isDefault = true;
withExternalGnupg = true;
};
};
home.packages = lib.mkIf cfg.enable (with pkgs; [
birdtray
]);
}

@ -1,4 +1,4 @@
{ pkgs, lib, ... }:
{pkgs, ...}:
{
programs.tmux = {
enable = true;
@ -7,9 +7,6 @@
escapeTime = 0;
keyMode = "vi";
prefix = "C-a";
mouse = true;
terminal = "screen-256color";
plugins = with pkgs.tmuxPlugins; [
copycat
fingers
@ -22,31 +19,15 @@
tmux-fzf
urlview
];
extraConfig = let
fileContentsWithoutShebang = script: lib.pipe script [
lib.fileContents
(lib.splitString "\n")
(lib.drop 3) # remove shebang
(lib.concatStringsSep "\n")
];
fcitx5-status = (pkgs.writeShellApplication {
name = "tmux-fcitx5-status";
runtimeInputs = with pkgs; [ dbus ];
text = fileContentsWithoutShebang ./scripts/fcitx5-status.sh;
});
mpd-status = (pkgs.writeShellApplication {
name = "tmux-mpd-status";
runtimeInputs = with pkgs; [ mpc-cli gawk gnugrep ];
text = fileContentsWithoutShebang ./scripts/mpd-status.sh;
});
in ''
extraConfig = ''
# Don't rename windows automatically after rename with ','
set-option -g allow-rename off
set -g mouse on
set -q -g status-utf8 on
setw -q -g utf8 on
set-option -g default-terminal screen-256color
set -g base-index 1 # windows starts at 1
setw -g monitor-activity on
set -g visual-activity on
@ -54,6 +35,9 @@
set -g status-left-length 30
set -g status-right-length 150
set -g base-index 1
set -g pane-base-index 0
######################
######## KEYS ########
######################
@ -107,8 +91,8 @@
### DESIGN CHANGES ###
######################
set-option -g status-left '#{prefix_highlight} #[bg=blue]#[fg=black,bold] ###S #[bg=default] #[fg=green]#(${lib.getExe fcitx5-status}) #[fg=red]%H:%M '
set-option -g status-right '#[fg=red]#(${lib.getExe mpd-status})'
set-option -g status-left '#{prefix_highlight} #[bg=blue]#[fg=black,bold] ###S #[bg=default] #[fg=green]#(~/.scripts/tmux/fcitx) #[fg=red]%H:%M '
set-option -g status-right '#[fg=red]#(~/.scripts/tmux/mpd)'
set-window-option -g window-status-current-style fg=magenta
set-option -g status-style 'bg=black fg=default'
set-option -g default-shell '${pkgs.zsh}/bin/zsh'

@ -1,26 +0,0 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p dbus
printState() {
STATUS=$(dbus-send --session --print-reply=literal --dest='org.fcitx.Fcitx5' '/controller' 'org.fcitx.Fcitx.Controller1.CurrentInputMethod' | tr -d '[:space:]')
case $STATUS in
keyboard-us)
echo 'US'
;;
keyboard-no)
echo 'NO'
;;
mozc)
echo '日本語'
;;
*)
echo "$STATUS?"
;;
esac
}
while :; do
printState
sleep 1
done

@ -1,29 +0,0 @@
#!/usr/bin/env nix-shell
#!nix-shell -i sh -p mpc-cli gawk gnugrep
while true; do
MPC_OUTPUT=$(mpc --format '[[%artist% - ]%title%]|[%file%]')
TITLE=$(head -n 1 <<<"$MPC_OUTPUT")
if [ ${#TITLE} -gt 60 ]; then
TITLE=$(awk '{print substr($0,0,57) "..."}' <<<"$TITLE")
fi
LINE2=$(head -n 2 <<<"$MPC_OUTPUT" | tail -n 1)
PLAY_STATUS_RAW=$(awk '{print $1}' <<<"$LINE2")
if [ "$PLAY_STATUS_RAW" == "[playing]" ]; then
PLAY_STATUS="▶"
elif [ "$PLAY_STATUS_RAW" == "[paused]" ]; then
PLAY_STATUS="⏸"
else
PLAY_STATUS="??"
fi
TIME=$(awk '{print $3}' <<<"$LINE2")
echo -e "$PLAY_STATUS $TITLE | [$TIME]"
sleep 1
done

@ -1,14 +0,0 @@
{ pkgs, ... }:
{
home.packages = [
pkgs.uv
];
# https://docs.astral.sh/uv/configuration/files/
# https://docs.astral.sh/uv/reference/settings/
xdg.configFile."uv/uv.toml".source = (pkgs.formats.toml { }).generate "uv-config" {
python-downloads = "never";
python-preference = "only-system";
pip.index-url = "https://test.pypi.org/simple";
};
}

@ -24,347 +24,360 @@ in
onChange = ''install -m660 $(realpath "${configFilePath}.ro") "${configFilePath}"'';
};
programs.vscode = {
programs.vscode ={
enable = true;
package = pkgs.vscode.overrideAttrs (prev: {
# NOTE: this messes up zsh's tab completion in the terminal whenever code is started
# from within a shell
preFixup = prev.preFixup + ''
gappsWrapperArgs+=(
--unset TMUX_PANE
)
'';
});
package = pkgs.vscode;
profiles.default = {
userSettings = let
editor = mapPrefixToSet "editor" {
fontFamily = "Fira Code";
fontLigatures = true;
lineNumbers = "relative";
mouseWheelZoom = false;
fontSize = 14;
"minimap.enabled" = false;
tabSize = 2;
insertSpaces = true;
"inlineSuggest.enabled" = true;
"inlayHints.enabled" = "offUnlessPressed";
detectIndentation = false;
tabCompletion = "onlySnippets";
snippetSuggestions = "top";
cursorBlinking = "smooth";
cursorSmoothCaretAnimation = "on";
multiCursorModifier = "ctrlCmd";
suggestSelection = "first";
cursorStyle = "line";
wordSeparators = "/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-";
wordWrap = "off";
# "bracketPairColorization.enabled" = true;
};
userSettings = let
editor = mapPrefixToSet "editor" {
fontFamily = "Fira Code";
fontLigatures = true;
lineNumbers = "relative";
mouseWheelZoom = false;
fontSize = 14;
"minimap.enabled" = false;
tabSize = 2;
insertSpaces = true;
"inlineSuggest.enabled" = true;
"inlayHints.enabled" = "offUnlessPressed";
detectIndentation = false;
tabCompletion = "onlySnippets";
snippetSuggestions = "top";
cursorBlinking = "smooth";
cursorSmoothCaretAnimation = "on";
multiCursorModifier = "ctrlCmd";
suggestSelection = "first";
cursorStyle = "line";
wordSeparators = "/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-";
wordWrap = "off";
# "bracketPairColorization.enabled" = true;
};
zen = mapPrefixToSet "zenMode" {
centerLayout = true;
hideStatusBar = false;
hideLineNumbers = false;
};
zen = mapPrefixToSet "zenMode" {
centerLayout = true;
hideStatusBar = false;
hideLineNumbers = false;
};
vim = mapPrefixToSet "vim" {
useSystemClipboard = true;
"statusBarColorControl" = true;
"statusBarColors.insert" = "#20ff00";
"statusBarColors.normal" = "#1D1E20";
"statusBarColors.visual" = "#00ffff";
"statusBarColors.replace" = "#ff002b";
handleKeys = {
"<C-d>" = true;
"<C-j>" = false;
"<C-b>" = false;
"<C-k>" = false;
"<C-w>" = false;
"<C-n>" = false;
"<A-o>" = true;
};
};
workbench = mapPrefixToSet "workbench" {
"settings.enableNaturalLanguageSearch" = false;
enableExperiments = false;
iconTheme = "material-icon-theme";
colorTheme = "Monokai ST3";
colorCustomizations = {
"statusBar.background" = "#1D1E20";
"statusBar.noFolderBackground" = "#1D1E20";
"statusBar.debuggingBackground" = "#1D1E20";
"[Monokai ST3]" = {
"editor.foreground" = "#ffffff";
};
};
editorAssociations = {
"*.pdf" = "default";
"*.ipynb" = "jupyter.notebook.ipynb";
};
};
python = mapPrefixToSet "python" {
"analysis.completeFunctionParens" = true;
"formatting.provider" = "yapf";
"formatting.yapfArgs" = [
"--style={based_on_style: pep8, indent_width: 2}"
];
"autoComplete.addBrackets" = true;
languageServer = "Pylance";
};
svg = mapPrefixToSet "svgviewer" {
transparencygrid = true;
enableautopreview = true;
previewcolumn = "Beside";
showzoominout = true;
};
indentRainbow = mapPrefixToSet "indentRainbow" {
errorColor= "rgb(255, 0, 0)";
colors = [ # http://colrd.com/palette/38436/
"rgba(26, 19, 52, 0.1)"
"rgba(1, 84, 90, 0.1)"
"rgba(3, 195, 131, 0.1)"
"rgba(251, 191, 69, 0.1)"
"rgba(237, 3, 69, 0.1)"
"rgba(113, 1, 98, 0.1)"
"rgba(2, 44, 125, 0.1)"
"rgba(38, 41, 74, 0.1)"
"rgba(1, 115, 81, 0.1)"
"rgba(170, 217, 98, 0.1)"
"rgba(239, 106, 50, 0.1)"
"rgba(161, 42, 94, 0.1)"
];
ignoreErrorLanguages = [
"markdown"
"haskell"
"elm"
"fsharp"
"java"
];
};
in
editor //
indentRainbow //
python //
svg //
workbench //
vim // # This needs to come after workbench because of setting ordering
zen //
{
"extensions.autoCheckUpdates" = false;
"extensions.autoUpdate" = false;
"diffEditor.ignoreTrimWhitespace" = false;
"diffEditor.hideUnchangedRegions" = "enabled";
"emmet.triggerExpansionOnTab" = true;
"explorer.confirmDragAndDrop" = false;
"git.allowForcePush" = true;
"git.autofetch" = true;
"telemetry.telemetryLevel" = "off";
"terminal.integrated.fontSize" = 14;
"vsintellicode.modify.editor.suggestSelection" = "automaticallyOverrodeDefaultValue";
"keyboard.dispatch" = "keyCode";
"window.zoomLevel" = 1;
"search.exclude" = {
"**/node_modules" = true;
"**/bower_components" = true;
"**/*.code-search" = true;
"**/.direnv/" = true;
};
# This setting does not support language overrides
"files.exclude" = {
# Java
"**/.classpath" = true;
"**/.project" = true;
"**/.settings" = true;
"**/.factorypath" = true;
};
# Extensions
"bracket-pair-colorizer-2.colorMode" = "Consecutive";
"bracket-pair-colorizer-2.forceIterationColorCycle" = true;
"bracket-pair-colorizer-2.colors" = [
"#fff200"
"#3d33ff"
"#ff57d5"
"#00ff11"
"#ff8400"
"#ff0030"
];
"errorLens.errorBackground" = "rgba(240,0,0,0.1)";
"errorLens.warningBackground" = "rgba(180,180,0,0.1)";
"liveshare.presence" = true;
"liveshare.showInStatusBar" = "whileCollaborating";
"liveServer.settings.port" = 5500;
"material-icon-theme.folders.associations" = {
ui = "layout";
bloc = "controller";
};
"redhat.telemetry.enabled" = false;
"[html]" = {
"editor.formatOnSave" = false;
"editor.defaultFormatter" = "vscode.html-language-features";
};
"[javascript]" = {
"editor.formatOnSave" = false;
"editor.defaultFormatter" = "vscode.typescript-language-features";
};
"[json]" = {
"editor.formatOnSave" = true;
"editor.defaultFormatter" = "vscode.json-language-features";
};
"[jsonc]" = {
"editor.defaultFormatter" = "vscode.json-language-features";
vim = mapPrefixToSet "vim" {
useSystemClipboard = true;
"statusBarColorControl" = true;
"statusBarColors.insert" = "#20ff00";
"statusBarColors.normal" = "#1D1E20";
"statusBarColors.visual" = "#00ffff";
"statusBarColors.replace" = "#ff002b";
handleKeys = {
"<C-d>" = true;
"<C-j>" = false;
"<C-b>" = false;
"<C-k>" = false;
"<C-w>" = false;
"<C-n>" = false;
"<A-o>" = true;
};
};
keybindings = [
{
key = "alt+k";
when = "codeActionMenuVisible";
command = "selectPrevCodeAction";
}
workbench = mapPrefixToSet "workbench" {
"settings.enableNaturalLanguageSearch" = false;
enableExperiments = false;
iconTheme = "material-icon-theme";
colorTheme = "Monokai ST3";
colorCustomizations = {
"statusBar.background" = "#1D1E20";
"statusBar.noFolderBackground" = "#1D1E20";
"statusBar.debuggingBackground" = "#1D1E20";
"[Monokai ST3]" = {
"editor.foreground" = "#ffffff";
};
};
editorAssociations = {
"*.pdf" = "default";
"*.ipynb" = "jupyter.notebook.ipynb";
};
};
{
key = "alt+j";
when = "codeActionMenuVisible";
command = "selectNextCodeAction";
}
python = mapPrefixToSet "python" {
"analysis.completeFunctionParens" = true;
"formatting.provider" = "yapf";
"formatting.yapfArgs" = [
"--style={based_on_style: pep8, indent_width: 2}"
];
"autoComplete.addBrackets" = true;
languageServer = "Pylance";
};
{
key = "alt+k";
command = "selectPrevSuggestion";
when = "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus";
}
svg = mapPrefixToSet "svgviewer" {
transparencygrid = true;
enableautopreview = true;
previewcolumn = "Beside";
showzoominout = true;
};
{
key = "alt+j";
command = "selectNextSuggestion";
when = "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus";
}
indentRainbow = mapPrefixToSet "indentRainbow" {
errorColor= "rgb(255, 0, 0)";
colors = [ # http://colrd.com/palette/38436/
"rgba(26, 19, 52, 0.1)"
"rgba(1, 84, 90, 0.1)"
"rgba(3, 195, 131, 0.1)"
"rgba(251, 191, 69, 0.1)"
"rgba(237, 3, 69, 0.1)"
"rgba(113, 1, 98, 0.1)"
"rgba(2, 44, 125, 0.1)"
"rgba(38, 41, 74, 0.1)"
"rgba(1, 115, 81, 0.1)"
"rgba(170, 217, 98, 0.1)"
"rgba(239, 106, 50, 0.1)"
"rgba(161, 42, 94, 0.1)"
];
ignoreErrorLanguages = [
"markdown"
"haskell"
"elm"
"fsharp"
"java"
];
};
{
key = "alt+k";
command = "editor.action.moveLinesUpAction";
when = "editorTextFocus && !editorReadonly && !suggestWidgetVisible";
}
in
editor //
indentRainbow //
python //
svg //
workbench //
vim // # This needs to come after workbench because of setting ordering
zen //
{
"extensions.autoCheckUpdates" = false;
"extensions.autoUpdate" = false;
"diffEditor.ignoreTrimWhitespace" = false;
"diffEditor.hideUnchangedRegions" = "enabled";
"emmet.triggerExpansionOnTab" = true;
"explorer.confirmDragAndDrop" = false;
"git.allowForcePush" = true;
"git.autofetch" = true;
"telemetry.telemetryLevel" = "off";
"terminal.integrated.fontSize" = 14;
"vsintellicode.modify.editor.suggestSelection" = "automaticallyOverrodeDefaultValue";
"window.zoomLevel" = 1;
{
key = "alt+j";
command = "editor.action.moveLinesDownAction";
when = "editorTextFocus && !editorReadonly && !suggestWidgetVisible";
}
"rust-analyzer.server.path" =
toString (pkgs.writeShellScript "ra-multiplex-client" "${lib.getExe pkgs.ra-multiplex} client");
{
key = "alt+j";
command = "workbench.action.quickOpenNavigateNext";
when = "inQuickOpen";
}
"search.exclude" = {
"**/node_modules" = true;
"**/bower_components" = true;
"**/*.code-search" = true;
"**/.direnv/" = true;
};
{
key = "alt+k";
command = "workbench.action.quickOpenNavigatePrevious";
when = "inQuickOpen";
}
# This setting does not support language overrides
"files.exclude" = {
# Java
"**/.classpath" = true;
"**/.project" = true;
"**/.settings" = true;
"**/.factorypath" = true;
};
{
key = "alt+f";
command = "editor.action.formatDocument";
when = "editorTextFocus && !editorReadonly";
}
# Extensions
{
key = "alt+o";
command = "editor.action.insertLineAfter";
when = "textInputFocus && !editorReadonly";
}
{
key = "alt+shift+o";
command = "editor.action.insertLineBefore";
when = "textInputFocus && !editorReadonly";
}
"bracket-pair-colorizer-2.colorMode" = "Consecutive";
"bracket-pair-colorizer-2.forceIterationColorCycle" = true;
"bracket-pair-colorizer-2.colors" = [
"#fff200"
"#3d33ff"
"#ff57d5"
"#00ff11"
"#ff8400"
"#ff0030"
];
extensions = with pkgs.vscode-extensions; [
# WakaTime.vscode-wakatime
# dotjoshjohnson.xml
# eamodio.gitlens
# jock.svg
# ms-azuretools.vscode-docker
# ms-toolsai.jupyter
# ms-vscode-remote.remote-ssh
# ms-vsliveshare.vsliveshare
bbenoist.nix
christian-kohler.path-intellisense
# coenraads.bracket-pair-colorizer-2
haskell.haskell
justusadam.language-haskell
justusadam.language-haskell
mechatroner.rainbow-csv
mhutchie.git-graph
ms-python.python
ms-python.vscode-pylance
ms-vscode-remote.remote-ssh
naumovs.color-highlight
oderwat.indent-rainbow
pkief.material-icon-theme
redhat.vscode-yaml
shardulm94.trailing-spaces
usernamehw.errorlens
rust-lang.rust-analyzer
mkhl.direnv
waderyan.gitblame
vscodevim.vim
hbenl.vscode-test-explorer
# vitaliymaz.vscode-svg-previewer
ms-vscode.test-adapter-converter
visualstudioexptteam.vscodeintellicode
tamasfe.even-better-toml
maximedenes.vscoq
] ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
{
name = "monokai-st3";
publisher = "AndreyVolosovich";
version = "0.2.0";
sha256 = "1rvz5hlrfshy9laybxzvrdklx328s13j0lb8ljbda9zkadi3wcad";
}
{
name = "comment-anchors";
publisher = "ExodiusStudios";
version = "1.10.4";
sha256 = "sha256-FvfjPpQsgCsnY1BylhLCM/qDQChf9/iTr3cKkCGfMVI=";
}
{
name = "vscode-gutter-preview";
publisher = "kisstkondoros";
version = "0.31.2";
sha256 = "sha256-2/RvDSsVL06UmNG9HchXaJMJ4FYtnpuJ2Bn53JVv1t8=";
}
{
name = "keyboard-quickfix";
publisher = "pascalsenn";
version = "0.0.6";
sha256 = "BK7ND6gtRVEitxaokJHmQ5rvSOgssVz+s9dktGQnY6M=";
}
];
"errorLens.errorBackground" = "rgba(240,0,0,0.1)";
"errorLens.warningBackground" = "rgba(180,180,0,0.1)";
"keyboard-quickfix.showActionNotification" = false;
"liveshare.presence" = true;
"liveshare.showInStatusBar" = "whileCollaborating";
"liveServer.settings.port" = 5500;
"material-icon-theme.folders.associations" = {
ui = "layout";
bloc = "controller";
};
"redhat.telemetry.enabled" = false;
"[html]" = {
"editor.formatOnSave" = false;
"editor.defaultFormatter" = "vscode.html-language-features";
};
"[javascript]" = {
"editor.formatOnSave" = false;
"editor.defaultFormatter" = "vscode.typescript-language-features";
};
"[json]" = {
"editor.formatOnSave" = true;
"editor.defaultFormatter" = "vscode.json-language-features";
};
"[jsonc]" = {
"editor.defaultFormatter" = "vscode.json-language-features";
};
};
keybindings = [
{
key = "ctrl+[Period]";
command = "keyboard-quickfix.openQuickFix";
when = "editorHasCodeActionsProvider && editorTextFocus && !editorReadonly";
}
{
key = "alt+k";
command = "selectPrevSuggestion";
when = "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus";
}
{
key = "alt+j";
command = "selectNextSuggestion";
when = "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus";
}
{
key = "alt+k";
command = "editor.action.moveLinesUpAction";
when = "editorTextFocus && !editorReadonly && !suggestWidgetVisible";
}
{
key = "alt+j";
command = "editor.action.moveLinesDownAction";
when = "editorTextFocus && !editorReadonly && !suggestWidgetVisible";
}
{
key = "alt+j";
command = "workbench.action.quickOpenNavigateNext";
when = "inQuickOpen";
}
{
key = "alt+k";
command = "workbench.action.quickOpenNavigatePrevious";
when = "inQuickOpen";
}
{
key = "alt+f";
command = "editor.action.formatDocument";
when = "editorTextFocus && !editorReadonly";
}
{
key = "alt+o";
command = "editor.action.insertLineAfter";
when = "textInputFocus && !editorReadonly";
}
{
key = "alt+shift+o";
command = "editor.action.insertLineBefore";
when = "textInputFocus && !editorReadonly";
}
];
extensions = with pkgs.vscode-extensions; [
# WakaTime.vscode-wakatime
# dotjoshjohnson.xml
# eamodio.gitlens
# jock.svg
# ms-azuretools.vscode-docker
# ms-toolsai.jupyter
ms-vscode-remote.remote-ssh
# ms-vsliveshare.vsliveshare
bbenoist.nix
christian-kohler.path-intellisense
# coenraads.bracket-pair-colorizer-2
haskell.haskell
justusadam.language-haskell
justusadam.language-haskell
mechatroner.rainbow-csv
mhutchie.git-graph
ms-python.python
ms-python.vscode-pylance
ms-vscode-remote.remote-ssh
naumovs.color-highlight
oderwat.indent-rainbow
pkief.material-icon-theme
redhat.vscode-yaml
shardulm94.trailing-spaces
usernamehw.errorlens
rust-lang.rust-analyzer
mkhl.direnv
waderyan.gitblame
# vs-liveshare
vscodevim.vim
] ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
{
name = "monokai-st3";
publisher = "AndreyVolosovich";
version = "0.2.0";
sha256 = "1rvz5hlrfshy9laybxzvrdklx328s13j0lb8ljbda9zkadi3wcad";
}
{
name = "vscode-svgviewer";
publisher = "cssho";
version = "2.0.0";
sha256 = "06swlqiv3gc7plcbmzz795y6zwpxsdhg79k1n3jj6qngfwnv2p6z";
}
{
name = "comment-anchors";
publisher = "ExodiusStudios";
version = "1.10.3";
sha256 = "sha256-IyiiS4jpcghwKI0j8s69uGNZlKnZ0o78ZCT0oZeJER0=";
}
{
name = "vscode-test-explorer";
publisher = "hbenl";
version = "2.21.1";
sha256 = "022lnkq278ic0h9ggpqcwb3x3ivpcqjimhgirixznq0zvwyrwz3w";
}
{
name = "vscode-gutter-preview";
publisher = "kisstkondoros";
version = "0.29.0";
sha256 = "00vibv9xmhwaqiqzp0y2c246pqiqfjsw4bqx4vcdd67pz1wnqhg1";
}
{
name = "test-adapter-converter";
publisher = "ms-vscode";
version = "0.1.9";
sha256 = "sha256-M53jhAVawk2yCeSrLkWrUit3xbDc0zgCK2snbK+BaSs=";
}
# {
# name = "indent-rainbow";
# publisher = "oderwat";
# version = "8.2.2";
# sha256 = "1xxljwh66f21fzmhw8icrmxxmfww1s67kf5ja65a8qb1x1rhjjgf";
# }
{
name = "vscodeintellicode";
publisher = "VisualStudioExptTeam";
version = "1.2.30";
sha256 = "sha256-f2Gn+W0QHN8jD5aCG+P93Y+JDr/vs2ldGL7uQwBK4lE=";
}
{
name = "keyboard-quickfix";
publisher = "pascalsenn";
version = "0.0.6";
sha256 = "BK7ND6gtRVEitxaokJHmQ5rvSOgssVz+s9dktGQnY6M=";
}
];
};
}

@ -1,245 +0,0 @@
{ config, pkgs, lib, ... }:
let
cfg = config.programs.waybar;
cfgs = cfg.settings.mainBar;
in
{
programs.waybar = {
enable = true;
systemd.enable = true;
settings = {
mainBar = {
layer = "top";
position = "top";
height = 30;
# TODO: configure this per machine
# output = [ "DP-2" ];
modules-left = [ "hyprland/workspaces" ];
modules-center = [ "clock" ];
modules-right = [ "mpd" "cpu" "memory" "wireplumber" "pulseaudio/slider" "battery" "tray" ];
"hyprland/workspaces" = {
all-outputs = true;
disable-scroll = true;
persistent-workspaces = {
${lib.head cfgs.output} = [ 1 2 3 4 5 6 7 8 ];
};
};
"mpd" = {
format = "{filename}";
};
"cpu" = {
format = "[#] {usage}%";
};
"memory" = {
format = "{used}/{total}Gb";
};
"wireplumber" = {
format = "{volume}% {icon}";
format-muted = "[M]";
};
"pulseaudio/slider" = {
orientation = "horizontal";
};
"tray" = {
icon-size = 20;
spacing = 8;
};
};
};
style = let
c = config.colors.defaultColorSet;
in ''
* {
font-family: FiraCode, FontAwesome, Roboto, Helvetica, Arial, sans-serif;
font-size: 13px;
}
window#waybar {
background-color: ${c.background};
color: ${c.foreground};
}
#pulseaudio-slider trough {
min-height: 10px;
min-width: 100px;
}
/**** DEFAULT ****/
window#waybar.hidden {
opacity: 0.2;
}
button {
/* Use box-shadow instead of border so the text isn't offset */
box-shadow: inset 0 -3px transparent;
/* Avoid rounded borders under each button name */
border: none;
border-radius: 0;
}
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
button:hover {
background: inherit;
box-shadow: inset 0 -3px #ffffff;
}
#workspaces button.empty {
color: ${c.yellow};
}
#workspaces button {
padding: 0 5px;
color: ${c.magenta};
background-color: transparent;
}
#workspaces button.visible {
color: ${c.green};
}
#workspaces button.urgent {
background-color: ${c.red};
}
#workspaces button:hover {
background: rgba(0, 0, 0, 0.2);
}
#mode {
background-color: #64727D;
box-shadow: inset 0 -3px #ffffff;
}
#clock,
#battery,
#cpu,
#memory,
#disk,
#temperature,
#backlight,
#network,
#pulseaudio,
#wireplumber,
#custom-media,
#tray,
#mode,
#idle_inhibitor,
#scratchpad,
#power-profiles-daemon,
#mpd {
padding: 0 10px;
color: ${c.foreground};
}
#window,
#workspaces {
margin: 0 4px;
}
/* If workspaces is the leftmost module, omit left margin */
.modules-left > widget:first-child > #workspaces {
margin-left: 0;
}
/* If workspaces is the rightmost module, omit right margin */
.modules-right > widget:last-child > #workspaces {
margin-right: 0;
}
#clock {
background-color: #64727D;
}
#cpu {
background-color: ${c.cyan};
color: #000000;
}
#memory {
background-color: ${c.yellow};
color: #000000;
}
#network {
background-color: #2980b9;
}
#network.disconnected {
background-color: #f53c3c;
}
#pulseaudio {
background-color: #f1c40f;
color: #000000;
}
#pulseaudio.muted {
background-color: #90b1b1;
color: #2a5c45;
}
#wireplumber {
background-color: #fff0f5;
color: #000000;
}
#wireplumber.muted {
background-color: #f53c3c;
}
#tray {
background-color: #2980b9;
}
#tray > .passive {
-gtk-icon-effect: dim;
}
#tray > .needs-attention {
-gtk-icon-effect: highlight;
background-color: #eb4d4b;
}
#mpd {
background-color: #66cc99;
color: #2a5c45;
}
#mpd.disconnected {
background-color: #f53c3c;
}
#mpd.stopped {
background-color: #90b1b1;
}
#mpd.paused {
background-color: #51a37a;
}
'';
# background-color: rgba(0,0,0,0);
# border-bottom: 3px solid rgba(100, 114, 125, 0.5);
#style = ''
#'';
};
systemd.user.services.waybar = {
Service.Environment = [
"DISPLAY=:0"
];
};
}

@ -89,7 +89,7 @@ myScratchpads = [ NS "ncmpcpp" spawnNC findNC layoutA
-- spawnMX = "element"
spawnFB = "thunar --class=floatingThunar"
spawnEX = "emacs --name=floatingEmacs"
spawnSC = "nsxiv -N floatingSchedule ~/uni/schedule.png"
spawnSC = "sxiv -N floatingSchedule ~/uni/schedule.png"
spawnHP = "echo \"" ++ help ++ "\" | xmessage -file -"
findNC = title =? "ncmpcppScratchpad"
@ -168,7 +168,7 @@ myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $
, ((modm .|. shiftMask , xK_space ), spawn $ myTerminal ++ " -e tmux")
-- , ((modm , xK_v ), spawn "rofi -modi lpass:$HOME/.scripts/rofi/lpass//rofi-lpass -show lpass")
-- , ((modm .|. shiftMask, xK_d ), viewDropboxStatus)
, ((modm .|. shiftMask, xK_d ), viewDropboxStatus)
]
termIsOpen :: X Bool

@ -1,4 +0,0 @@
{ ... }:
{
programs.yt-dlp.enable = true;
}

@ -1,154 +1,26 @@
{ pkgs, unstable-pkgs, ... }:
{ config, pkgs, lib, ... }:
{
programs.zed-editor = {
enable = true;
home.packages = with pkgs; [ zed-editor ];
package = unstable-pkgs.zed-editor;
xdg.configFile."zed/settings.json".source = let
format = pkgs.formats.json { };
in format.generate "zed-settings.json" {
autosave = "off";
buffer_font_family = "Fira Code";
load_direnv = "shell_hook";
format_on_save = "off";
userSettings = {
load_direnv = "shell_hook";
base_keymap = "VSCode";
autosave = "off";
format_on_save = "off";
remove_trailing_whitespace_on_save = true;
tab_size = 2;
ui_font_family = "Noto Sans";
ui_font_size = 18;
buffer_font_family = "Fira Code";
buffer_font_size = 16;
terminal.font_family = "Fira Code";
terminal.font_size = 15;
file_types = {
"Groovy" = [ "Jenkinsfile*" ];
"Dockerfile" = [ "Dockerfile*" ];
"JSONC" = [ "json5" ];
};
tabs = {
file_icons = true;
show_close_button = "always";
show_diagnostics = "errors";
};
telemetry = {
diagnostics = false;
metrics = false;
};
diagnostics = {
include_warnings = true;
inline.enabled = true;
update_with_cursor = false;
primary_only = false;
use_rendered = false;
};
relative_linue_numbers = true;
vim_mode = true;
vim = {
toggle_relative_line_numbers = true;
};
theme = {
mode = "dark";
light = "monokai Classic";
dark = "monokai Darker Classic";
};
icon_theme = "Material Icon Theme";
file_scan_exclusions = [
"**/.git"
"**/.svn"
"**/.hg"
"**/.jj"
"**/CVS"
"**/.DS_Store"
"**/Thumbs.db"
"**/.classpath"
"**/.settings"
"**/.direnv"
];
git_status = true;
git.inline_blame.enabled = false;
collaboration_panel.button = false;
preview_tabs.enable = false;
indent_guides = {
enabled = true;
coloring = "indent_aware";
};
features.edit_prediction_provider = "copilot";
languages = {
Nix = {
tab_size = 2;
format_on_save = "off";
};
};
lsp = {
rust-analyzer.binary.path_lookup = true;
nix.binary.path_lookup = true;
};
telemetry = {
diagnostics = false;
metrics = false;
};
userKeymaps = [
{
bindings = {
ctrl-b = "workspace::ToggleLeftDock";
ctrl-j = "workspace::ToggleBottomDock";
ctrl-w = "pane::CloseActiveItem";
ctrl-h = "pane::ActivatePreviousItem";
ctrl-l = "pane::ActivateNextItem";
ctrl-shift-h = "pane::ActivateLastItem";
# ctrl-shift-l = "pane::ActivatFirstItem"; # wat?
ctrl-shift-o = "workspace::Open";
};
}
];
vim_mode = true;
extensions = [
"assembly-syntax"
"basher"
"dart"
"dart"
"dockerfile"
"env"
"git-firefly"
"graphql"
"groovy"
"html"
"ini"
"just"
"latex"
"live-server"
"log"
"make"
"material-icon-theme"
"mermaid"
"neocmake"
"nix"
"ocaml"
"rainbow-csv"
"ruff"
"sql"
"strace"
"toml"
"typst"
];
theme = {
mod = "dark";
dark = "monokai Classic";
};
};
xdg.configFile."zed/themes/monokai.json".source = let
@ -159,10 +31,4 @@
hash = "sha256-mlEcgnLStYH1pV3p1iqNSvfVu4MpvpEOc+vxI+90MJs=";
};
in "${package}/themes/monokai.json";
programs.zsh.initContent = ''
if [[ "$ZED_TERM" == "true" && -n "$TMUX_PANE" ]]; then
unset TMUX_PANE
fi
'';
}

@ -1,7 +0,0 @@
{ config, ... }:
{
programs.zoxide = {
enable = true;
enableNushellIntegration = config.programs.nushell.enable;
};
}

@ -24,6 +24,10 @@ in
defaultKeymap = "viins";
enableCompletion = true;
initExtraBeforeCompInit = ''
fpath+=(${pkgs.zsh-completions}/share/zsh/site-functions)
'';
completionInit = "";
history = {
@ -69,24 +73,19 @@ in
}
];
initContent = lib.mkMerge [
(lib.mkOrder 550 ''
fpath+=(${pkgs.zsh-completions}/share/zsh/site-functions)
'')
''
source ${./p10k.zsh}
initExtra = ''
source ${./p10k.zsh}
enable-fzf-tab
enable-fzf-tab
zstyle ':fzf-tab:complete:cd:*' fzf-preview '${lib.getExe pkgs.eza} -1 --color=always $realpath'
zstyle ':fzf-tab:complete:cd:*' fzf-preview '${lib.getExe pkgs.eza} -1 --color=always $realpath'
# Use tmux buffer if we are inside tmux
if ! { [ "$TERM" = "screen" ] && [ -n "$TMUX" ]; } then
zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup
fi
# Use tmux buffer if we are inside tmux
if ! { [ "$TERM" = "screen" ] && [ -n "$TMUX" ]; } then
zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup
fi
source "${config.xdg.configHome}/mutable_env.sh"
''
];
source "${config.xdg.configHome}/mutable_env.sh"
'';
};
}

Some files were not shown because too many files have changed in this diff Show More