This commit is contained in:
atagen 2023-03-31 17:06:30 +11:00
commit e1f0d0db28
144 changed files with 10150 additions and 1 deletions

@ -1 +0,0 @@
Subproject commit b76809f06d5460e8cd9cd4be770760e4e54a142f

21
foreign/dotfiles/LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-2021 Mihai Fufezan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,74 @@
<h1 align="center">fufexan/dotfiles</h1>
# 🗒 About
In-house baked configs for Home-Manager and NixOS. Borrowed bits sprinkled on
top. Using [flakes](https://nixos.wiki/wiki/Flakes) and
[flake-parts](https://github.com/hercules-ci/flake-parts).
See an overview of the flake outputs by running
`nix flake show github:fufexan/dotfiles`.
## 🗃️ Contents
- [modules](modules): NixOS common configs
- [hosts](hosts): host-specific configuration
- [home](home): my [Home Manager](https://github.com/nix-community/home-manager) config
- [lib](lib): helper functions
- [pkgs](pkgs): package definitions
# 📦 Exported packages
Run packages directly with:
```console
nix run github:fufexan/dotfiles#packageName
```
Or install from the `packages` output. For example:
```nix
# flake.nix
{
inputs.fufexan-dotfiles.url = "github:fufexan/dotfiles";
# Override my nixpkgs, binary cache will have less hits
inputs.fufexan-dotfiles.inputs.nixpkgs.follows = "nixpkgs";
}
# configuration.nix
{pkgs, inputs, ...}: {
environment.systemPackages = [
inputs.fufexan-dotfiles.packages."x86_64-linux".packageName
];
}
```
## 💻 Desktop preview
<a href="https://drive.google.com/file/d/1W-bwn3UwbMxReiiNqMmq38noa7Xw0Gj1/preview">
<img src="https://user-images.githubusercontent.com/36706276/216402032-ff32fcad-ca21-49d3-9c29-6ff0d2d8b1d8.png" alt="Desktop Preview">
</a>
*Hint: click to go to a video showcase*
# 💾 Resources
Other configurations from where I learned and copied:
- [colemickens/nixcfg](https://github.com/colemickens/nixcfg)
- [flake-utils-plus](https://github.com/gytis-ivaskevicius/flake-utils-plus)
- [gytis-ivaskevicius/nixfiles](https://github.com/gytis-ivaskevicius/nixfiles)
- [Mic92/dotfiles](https://github.com/Mic92/dotfiles)
- [NobbZ/nixos-config](https://github.com/NobbZ/nixos-config)
- [privatevoid-net/privatevoid-infrastructure](https://github.com/privatevoid-net/privatevoid-infrastructure)
- [RicArch97/nixos-config](https://github.com/RicArch97/nixos-config)
- [viperML/dotfiles](https://github.com/viperML/dotfiles)
# 👥 People
These are the people whom I've taken inspiration from while writing these
configs. There surely are more but I tend to forget. Regardless, I am thankful
to all of them.
DieracDelta - gytis-ivaskevicius - hlissner - keksbg - Kranzes -
matthewcroughan - max-privatevoid - Misterio77 - NobbZ - OPNA2608 -
pnotequalnp - RicArch97 - tadeokondrak - viperML - Xe - yusdacra

788
foreign/dotfiles/flake.lock generated Normal file
View file

@ -0,0 +1,788 @@
{
"nodes": {
"agenix": {
"inputs": {
"darwin": "darwin",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1677969766,
"narHash": "sha256-AIp/ZYZMNLDZR/H7iiAlaGpu4lcXsVt9JQpBlf43HRY=",
"owner": "ryantm",
"repo": "agenix",
"rev": "03b51fe8e459a946c4b88dcfb6446e45efb2c24e",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"crane": {
"flake": false,
"locked": {
"lastModified": 1670900067,
"narHash": "sha256-VXVa+KBfukhmWizaiGiHRVX/fuk66P8dgSFfkVN4/MY=",
"owner": "ipetkov",
"repo": "crane",
"rev": "59b31b41a589c0a65e4a1f86b0e5eac68081468b",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"darwin": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1673295039,
"narHash": "sha256-AsdYgE8/GPwcelGgrntlijMg4t3hLFJFCRF3tL5WVjA=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "87b9d090ad39b25b2400029c64825fc2a8868943",
"type": "github"
},
"original": {
"owner": "lnl7",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"devshell": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1678957337,
"narHash": "sha256-Gw4nVbuKRdTwPngeOZQOzH/IFowmz4LryMPDiJN/ah4=",
"owner": "numtide",
"repo": "devshell",
"rev": "3e0e60ab37cd0bf7ab59888f5c32499d851edb47",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"dream2nix": {
"inputs": {
"alejandra": [
"helix",
"nci"
],
"all-cabal-json": [
"helix",
"nci"
],
"crane": "crane",
"devshell": [
"helix",
"nci"
],
"flake-parts": [
"helix",
"nci",
"parts"
],
"flake-utils-pre-commit": [
"helix",
"nci"
],
"ghc-utils": [
"helix",
"nci"
],
"gomod2nix": [
"helix",
"nci"
],
"mach-nix": [
"helix",
"nci"
],
"nix-pypi-fetcher": [
"helix",
"nci"
],
"nixpkgs": [
"helix",
"nci",
"nixpkgs"
],
"poetry2nix": [
"helix",
"nci"
],
"pre-commit-hooks": [
"helix",
"nci"
],
"pruned-racket-catalog": [
"helix",
"nci"
]
},
"locked": {
"lastModified": 1677289985,
"narHash": "sha256-lUp06cTTlWubeBGMZqPl9jODM99LpWMcwxRiscFAUJg=",
"owner": "nix-community",
"repo": "dream2nix",
"rev": "28b973a8d4c30cc1cbb3377ea2023a76bc3fb889",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "dream2nix",
"type": "github"
}
},
"eww": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": [
"nixpkgs"
],
"rust-overlay": [
"rust-overlay"
]
},
"locked": {
"lastModified": 1678303550,
"narHash": "sha256-JlpoMXL+QIO0DUIyAcGRJte2G/jF/rSeO/zze5W7S/s=",
"owner": "elkowar",
"repo": "eww",
"rev": "45154bbf5962cad9c4e6c76f75d57dd8d740d307",
"type": "github"
},
"original": {
"owner": "elkowar",
"repo": "eww",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1650374568,
"narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "b4a34015c698c7793d592d66adbab377907a2be8",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1678379998,
"narHash": "sha256-TZdfNqftHhDuIFwBcN9MUThx5sQXCTeZk9je5byPKRw=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "c13d60b89adea3dc20704c045ec4d50dd964d447",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1642700792,
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "846b2ae0fc4cc943637d3d1def4454213e203cba",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"fu": {
"locked": {
"lastModified": 1678901627,
"narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"helix": {
"inputs": {
"nci": "nci",
"nixpkgs": "nixpkgs",
"parts": [
"flake-parts"
],
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1678544833,
"narHash": "sha256-aLs6qjiViaxryP2XMjKPzrJGYfIQsGTbNWfbySfivmY=",
"owner": "SoraTenshi",
"repo": "helix",
"rev": "80782f4f3cd557617d09b0d8f42dbce780552630",
"type": "github"
},
"original": {
"owner": "SoraTenshi",
"ref": "daily-driver",
"repo": "helix",
"type": "github"
}
},
"hm": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"utils": "utils"
},
"locked": {
"lastModified": 1679067095,
"narHash": "sha256-G2dJQURL/CCi+8RP6jNJG8VqgtzEMCA+6mNodd3VR6E=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "3239e0b40f242f47bf6c0c37b2fd35ab3e76e370",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"hyprland": {
"inputs": {
"hyprland-protocols": "hyprland-protocols",
"nixpkgs": "nixpkgs_2",
"wlroots": "wlroots",
"xdph": "xdph"
},
"locked": {
"lastModified": 1679166084,
"narHash": "sha256-yr+alTr1eGjEKpMiD06FTTMP6vaoNwYEZT6mW6dQ5rM=",
"owner": "hyprwm",
"repo": "Hyprland",
"rev": "06244555915339967864292dd0b83cd9732516d8",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "Hyprland",
"type": "github"
}
},
"hyprland-contrib": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1679036674,
"narHash": "sha256-2s3Hfq56jL8ePyc3+calPT34FNMK2zksqwPhIxAq20o=",
"owner": "hyprwm",
"repo": "contrib",
"rev": "1af47a008e850c595aeddc83bb3f04fd81935caa",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "contrib",
"type": "github"
}
},
"hyprland-protocols": {
"inputs": {
"nixpkgs": [
"hyprland",
"nixpkgs"
]
},
"locked": {
"lastModified": 1671839510,
"narHash": "sha256-+PY1qqJfmZzzROgcIY4I7AkCwpnC+qBIYk2eFoA9RWc=",
"owner": "hyprwm",
"repo": "hyprland-protocols",
"rev": "b8f55e02a328c47ed373133c52483bbfa20a1b75",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprland-protocols",
"type": "github"
}
},
"kmonad": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"dir": "nix",
"lastModified": 1673185501,
"narHash": "sha256-uEtWPpl9nH7QqochHo1z+giPga1zXR1Ko3dOXHIapFY=",
"owner": "kmonad",
"repo": "kmonad",
"rev": "3413f1be996142c8ef4f36e246776a6df7175979",
"type": "github"
},
"original": {
"dir": "nix",
"owner": "kmonad",
"repo": "kmonad",
"type": "github"
}
},
"lowdown-src": {
"flake": false,
"locked": {
"lastModified": 1633514407,
"narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=",
"owner": "kristapsdz",
"repo": "lowdown",
"rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8",
"type": "github"
},
"original": {
"owner": "kristapsdz",
"repo": "lowdown",
"type": "github"
}
},
"mk-naked-shell": {
"flake": false,
"locked": {
"lastModified": 1676572903,
"narHash": "sha256-oQoDHHUTxNVSURfkFcYLuAK+btjs30T4rbEUtCUyKy8=",
"owner": "yusdacra",
"repo": "mk-naked-shell",
"rev": "aeca9f8aa592f5e8f71f407d081cb26fd30c5a57",
"type": "github"
},
"original": {
"owner": "yusdacra",
"repo": "mk-naked-shell",
"type": "github"
}
},
"nci": {
"inputs": {
"dream2nix": "dream2nix",
"mk-naked-shell": "mk-naked-shell",
"nixpkgs": [
"helix",
"nixpkgs"
],
"parts": "parts",
"rust-overlay": [
"helix",
"rust-overlay"
]
},
"locked": {
"lastModified": 1677297103,
"narHash": "sha256-ArlJIbp9NGV9yvhZdV0SOUFfRlI/kHeKoCk30NbSiLc=",
"owner": "yusdacra",
"repo": "nix-cargo-integration",
"rev": "a79272a2cb0942392bb3a5bf9a3ec6bc568795b2",
"type": "github"
},
"original": {
"owner": "yusdacra",
"repo": "nix-cargo-integration",
"type": "github"
}
},
"nix-gaming": {
"inputs": {
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1678324469,
"narHash": "sha256-FWI0+K1zdfzOq8BbgGhRvy+qp2J4KauGL1geAc19PRQ=",
"owner": "fufexan",
"repo": "nix-gaming",
"rev": "18fac9dd032d0bb1d4c660b3257fa00df7f0145d",
"type": "github"
},
"original": {
"owner": "fufexan",
"repo": "nix-gaming",
"type": "github"
}
},
"nix-super": {
"inputs": {
"lowdown-src": "lowdown-src",
"nixpkgs": "nixpkgs_4",
"nixpkgs-regression": "nixpkgs-regression"
},
"locked": {
"lastModified": 1677536397,
"narHash": "sha256-pKp+dmOJc3/9R3dBP30u2zXOyCuF5dVzgFlS1upSwZk=",
"owner": "privatevoid-net",
"repo": "nix-super",
"rev": "8eb40776e51819038fbb8a087d9885842451a333",
"type": "github"
},
"original": {
"owner": "privatevoid-net",
"repo": "nix-super",
"type": "github"
}
},
"nix-xilinx": {
"inputs": {
"flake-compat": "flake-compat_2",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1678957299,
"narHash": "sha256-myDk5QC9Q5FESSJl5N3Nf67w+dwq2KpvcguTwodKGqo=",
"owner": "doronbehar",
"repo": "nix-xilinx",
"rev": "e1533146984dd11bdefd6042c282cd123aca8d71",
"type": "gitlab"
},
"original": {
"owner": "doronbehar",
"repo": "nix-xilinx",
"type": "gitlab"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1677063315,
"narHash": "sha256-qiB4ajTeAOVnVSAwCNEEkoybrAlA+cpeiBxLobHndE8=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "988cc958c57ce4350ec248d2d53087777f9e1949",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-regression": {
"locked": {
"lastModified": 1643052045,
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1677676435,
"narHash": "sha256-6FxdcmQr5JeZqsQvfinIMr0XcTyTuR7EXX0H3ANShpQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a08d6979dd7c82c4cef0dcc6ac45ab16051c1169",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1677995890,
"narHash": "sha256-eOnCn0o3I6LP48fAi8xWFcn49V2rL7oX5jCtJTeN1LI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a1240f6b4a0bcc84fc48008b396a140d9f3638f6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1670461440,
"narHash": "sha256-jy1LB8HOMKGJEGXgzFRLDU1CBGL0/LlkolgnqIsF0D8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "04a75b2eecc0acf6239acf9dd04485ff8d14f425",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-22.11-small",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1678898370,
"narHash": "sha256-xTICr1j+uat5hk9FyuPOFGxpWHdJRibwZC+ATi0RbtE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ac718d02867a84b42522a0ece52d841188208f2c",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"parts": {
"inputs": {
"nixpkgs-lib": [
"helix",
"nci",
"nixpkgs"
]
},
"locked": {
"lastModified": 1675933616,
"narHash": "sha256-/rczJkJHtx16IFxMmAWu5nNYcSXNg1YYXTHoGjLrLUA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "47478a4a003e745402acf63be7f9a092d51b83d7",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"devshell": "devshell",
"eww": "eww",
"flake-parts": "flake-parts",
"fu": "fu",
"helix": "helix",
"hm": "hm",
"hyprland": "hyprland",
"hyprland-contrib": "hyprland-contrib",
"kmonad": "kmonad",
"nix-gaming": "nix-gaming",
"nix-super": "nix-super",
"nix-xilinx": "nix-xilinx",
"nixpkgs": "nixpkgs_5",
"rust-overlay": "rust-overlay_2",
"spicetify-nix": "spicetify-nix"
}
},
"rust-overlay": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": [
"helix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1677292251,
"narHash": "sha256-D+6q5Z2MQn3UFJtqsM5/AvVHi3NXKZTIMZt1JGq/spA=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "34cdbf6ad480ce13a6a526f57d8b9e609f3d65dc",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"rust-overlay_2": {
"inputs": {
"flake-utils": [
"fu"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1679106165,
"narHash": "sha256-03Opt2yu4E/AIFjvlgib0/nhMn6B4B/t/nvwS2bzOGw=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "7313c06ac334d6262ddfe30a38b3abc3da6bd565",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"spicetify-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1675736383,
"narHash": "sha256-fjQmN3pYGstBNHCFdmPzDf1/Dt04v3b7+/w4cQ4gkKo=",
"owner": "the-argus",
"repo": "spicetify-nix",
"rev": "ec85c2a2f5d1035142b8e383cc77b68bb0b9ebc8",
"type": "github"
},
"original": {
"owner": "the-argus",
"repo": "spicetify-nix",
"type": "github"
}
},
"utils": {
"locked": {
"lastModified": 1676283394,
"narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"wlroots": {
"flake": false,
"locked": {
"host": "gitlab.freedesktop.org",
"lastModified": 1677789111,
"narHash": "sha256-dWrk+Q3bLdtFe5rkyaAKWCQJCeE/KFNllcu1DvBC38c=",
"owner": "wlroots",
"repo": "wlroots",
"rev": "5ae17de23f5fd9bb252a698f3771c840280e2c05",
"type": "gitlab"
},
"original": {
"host": "gitlab.freedesktop.org",
"owner": "wlroots",
"repo": "wlroots",
"type": "gitlab"
}
},
"xdph": {
"inputs": {
"hyprland-protocols": [
"hyprland",
"hyprland-protocols"
],
"nixpkgs": [
"hyprland",
"nixpkgs"
]
},
"locked": {
"lastModified": 1673116118,
"narHash": "sha256-eR0yDSkR2XYMesfdRWJs25kAdXET2mbNNHu5t+KUcKA=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"rev": "d479c846531fd0e1d2357c9588b8310a2b859ef2",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

111
foreign/dotfiles/flake.nix Normal file
View file

@ -0,0 +1,111 @@
{
description = "fufexan's NixOS and Home-Manager flake";
outputs = inputs:
inputs.flake-parts.lib.mkFlake {inherit inputs;} {
systems = ["x86_64-linux"];
imports = [
./home/profiles
./hosts
./modules
./pkgs
./lib
{config._module.args._inputs = inputs // {inherit (inputs) self;};}
];
perSystem = {
config,
inputs',
pkgs,
system,
...
}: {
imports = [
{
_module.args.pkgs = inputs.self.legacyPackages.${system};
}
];
devShells.default = inputs'.devshell.legacyPackages.mkShell {
packages = [
pkgs.alejandra
pkgs.git
config.packages.repl
];
name = "dots";
};
formatter = pkgs.alejandra;
};
};
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
agenix = {
url = "github:ryantm/agenix";
inputs.nixpkgs.follows = "nixpkgs";
};
devshell = {
url = "github:numtide/devshell";
inputs.nixpkgs.follows = "nixpkgs";
};
eww = {
url = "github:elkowar/eww";
inputs.nixpkgs.follows = "nixpkgs";
inputs.rust-overlay.follows = "rust-overlay";
};
fu.url = "github:numtide/flake-utils";
helix = {
url = "github:SoraTenshi/helix/daily-driver";
inputs.parts.follows = "flake-parts";
};
hm = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
hyprland.url = "github:hyprwm/Hyprland";
hyprland-contrib = {
url = "github:hyprwm/contrib";
inputs.nixpkgs.follows = "nixpkgs";
};
kmonad = {
url = "github:kmonad/kmonad?dir=nix";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-gaming.url = "github:fufexan/nix-gaming";
nix-super.url = "github:privatevoid-net/nix-super";
nix-xilinx = {
url = "gitlab:doronbehar/nix-xilinx";
inputs.nixpkgs.follows = "nixpkgs";
};
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "fu";
};
spicetify-nix = {
url = "github:the-argus/spicetify-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
}

View file

@ -0,0 +1,15 @@
# Home config
Home-Manager configurations for different hosts.
Name | Description
--------------- | -----------
`default.nix` | Home-Manager specific configuration
`editors` | Helix & Neovim
`programs` | Programs
`shell` | Zsh, Nix options, etc.
`terminals` | Terminal configs
`wayland` | Wayland-specific options, including Sway and Waybar configs
`profiles` is a special dir where `homeConfigurations` are set up. They're
basically the entrypoints of the configs.

View file

@ -0,0 +1,18 @@
{
home = {
username = "mihai";
homeDirectory = "/home/mihai";
stateVersion = "20.09";
extraOutputsToInstall = ["doc" "devdoc"];
};
# disable manuals as nmd fails to build often
manual = {
html.enable = false;
json.enable = false;
manpages.enable = false;
};
# let HM manage itself when in standalone mode
programs.home-manager.enable = true;
}

View file

@ -0,0 +1,44 @@
{
inputs,
pkgs,
...
} @ args: {
home.packages = [pkgs.shellcheck];
programs.helix = {
enable = true;
package = inputs.helix.packages.${pkgs.hostPlatform.system}.default;
languages = import ./languages.nix args;
settings = {
theme = "catppuccin_mocha";
editor = {
true-color = true;
color-modes = true;
cursorline = true;
cursor-shape = {
insert = "bar";
normal = "block";
select = "underline";
};
indent-guides = {
render = true;
rainbow-option = "dim";
};
rainbow-brackets = true;
statusline.center = ["position-percentage"];
whitespace.characters = {
newline = "";
tab = "";
};
};
keys.normal.space.u = {
f = ":format"; # format using LSP formatter
w = ":set whitespace.render all";
W = ":set whitespace.render none";
};
};
};
}

View file

@ -0,0 +1,47 @@
{pkgs, ...}:
with pkgs; [
{
name = "bash";
language-server = {
command = "${nodePackages.bash-language-server}/bin/bash-language-server";
args = ["start"];
};
auto-format = true;
formatter = {
command = "${shfmt}/bin/shfmt";
args = ["-i" "2" "-"];
};
}
{
name = "cpp";
language-server = {
command = "${clang-tools}/bin/clangd";
clangd.fallbackFlags = ["-std=c++2b"];
};
}
{
name = "nix";
language-server = {command = lib.getExe nil;};
config.nil.formatting.command = ["alejandra" "-q"];
}
{
name = "clojure";
scope = "source.clojure";
injection-regex = "(clojure|clj|edn|boot|yuck)";
file-types = ["clj" "cljs" "cljc" "clje" "cljr" "cljx" "edn" "boot" "yuck"];
roots = ["project.clj" "build.boot" "deps.edn" "shadow-cljs.edn"];
comment-token = ";";
language-server = {command = "clojure-lsp";};
indent = {
tab-width = 2;
unit = " ";
};
}
{
name = "css";
language-server = {
command = "${nodePackages.vscode-css-languageserver-bin}/bin/css-languageserver";
args = ["--stdio"];
};
}
]

View file

@ -0,0 +1,14 @@
vim.opt.expandtab = true
vim.opt.hidden = true
vim.opt.incsearch = true
vim.opt.mouse = "a"
vim.opt.number = true
vim.opt.shiftwidth = 2
vim.opt.splitbelow = true
vim.opt.splitright = true
vim.opt.signcolumn = "yes:3"
vim.opt.tabstop = 2
vim.opt.timeoutlen = 0
vim.wo.wrap = false
vim.opt.exrc = true
vim.cmd("syntax on")

View file

@ -0,0 +1,28 @@
local lspc = require'lspconfig'
lspc.nil_ls.setup{}
lspc.clangd.setup{}
local buf_map = function(bufnr, mode, lhs, rhs, opts)
vim.api.nvim_buf_set_keymap(bufnr, mode, lhs, rhs, opts or {
silent = true,
})
end
lspc.tsserver.setup({
on_attach = function(client, bufnr)
client.resolved_capabilities.document_formatting = false
client.resolved_capabilities.document_range_formatting = false
local ts_utils = require("nvim-lsp-ts-utils")
ts_utils.setup({})
ts_utils.setup_client(client)
buf_map(bufnr, "n", "gs", ":TSLspOrganize<CR>")
buf_map(bufnr, "n", "gi", ":TSLspRenameFile<CR>")
buf_map(bufnr, "n", "go", ":TSLspImportAll<CR>")
on_attach(client, bufnr)
end,
})

View file

@ -0,0 +1,73 @@
local has_words_before = function()
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end
local feedkey = function(key, mode)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true)
end
local cmp = require("cmp")
local lspkind = require("lspkind")
cmp.setup({
sources = {
{ name = "nvim_lsp" },
{ name = "cmp_tabnine" },
{ name = "treesitter" },
{ name = "buffer" },
{ name = "path" },
{ name = "vsnip" },
-- { name = "copilot" },
},
snippet = {
expand = function(args)
vim.fn["vsnip#anonymous"](args.body)
end,
},
formatting = {
format = lspkind.cmp_format({
with_text = true,
menu = {
buffer = "[Buf]",
nvim_lsp = "[LSP]",
nvim_lua = "[Lua]",
latex_symbols = "[Latex]",
treesitter = "[TS]",
cmp_tabnine = "[TN]",
vsnip = "[Snip]",
},
}),
},
mapping = {
["<CR>"] = cmp.mapping.confirm({ select = true }),
["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif vim.fn["vsnip#available"](1) == 1 then
feedkey("<Plug>(vsnip-expand-or-jump)", "")
elseif has_words_before() then
cmp.complete()
else
fallback()
end
end, {
"i",
"s",
}),
["<S-Tab>"] = cmp.mapping(function()
if cmp.visible() then
cmp.select_prev_item()
elseif vim.fn["vsnip#jumpable"](-1) == 1 then
feedkey("<Plug>(vsnip-jump-prev)", "")
end
end, {
"i",
"s",
}),
},
})

View file

@ -0,0 +1,20 @@
-- set colorscheme
vim.cmd 'set termguicolors'
vim.g.catppuccin_flavour = "mocha"
require("catppuccin").setup()
vim.cmd [[colorscheme catppuccin]]
-- enable colorizer
require'colorizer'.setup()
-- set sign
vim.cmd 'sign define DiagnosticSignError text= linehl= texthl=DiagnosticSignError numhl='
vim.cmd 'sign define DiagnosticSignHint text= linehl= texthl=DiagnosticSignHint numhl='
vim.cmd 'sign define DiagnosticSignInfo text= linehl= texthl=DiagnosticSignInfo numhl='
vim.cmd 'sign define DiagnosticSignWarn text= linehl= texthl=DiagnosticSignWarn numhl='
-- set lightline theme to horizon
vim.g.lightline = { colorscheme = "catppuccin" }

View file

@ -0,0 +1,14 @@
require'nvim-treesitter.configs'.setup {
textobjects = {
select = {
enable = true,
keymaps = {
-- You can use the capture groups defined in textobjects.scm
["af"] = "@function.outer",
["if"] = "@function.inner",
["ac"] = "@class.outer",
["ic"] = "@class.inner",
},
},
},
}

View file

@ -0,0 +1,30 @@
require("nvim-treesitter.configs").setup({
highlight = {
enable = true,
disable = {},
},
rainbow = {
enable = true,
extended_mode = true,
},
autotag = {
enable = true,
},
context_commentstring = {
enable = true,
},
incremental_selection = {
enable = true,
keymaps = {
init_selection = "gnn",
node_incremental = "grn",
scope_incremental = "grc",
node_decremental = "grm",
},
},
})
-- breaks highlight
-- vim.cmd([[set foldmethod=expr]])
-- vim.cmd([[set foldlevel=10]])
-- vim.cmd([[set foldexpr=nvim_treesitter#foldexpr()]])

View file

@ -0,0 +1,29 @@
-- telescope
require('telescope').load_extension('fzy_native')
-- null-ls
local nb = require('null-ls').builtins
require('null-ls').setup({
sources = {
nb.formatting.alejandra,
nb.code_actions.statix,
nb.diagnostics.cppcheck,
nb.diagnostics.deadnix,
nb.diagnostics.statix,
nb.diagnostics.eslint,
nb.completion.spell,
},
})
require("gitsigns").setup()
-- autopairs
require('nvim-autopairs').setup{}
-- copy to system clipboard
vim.api.nvim_set_keymap( 'v', '<Leader>y', '"+y', {noremap = true})
vim.api.nvim_set_keymap( 'n', '<Leader>y', ':%+y<CR>', {noremap = true})
-- paste from system clipboard
vim.api.nvim_set_keymap( 'n', '<Leader>p', '"+p', {noremap = true})

View file

@ -0,0 +1,39 @@
vim.g.mapleader = " "
local wk = require("which-key")
wk.setup({})
wk.register({
["<leader>"] = {
b = { "<cmd>Telescope buffers<cr>", "Buffers" },
["/"] = { "<cmd>Telescope live_grep<cr>", "Live Grep" },
f = { "<cmd>Telescope find_files<cr>", "Find File" },
g = {
name = "Git / VCS",
i = { "<cmd>lua require('telescope').extensions.gh.issues()<cr>", "Github Issues" },
p = { "<cmd>lua require('telescope').extensions.gh.pull_request()<cr>", "Github PRs" },
b = { "<cmd>ToggleBlameLine<cr>", "Toggle BlameLine" },
c = { "<cmd>Neogit commit<cr>", "Commit" },
s = { "<cmd>Neogit kind=split<cr>", "Staging" },
},
a = { "<cmd>lua require('telescope.builtin').lsp_code_actions()<cr>", "Code Actions" },
d = { "<cmd>lua require('telescope.builtin').lsp_document_diagnostics()<cr>", "LSP Diagnostics" },
k = { "<cmd>lua vim.lsp.buf.signature_help()<cr>", "Signature Help" },
l = {
name = "LSP",
f = { "<cmd>lua vim.lsp.buf.formatting_sync()<cr>", "Format file"},
q = { "<cmd>lua vim.lsp.diagnostic.set_loclist()<cr>", "Set Loclist" },
e = { "<cmd>lua vim.lsp.diagnostic.show_line_diagnostics()<cr>", "Show Line Diagnostics" },
},
p = { "\"+p", "Paste from clipboard" },
P = { "\"+P", "Paste from clipboard before cursor" },
y = { "\"+y", "Yank to clipboard" },
},
g = {
l = { "$", "Line end" },
h = { "0", "Line start" },
s = { "^", "First non-blank in line" },
e = { "G", "Bottom" },
},
})

View file

@ -0,0 +1,62 @@
{pkgs, ...}: {
programs.neovim = {
enable = true;
vimAlias = true;
viAlias = true;
vimdiffAlias = true;
plugins = with pkgs.vimPlugins; [
catppuccin-nvim
cmp-buffer
cmp-nvim-lsp
cmp-path
cmp-spell
cmp-treesitter
cmp-vsnip
friendly-snippets
gitsigns-nvim
lightline-vim
lspkind-nvim
neogit
null-ls-nvim
nvim-autopairs
nvim-cmp
nvim-colorizer-lua
nvim-lspconfig
nvim-tree-lua
nvim-ts-rainbow
(nvim-treesitter.withPlugins (_: pkgs.tree-sitter.allGrammars))
plenary-nvim
telescope-fzy-native-nvim
telescope-nvim
vim-floaterm
vim-sneak
vim-vsnip
which-key-nvim
];
extraPackages = with pkgs; [gcc ripgrep fd];
extraConfig = let
luaRequire = module:
builtins.readFile (builtins.toString
./config
+ "/${module}.lua");
luaConfig = builtins.concatStringsSep "\n" (map luaRequire [
"init"
"lspconfig"
"nvim-cmp"
"theming"
"treesitter"
"treesitter-textobjects"
"utils"
"which-key"
]);
in ''
lua << 
${luaConfig}

'';
};
}

View file

@ -0,0 +1,44 @@
{
inputs,
withSystem,
module_args,
...
}: let
sharedModules = [
../.
../shell
module_args
];
homeImports = {
"mihai@io" =
[
./io
inputs.spicetify-nix.homeManagerModule
inputs.hyprland.homeManagerModules.default
]
++ sharedModules;
server = sharedModules ++ [./server];
};
inherit (inputs.hm.lib) homeManagerConfiguration;
in {
imports = [
{_module.args = {inherit homeImports;};}
];
flake = {
homeConfigurations = withSystem "x86_64-linux" ({pkgs, ...}: {
"mihai@io" = homeManagerConfiguration {
modules = homeImports."mihai@io" ++ module_args;
inherit pkgs;
};
server = homeManagerConfiguration {
modules = homeImports.server ++ module_args;
inherit pkgs;
};
});
homeManagerModules.eww-hyprland = import ./programs/eww;
};
}

View file

@ -0,0 +1,73 @@
{
imports = [
../../editors/helix
../../editors/neovim
../../programs
../../programs/games.nix
../../programs/dunst.nix
../../wayland
../../terminals/alacritty.nix
../../terminals/wezterm.nix
];
services = {
kanshi = {
# use 1.6 scaling: 2560 : 1.6 = 1600, exact division. good for offsets
# restart eww every time because it won't expand/contract automatically
enable = true;
profiles = {
undocked = {
outputs = [
{
criteria = "eDP-1";
position = "0,0";
}
];
};
docked-all = {
outputs = [
{
criteria = "eDP-1";
position = "1366,0";
}
{
criteria = "DP-1";
position = "0,0";
}
{
criteria = "DP-2";
position = "1600,0";
}
];
};
docked1 = {
outputs = [
{
criteria = "eDP-1";
position = "1366,0";
}
{
criteria = "DP-1";
position = "0,0";
}
];
};
docked2 = {
outputs = [
{
criteria = "eDP-1";
position = "1366,0";
}
{
criteria = "DP-2";
position = "0,0";
}
];
};
};
systemdTarget = "graphical-session.target";
};
};
}

View file

@ -0,0 +1,3 @@
{
programs.helix.enable = true;
}

View file

@ -0,0 +1,13 @@
{pkgs, ...}: {
# use Cinny Matrix client
# create systemd service that serves it on localhost:9999
systemd.user.services.cinny = {
Unit.Description = "Cinny Service";
Service = {
Type = "simple";
ExecStart = "${pkgs.darkhttpd}/bin/darkhttpd ${pkgs.cinny} --addr 127.0.0.1 --port 9999";
TimeoutStopSec = 5;
};
Install.WantedBy = ["default.target"];
};
}

View file

@ -0,0 +1,57 @@
{
pkgs,
config,
...
}: {
imports = [
../shell/nix.nix
./cinny.nix
./files
./media.nix
./git.nix
./gtk.nix
./packages.nix
./qt.nix
./spicetify.nix
./xdg.nix
./zathura.nix
];
programs = {
chromium = {
enable = true;
commandLineArgs = ["--enable-features=TouchpadOverscrollHistoryNavigation"];
extensions = [
{id = "cjpalhdlnbpafiamejdnhcphjbkeiagm";}
{id = "bkkmolkhemgaeaeggcmfbghljjjoofoh";}
];
};
firefox = {
enable = true;
profiles.mihai = {};
};
gpg = {
enable = true;
homedir = "${config.xdg.dataHome}/gnupg";
};
password-store = {
enable = true;
package = pkgs.pass.withExtensions (exts: [exts.pass-otp]);
settings.PASSWORD_STORE_DIR = "${config.xdg.dataHome}/password-store";
};
};
services = {
gpg-agent = {
enable = true;
enableSshSupport = true;
pinentryFlavor = "gnome3";
sshKeys = ["73D1C4271E8C508E1E55259660C94BE828B07738"];
};
syncthing.enable = true;
};
}

View file

@ -0,0 +1,58 @@
{
pkgs,
default,
...
}: {
# notification daemon
services.dunst = {
enable = true;
iconTheme = {
name = "Papirus-Dark";
package = pkgs.papirus-icon-theme;
};
settings = {
global = {
alignment = "center";
corner_radius = 16;
follow = "mouse";
font = "Roboto 10";
format = "<b>%s</b>\\n%b";
frame_width = 1;
offset = "5x5";
horizontal_padding = 8;
icon_position = "left";
indicate_hidden = "yes";
markup = "yes";
max_icon_size = 64;
mouse_left_click = "do_action";
mouse_middle_click = "close_all";
mouse_right_click = "close_current";
padding = 8;
plain_text = "no";
separator_color = "auto";
separator_height = 1;
show_indicators = false;
shrink = "no";
word_wrap = "yes";
};
fullscreen_delay_everything = {fullscreen = "delay";};
urgency_critical = {
background = default.xcolors.bg;
foreground = default.xcolors.fg;
frame_color = default.xcolors.red;
};
urgency_low = {
background = default.xcolors.bg;
foreground = default.xcolors.fg;
frame_color = default.xcolors.blue;
};
urgency_normal = {
background = default.xcolors.bg;
foreground = default.xcolors.fg;
frame_color = default.xcolors.green;
};
};
};
}

View file

@ -0,0 +1,68 @@
# Eww configuration
This configuration aims to provide a fully working shell replacement for
compositors/window managers. Features constantly get added and existing ones
get improved.
## 🗃️ Components
The same daemon runs multiple windows which interact with each other:
### bar
![bar](https://user-images.githubusercontent.com/36706276/216402839-0f8ec9b0-dc4b-4cb8-9834-db59b61db97f.png)
### music window
![music](https://user-images.githubusercontent.com/36706276/192146077-f8da4691-9a0c-487f-9805-3fd4d55551e9.gif)
### calendar
![calendar](https://user-images.githubusercontent.com/36706276/204923748-f5c7db3a-5000-40cf-ba41-cd2d5f14146a.png)
### system info
![system](https://user-images.githubusercontent.com/36706276/216403137-a3231c60-976a-4e5d-85c0-899679ab0a92.png)
## ❔ Usage
### Home Manager
If you use Home Manager, installing is as simple as adding my flake to your
inputs, passing `inputs` to `extraSpecialArgs` and importing the relevant
module:
```nix
{inputs, ...}: {
imports = [inputs.fufexan.homeManagerModules.eww-hyprland];
programs.eww-hyprland = {
enable = true;
# default package
package = pkgs.eww-wayland;
# if you want to change colors
colors = builtins.readFile ./macchiato.scss;
# set to true to reload on change
autoReload = false;
};
}
```
Make sure to also add the fonts listed below.
### Other distros
To quickly install this config, grab all the files in this directory and put
them in `~/.config/eww`. Then run `eww daemon` and `eww open bar`. Enjoy!
Dependencies:
- Icon fonts: `material-symbols-outline` (any variation can be used as long as you change the `font-family` property of `.icon`)
- Text font: [Jost](https://fonts.google.com/specimen/Jost)
- Script deps: everything in `default.nix`'s `dependencies` list.
## 🎨 Theme
The theme colors can be changed in `css/_colors.scss`. Currently the theme used
is [Catppuccin Mocha](https://github.com/catppuccin/catppuccin).

View file

@ -0,0 +1,31 @@
.calendar-win {
@include window;
background-color: $bg;
color: $fg;
padding: .2em;
}
calendar {
padding: 5px;
:selected {
color: $magenta;
}
.header {
color: $black;
}
.highlight {
color: $red;
font-weight: bold;
}
.button {
color: $blue;
}
:indeterminate {
color: $green;
}
}

View file

@ -0,0 +1,35 @@
$rosewater: #f5e0dc;
$flamingo: #f2cdcd;
$pink: #f5c2e7;
$mauve: #cba6f7;
$red: #f38ba8;
$maroon: #eba0ac;
$peach: #fab387;
$yellow: #f9e2af;
$green: #a6e3a1;
$teal: #94e2d5;
$sky: #89dceb;
$sapphire: #74c7ec;
$blue: #89b4fa;
$lavender: #b4befe;
$text: #cdd6f4;
$subtext1: #bac2de;
$subtext0: #a6adc8;
$overlay2: #9399b2;
$overlay1: #7f849c;
$overlay0: #6c7086;
$surface2: #585b70;
$surface1: #45475a;
$surface0: #313244;
$base: #1e1e2e;
$mantle: #181825;
$crust: #11111b;
$fg: $text;
$bg: rgba(30, 30, 46, 0.6);
$bg1: rgba(49, 50, 68, 0.6);
$border: #28283d;
$shadow: $crust;

View file

@ -0,0 +1,66 @@
.song-cover-art {
@include rounding;
background-position: center;
background-size: cover;
margin: 4px 5px 4px 0;
min-height: 24px;
min-width: 24px;
}
.music-window {
@include window;
background-color: $bg;
border: 1px solid $border;
color: $fg;
}
.music-cover-art {
background-position: center;
background-size: cover;
border-radius: 8px;
margin: 1em;
min-height: 170px;
min-width: 170px;
}
.music-box {
margin: 1rem 1rem 1rem 0;
}
.music-title {
font-size: 1.1rem;
font-weight: bold;
}
.music-artist {
color: $white_a;
}
.music-button label {
color: $white_a;
font-size: 2rem;
}
.music-time {
color: $white_a;
margin: 0 1rem;
}
.music-bar scale {
highlight {
background-image: linear-gradient(to right, $cyan, $blue_a);
border-radius: 24px;
}
trough {
background-color: $bg1;
border-radius: 24px;
margin-top: 0;
min-height: 10px;
min-width: 170px;
}
}
.playctl {
color: $yellow;
}

View file

@ -0,0 +1,36 @@
.osd-part {
@include window;
background: $bg;
margin: 0 .5rem .5rem;
label {
color: $text;
font-size: 2rem;
margin: 0 .1rem 0 .2rem;
}
scale {
margin: -.2rem 0;
}
trough {
@include rounding;
background-color: $bg1;
margin: 1rem 0 .5rem;
min-height: 10rem;
min-width: .7rem;
highlight {
@include rounding;
min-width: 0;
}
}
}
.osd-volume highlight {
background-image: linear-gradient(to top, $cyan, $blue_a);
}
.osd-brightness highlight {
background-image: linear-gradient(to top, $yellow, $yellow_a);
}

View file

@ -0,0 +1,127 @@
.system-menu-box {
@include window;
background-color: $bg;
color: $text;
}
.separator {
font-size: 1rem;
}
.top-row {
margin: 1rem 1.5rem 0;
.time { font-size: 2rem; }
.date-box {
margin: 0 1rem;
label { font-size: 1.1rem; }
.date {
background: unset;
margin: 0 .5rem 0 0;
padding: 0;
}
}
}
.system-row {
margin: .5rem .7rem;
.airplane-box button {
padding: 1rem 3rem;
}
label {
font-size: 1rem;
margin: 0 .1rem;
}
}
.element {
@include rounding;
background-color: $black;
margin: .3rem;
button {
@include rounding;
padding: 1rem;
label {
font-size: 1.5rem;
}
&:hover {
background-color: $cyan_a;
}
}
}
.sliders {
@include rounding;
background-color: $black;
margin: .5rem 1rem;
padding: .6rem 1rem;
scale {
margin-right: -1rem;
min-width: 21.5rem;
trough { margin-right: 0; }
}
box { margin: .2rem 0; }
label { font-size: 1.2rem; }
}
.volume-slider-box,
.brightness-slider-box {
trough { background-color: $base; }
}
.volume-bar highlight {
@include rounding;
background-image: linear-gradient(to right, $cyan, $blue_a);
}
.brightness-slider-box scale highlight {
@include rounding;
background-image: linear-gradient(to right, $yellow, $yellow_a);
}
.bottom-row {
margin: .5rem 1rem;
.battery-icon { font-size: 2rem; }
.battery-wattage { color: $magenta; }
.battery-status {
color: $green;
margin: 0 .5rem;
}
button {
background-color: $black;
border-radius: 50%;
margin-bottom: .1rem;
padding: 0 .5rem;
label { font-size: 1.5rem; }
&:hover { background-color: $black_a; }
}
}
.bt-connected {
background-color: $blue;
color: $red;
button:hover { background-color: rgba(0, 0, 0, .1); }
}
.wifi-connected {
background-color: $magenta;
color: $red;
button:hover { background-color: rgba(0, 0, 0, .1); }
}

View file

@ -0,0 +1,80 @@
* {
transition: 1s;
}
.membar {
color: $yellow;
}
.cpubar {
color: $blue;
}
.batbar {
color: $green;
}
.membar,
.cpubar,
.batbar {
background-color: $bg1;
}
.iconmem {
color: $yellow;
}
.iconcpu {
color: $blue;
}
.icon-text {
font-size: 3rem;
padding: .7rem;
}
.sys-text-sub {
color: $text;
}
.sys-text-mem,
.sys-text-cpu {
font-size: 1rem;
font-weight: bold;
}
.sys-icon-mem,
.sys-icon-cpu {
font-size: 1.5rem;
margin: 1.5rem;
}
.system-info-box {
@include rounding;
background-color: $black;
margin: .5rem 1rem;
padding: .5rem;
}
.sys-mem,
.sys-cpu {
background-color: $bg;
}
.sys-icon-mem,
.sys-text-mem,
.sys-mem {
color: $yellow;
}
.sys-icon-cpu,
.sys-text-cpu,
.sys-cpu {
color: $blue;
}
.sys-box {
margin: .3em;
box { margin-left: 1rem; }
}

View file

@ -0,0 +1,5 @@
.vol-icon { color: $green; }
.volbar highlight {
background-image: linear-gradient(to right, $cyan, $blue_a);
border-radius: 10px;
}

View file

@ -0,0 +1,128 @@
{
config,
pkgs,
lib,
...
}: let
dependencies = with pkgs; [
config.wayland.windowManager.hyprland.package
cfg.package
bash
bc
blueberry
bluez
coreutils
dbus
dunst
findutils
gawk
gnome.gnome-control-center
gnused
gojq
imagemagick
jaq
light
networkmanager
pavucontrol
playerctl
procps
pulseaudio
ripgrep
socat
udev
upower
util-linux
wget
wireplumber
wlogout
socat
fuzzel
swaynotificationcenter
];
reload_script = pkgs.writeShellScript "reload_eww" ''
windows=$(eww windows | rg '\*' | tr -d '*')
systemctl --user restart eww.service
echo $windows | while read -r w; do
eww open $w
done
'';
cfg = config.programs.eww-hyprland;
in {
options.programs.eww-hyprland = {
enable = lib.mkEnableOption "eww Hyprland config";
package = lib.mkOption {
type = with lib.types; nullOr package;
default = pkgs.eww-wayland;
defaultText = lib.literalExpression "pkgs.eww-wayland";
description = "Eww package to use.";
};
autoReload = lib.mkOption {
type = lib.types.bool;
default = false;
defaultText = lib.literalExpression "false";
description = "Whether to restart the eww daemon and windows on change.";
};
colors = lib.mkOption {
type = with lib.types; nullOr lines;
default = null;
defaultText = lib.literalExpression "null";
description = ''
SCSS file with colors defined in the same way as Catppuccin colors are,
to be used by eww.
Defaults to Catppuccin Mocha.
'';
};
};
config = lib.mkIf cfg.enable {
home.packages = [cfg.package];
# remove nix files
xdg.configFile."eww" = {
source = lib.cleanSourceWith {
filter = name: _type: let
baseName = baseNameOf (toString name);
in
!(lib.hasSuffix ".nix" baseName) && !(baseName == "_colors.scss");
src = lib.cleanSource ./.;
};
# links each file individually, which lets us insert the colors file separately
recursive = true;
onChange =
if cfg.autoReload
then reload_script.outPath
else "";
};
# colors file
xdg.configFile."eww/css/_colors.scss".text =
if cfg.colors != null
then cfg.colors
else (builtins.readFile ./css/_colors.scss);
systemd.user.services.eww = {
Unit = {
Description = "Eww Daemon";
# not yet implemented
# PartOf = ["tray.target"];
PartOf = ["graphical-session.target"];
};
Service = {
Environment = "PATH=/run/wrappers/bin:${lib.makeBinPath dependencies}";
ExecStart = "${cfg.package}/bin/eww daemon --no-daemonize";
Restart = "on-failure";
};
Install.WantedBy = ["graphical-session.target"];
};
};
}

View file

@ -0,0 +1,93 @@
@import 'css/colors';
@mixin rounding {
border-radius: 16px;
}
@mixin window {
border: 1px solid $border;
box-shadow: 0 2px 3px $shadow;
margin: 5px 5px 0px;
@include rounding;
}
* {
all: unset;
font-family: "Montreux Classic", "Jost *", Roboto, sans-serif;
transition: 200ms ease;
}
@import 'css/calendar';
@import 'css/music';
@import 'css/osd';
@import 'css/sidebar';
@import 'css/system';
@import 'css/volume';
.bar {
color: $fg;
label {
font-size: 1.4rem;
}
}
.vis {
background-color: $bg;
border-radius: 24px;
padding: 4px 24px;
margin-top: 12px;
margin-bottom: 0px;
border: 3px solid $outline;
}
.invis {
background-color: rgba(0, 0, 0, 0);
}
tooltip {
background: $bg;
border: 1px solid $border;
border-radius: 8px;
label {
font-size: 1rem;
}
}
.icon,
.icon label { font-family: Material Symbols Outlined; }
.module { margin: 0 5px; }
.hour {
padding-left: 5px;
}
.minute {
padding-right: .7rem;
}
.date {
background: $bg;
color: $yellow;
label {
font-size: 1.2rem;
}
}
.bright-icon { color: $yellow_a; }
.module-bt { font-size: 1.2rem; }
scale trough {
background-color: $bg;
border-radius: 24px;
margin: 0 1rem;
min-height: 10px;
min-width: 70px;
}
.workspaces {
margin-left: 10px;
button { transition: color 2s ease; }
}

View file

@ -0,0 +1,56 @@
(include "./modules/clock.yuck")
(include "./modules/music.yuck")
(include "./modules/net.yuck")
(include "./modules/sys.yuck")
(include "./modules/variables.yuck")
(include "./modules/volume.yuck")
(include "./modules/workspaces.yuck")
(include "./modules/current_win.yuck")
(include "./windows/calendar.yuck")
(include "./windows/music.yuck")
(include "./windows/osd.yuck")
(include "./windows/system-menu.yuck")
(defwidget left []
(box
:space-evenly false
:halign "start"
:class "vis"
(workspaces)))
(defwidget right []
(box
:space-evenly false
:halign "end"
:class "vis bar"
(music-module)
(volume-module)
(net)
(sys)
(clock_module)))
(defwidget center []
(box
:space-evenly false
:halign "center"
:class "vis bar"
(current-win-module)))
(defwidget bar-box []
(centerbox
:class "invis bar"
(left)
(center)
(right)))
(defwindow bar
:monitor 0
:geometry (geometry :x "0%"
:y "0%"
:width "98%"
:height "24px"
:anchor "top center")
:stacking "fg"
:exclusive true
(bar-box))

View file

@ -0,0 +1,8 @@
(defwidget bluetooth []
(button
:class "module-bt module icon"
:onclick "blueberry"
:onrightclick "scripts/bluetooth toggle"
:tooltip "${bluetooth.text} ${bluetooth.battery}"
:style "color: ${bluetooth.color};"
{bluetooth.icon}))

View file

@ -0,0 +1,9 @@
(defwidget bright []
(box
:class "module"
(eventbox
:onscroll "echo {} | sed -e 's/up/-U 1/g' -e 's/down/-A 1/g' | xargs light"
(label
:text {brightness.icon}
:class "bright-icon icon"
:tooltip "brightness ${round(brightness.percent, 0)}%"))))

View file

@ -0,0 +1,24 @@
(defvar date_rev false)
(defwidget clock_module []
(eventbox
:onhover "${EWW_CMD} update date_rev=true"
:onhoverlost "${EWW_CMD} update date_rev=false"
(overlay
:class "module"
(box
:space-evenly false
(label
:text {time.hour}
:class "hour")
(label
:text ":")
(label
:text {time.minute}
:class "minute"))
(revealer
:reveal date_rev
(button
:class "date"
:onclick "${EWW_CMD} open --toggle calendar"
{time.date})))))

View file

@ -0,0 +1,8 @@
(defwidget current-win-module []
(box
(button
:class "module"
{current_win.title}
)
)
)

View file

@ -0,0 +1,28 @@
(defwidget music-module []
(eventbox
:onhover "${EWW_CMD} update music_reveal=true"
:onhoverlost "${EWW_CMD} update music_reveal=false"
(box
:class "module"
:space-evenly false
(box
:class "song-cover-art"
:style "background-image: url(\"${music.cover}\");")
(button
:class "module"
:onclick "${EWW_CMD} open --toggle music"
{music.status == "Stopped" || music.status == "" ? "" :
"${music.artist} - ${music.title}"})
(box
:class "icon"
{music.static == "Stopped" || music.status == "" ? "" : music.status == "Playing" ? "" : "" })
(revealer
:class "playctl"
:transition "slideright"
:reveal music_reveal
:duration "350ms"
(box
:class "icon"
(button :class "song-button" :onclick "playerctl previous" "")
(button :class "song-button" :onclick "playerctl play-pause" {music.status == "Playing" ? "" : ""})
(button :class "song-button" :onclick "playerctl next" ""))))))

View file

@ -0,0 +1,7 @@
(defwidget net []
(button
:class "module icon"
:onclick "gnome-control-center &"
:tooltip {net.essid}
:style "color: ${net.color};"
{net.icon}))

View file

@ -0,0 +1,32 @@
(defwidget sys []
(box
:class "module"
:space-evenly false
:spacing 5
(circular-progress
:value "${EWW_CPU.avg}"
:class "cpubar"
:thickness 3
(button
:tooltip "using ${round(EWW_CPU.avg,0)}% cpu"
:onclick "${EWW_CMD} open --toggle system-menu"
(label :class "icon-text" :text "")))
(circular-progress
:value {memory.percent}
:class "membar"
:thickness 3
(button
:tooltip "using ${round(memory.percent,0)}% ram"
:onclick "${EWW_CMD} open --toggle system-menu"
(label :class "icon-text" :text "")))
(circular-progress
:value "${EWW_BATTERY["BAT0"].capacity}"
:class "batbar"
:style "color: ${battery.color};"
:thickness 3
(button
:tooltip "battery on ${EWW_BATTERY["BAT0"].capacity}%"
:onclick "${EWW_CMD} open --toggle system-menu"
(label :class "icon-text" :text "")))))

View file

@ -0,0 +1,21 @@
(defvar bright_reveal false)
(defvar bt_rev false)
(defvar music_reveal false)
(defvar net_rev false)
(defvar time_rev false)
(defvar vol_reveal false)
(defvar osd-brightness false)
(defvar osd-volume false)
(defpoll time :interval "5s" `date +'{"date": "%d/%m", "hour": "%H", "minute": "%M", "day": "%A"}'`)
(deflisten airplane "scripts/airplane")
(deflisten battery "scripts/battery")
(deflisten bluetooth "scripts/bluetooth")
(deflisten brightness "scripts/brightness")
(deflisten memory "scripts/memory")
(deflisten music "scripts/music")
(deflisten net "scripts/net")
(deflisten volume "scripts/volume")
(deflisten workspace "scripts/workspaces")
(deflisten current_win "scripts/current_win")

View file

@ -0,0 +1,11 @@
(defwidget volume-module []
(box
:class "module icon"
(eventbox
:onscroll "echo {} | sed -e 's/up/-/g' -e 's/down/+/g' | xargs -I% wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.005%"
:onclick "pavucontrol &"
:onrightclick "scripts/volume mute SINK"
(label
:class "vol-icon"
:tooltip "volume ${volume.percent}%"
:text {volume.icon}))))

View file

@ -0,0 +1,13 @@
(defwidget workspaces []
(eventbox
:onscroll "echo {} | sed -e \"s/up/-1/g\" -e \"s/down/+1/g\" | xargs hyprctl dispatch workspace"
(box
:class "module workspaces"
:spacing 5
(for ws in workspace
(button
:onclick "hyprctl dispatch workspace ${ws.number}"
:class "ws icon"
:style "color: ${ws.color};"
; :tooltip {ws.tooltip}
"●")))))

View file

@ -0,0 +1,29 @@
#!/bin/sh
icon() {
if [ "$STATUS" = "no" ]; then
echo ""
else
echo ""
fi
}
toggle() {
if [ "$STATUS" = "no" ]; then
rfkill block all
notify-send --urgency=normal -i airplane-mode-symbolic "Airplane Mode" "Airplane mode has been turned on!"
else
rfkill unblock all
notify-send --urgency=normal -i airplane-mode-disabled-symbolic "Airplane Mode" "Airplane mode has been turned off!"
fi
}
if [ "$1" = "toggle" ]; then
toggle
else
while true; do
STATUS="$(rfkill list | sed -n 2p | awk '{print $3}')"
icon
sleep 3;
done
fi

View file

@ -0,0 +1,65 @@
#!/usr/bin/env bash
icons=("" "" "" "" "" "" "" "")
num_icons=$(bc <<< "100 / ${#icons[@]}")
geticon() {
level=$(awk -v n="$CAPACITY" -v c="$num_icons" 'BEGIN{print int(n/c-1)}')
if [[ "$level" -lt 0 ]]; then
level=0
fi
echo "${icons[$level]}"
}
status() {
if [ "$STATE" = "Charging" ]; then
echo -n "charging"
if [ "$RATE" -gt 0 ]; then
echo ", $(gettime) left"
else
echo ""
fi
elif [ "$STATE" = "Discharging" ]; then
echo "$(gettime)h left"
else
echo "fully charged"
fi
}
color() {
if [ "$CAPACITY" -le 20 ]; then
echo '#f38ba8'
else
echo '#a6e3a1'
fi
}
wattage() {
microwatts=1000000
echo "$(bc -l <<< "scale=1; $RATE / $microwatts") W"
}
gettime() {
FULL=$(cat /sys/class/power_supply/BAT0/energy_full)
NOW=$(cat /sys/class/power_supply/BAT0/energy_now)
if [ "$RATE" -gt 0 ]; then
if [ "$STATE" = "Discharging" ]; then
EX="$NOW / $RATE"
else
EX="($FULL - $NOW) / $RATE"
fi
date -u -d@"$(bc -l <<< "$EX * 3600")" +%H:%M
fi
}
while true; do
RATE=$(cat /sys/class/power_supply/BAT0/power_now)
CAPACITY=$(cat /sys/class/power_supply/BAT0/capacity)
STATE=$(cat /sys/class/power_supply/BAT0/status)
echo '{ "icon": "'"$(geticon)"'", "percent": '"$CAPACITY"', "wattage": "'"$(wattage)"'", "status": "'"$(status)"'", "color": "'"$(color)"'" }'
sleep 3
done

View file

@ -0,0 +1,51 @@
#!/usr/bin/env bash
toggle() {
status=$(rfkill -J | jaq -r '.rfkilldevices[] | select(.type == "bluetooth") | .soft' | head -1)
if [ "$status" = "unblocked" ]; then
rfkill block bluetooth
else
rfkill unblock bluetooth
fi
}
if [ "$1" = "toggle" ]; then
toggle
else
while true; do
powered=$(bluetoothctl show | rg Powered | cut -f 2- -d ' ')
status=$(bluetoothctl info)
name=$(echo "$status" | rg Name | cut -f 2- -d ' ')
mac=$(echo "$status" | head -1 | awk '{print $2}' | tr ':' '_')
if [[ "$(echo "$status" | rg Percentage)" != "" ]]; then
battery="$(upower -i /org/freedesktop/UPower/devices/headset_dev_"$mac" | rg percentage | awk '{print $2}' | cut -f 1 -d '%')%"
else
battery=""
fi
if [ "$powered" = "yes" ]; then
if [ "$status" != "Missing device address argument" ]; then
text="$name"
icon=""
color="#89b4fa"
class="bt-connected"
else
icon=""
text="Disconnected"
color="#45475a"
class=""
fi
else
icon=""
text="Bluetooth off"
color="#45475a"
class=""
fi
echo '{ "icon": "'"$icon"'", "battery": "'"$battery"'", "text": "'"$text"'", "color": "'"$color"'", "class": "'"$class"'" }'
sleep 3
done
fi

View file

@ -0,0 +1,61 @@
#!/usr/bin/env bash
icons=("" "" "")
if [ ! "$XDG_CACHE_HOME" ]; then
XDG_CACHE_HOME="/home/mihai/.local/cache"
fi
date="$XDG_CACHE_HOME/eww/osd_brightness.date"
osd() {
if [ ! -f "$date" ]; then
mkdir -p "$XDG_CACHE_HOME/eww"
fi
date +%s > "$date"
}
osd_handler() {
lock=0
rundate=0
if [ ! -f "$date" ]; then
mkdir -p "$XDG_CACHE_HOME/eww"
echo 0 > "$date"
fi
while true; do
# get dates
rundate=$(cat "$date")
currentdate=$(date +%s)
# handle showing
if [ "$rundate" = "$currentdate" ] && [ "$lock" -eq 0 ]; then
eww open osd
eww update osd-brightness=true
lock=1
elif [ "$((currentdate - rundate))" = "2" ] && [ "$lock" -eq 1 ]; then
eww update osd-brightness=false
lock=0
if [ "$(eww get osd-brightness)" = "false" ] && [ "$(eww get osd-volume)" = "false" ]; then
eww close osd
fi
fi
sleep 0.1
done
eww close osd
}
if [ "$1" = "osd" ]; then
osd
else
osd_handler &
# initial
icon=${icons[$(awk -v n="$(light)" 'BEGIN{print int(n/34)}')]}
echo '{ "percent": '"$(light)"', "icon": "'"$icon"'" }'
udevadm monitor | rg --line-buffered "backlight" | while read -r _; do
icon="${icons[$(awk -v n="$(light)" 'BEGIN{print int(n/34)}')]}"
echo '{ "percent": '"$(light)"', "icon": "'"$icon"'" }'
done
fi

View file

@ -0,0 +1,10 @@
#!/usr/bin/env bash
socat -u UNIX-CLIENT:/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock STDOUT |
while read line; do
if [[ "$line" == activewindow\>\>* ]]; then
windowtitle="$(echo $line | cut -d',' -f 2)"
echo '{"title": "'$windowtitle'"}'
fi
done

View file

@ -0,0 +1,20 @@
#!/usr/bin/env bash
while true; do
# human-readable
freeH=$(free -h --si | rg "Mem:")
# non-human-readable
freeN=$(free --mega | rg "Mem:")
total="$(echo "$freeH" | awk '{ print $2 }')"
used="$(echo "$freeH" | awk '{ print $3 }')"
t="$(echo "$freeN" | awk '{ print $2 }')"
u="$(echo "$freeN" | awk '{ print $3 }')"
free=$(printf '%.1fG' "$(bc -l <<< "($t - $u) / 1000")")
perc=$(printf '%.1f' "$(free -m | rg Mem | awk '{print ($3/$2)*100}')")
echo '{ "total": "'"$total"'", "used": "'"$used"'", "free": "'"$free"'", "percent": '"$perc"' }'
sleep 3
done

View file

@ -0,0 +1,111 @@
#!/usr/bin/env bash
get_status() {
s=$1
if [ "$s" = "Playing" ]; then
echo ""
else
echo ""
fi
}
get_length_sec() {
len=$1
if [ -z "$len" ]; then
echo 0
else
bc <<<"$len / 1000000"
fi
}
get_length_time() {
len=$1
if [ -n "$len" ]; then
len=$(bc <<<"$len / 1000000 + 1")
date -d@"$len" +%M:%S
else
echo ""
fi
}
get_position() {
pos=$1
len=$2
if [ -n "$pos" ]; then
bc -l <<<"$pos / $len * 100"
else
echo 0
fi
}
get_position_time() {
pos=$1
len=$2
if [ -n "$pos" ]; then
date -d@"$(bc <<<"$pos / 1000000")" +%M:%S
else
echo ""
fi
}
get_cover() {
mkdir -p "$XDG_CACHE_HOME/eww_covers"
cd "$XDG_CACHE_HOME/eww_covers" || exit
IMGPATH="$XDG_CACHE_HOME/eww_covers/cover_art.png"
COVER_URL="$1"
if [[ "$COVER_URL" = https* ]]; then
if [ ! -e "$XDG_CACHE_HOME/eww_covers/$(basename "$COVER_URL")" ]; then
wget -N "$COVER_URL" -o /dev/null
fi
rm "$IMGPATH"
ln -s "$(basename "$COVER_URL")" "$IMGPATH"
IMG="${IMGPATH}"
elif [ "$COVER_URL" = "" ]; then
IMG=""
else
IMG="$COVER_URL"
fi
echo "$IMG"
}
sanitize() {
echo "$1" | sed 's/"/\"/g'
}
prevCover=''
playerctl -F metadata -f '{{title}}\{{artist}}\{{status}}\{{position}}\{{mpris:length}}\{{mpris:artUrl}}' 2>/dev/null | while IFS="$(printf '\')" read -r title artist status position len cover; do
if [[ "$cover" != "$prevCover" ]]; then
COVER=$(get_cover "$cover")
if [ "$COVER" != "" ]; then
cols=$(convert "$COVER" -colors 2 -format "%c" histogram:info: | awk '{print $3}')
color1=$(echo "$cols" | head -1)
color1=$(printf "rgba(%d, %d, %d, 0.6)" ${color1:1:2} ${color1:3:2} ${color1:5:2})
color2=$(echo "$cols" | tail -1)
else
color1="#1e1e2e"
color2="#28283d"
fi
fi
jaq --null-input -r -c \
--arg artist "$(sanitize "$artist")" \
--arg title "$(sanitize "$title")" \
--arg status "$status" \
--arg pos "$(get_position "$position" "$len")" \
--arg pos_time "$(get_position_time "$position" "$len")" \
--arg length "$(get_length_time "$len")" \
--arg cover "$COVER" \
--arg color1 "$color1" \
--arg color2 "$color2" \
'{"artist": $artist, "title": $title, "status": $status, "position": $pos, "position_time": $pos_time, "length": $length, "cover": $cover, "color1": $color1, "color2": $color2}'
prevCover=$cover
done

View file

@ -0,0 +1,43 @@
#!/usr/bin/env bash
toggle() {
status=$(rfkill -J | jaq -r '.rfkilldevices[] | select(.type == "wlan") | .soft' | head -1)
if [ "$status" = "unblocked" ]; then
rfkill block wlan
else
rfkill unblock wlan
fi
}
if [ "$1" = "toggle" ]; then
toggle
else
while true; do
status=$(nmcli -f state g| tail -1)
wifistatus=$(nmcli -t -f in-use,ssid,signal dev wifi | rg '\*' | sed 's/\"/\\"/g')
signal=$(echo "$wifistatus" | awk -F: '{print $3}')
essid=$(echo "$wifistatus" | awk -F: '{print $2}')
icons=("" "" "" "" "")
if [ "$status" = "disconnected" ] ; then
icon=""
color="#988ba2"
class=""
else
level=$(awk -v n="$signal" 'BEGIN{print int((n-1)/20)}')
if [ "$level" -gt 4 ]; then
level=4
fi
icon=${icons[$level]}
color="#cba6f7"
class="wifi-connected"
fi
echo '{ "essid": "'"$essid"'", "icon": "'"$icon"'", "color": "'"$color"'", "class": "'"$class"'" }'
sleep 3
done
fi

View file

@ -0,0 +1,102 @@
#!/usr/bin/env bash
volicons=("" "" "")
if [ ! "$XDG_CACHE_HOME" ]; then
XDG_CACHE_HOME="/home/mihai/.local/cache"
fi
date="$XDG_CACHE_HOME/eww/osd_vol.date"
vol() {
wpctl get-volume @DEFAULT_AUDIO_"$1"@ | awk '{print int($2*100)}'
}
ismuted() {
wpctl get-volume @DEFAULT_AUDIO_"$1"@ | rg -i muted
echo $?
}
setvol() {
wpctl set-volume @DEFAULT_AUDIO_"$1"@ "$(awk -v n="$2" 'BEGIN{print (n / 100)}')"
}
setmute() {
wpctl set-mute @DEFAULT_AUDIO_"$1"@ toggle
}
osd() {
if [ ! -f "$date" ]; then
mkdir -p "$XDG_CACHE_HOME/eww"
fi
date +%s > "$date"
}
osd_handler() {
lock=0
rundate=0
if [ ! -f "$date" ]; then
mkdir -p "$XDG_CACHE_HOME/eww"
echo 0 > "$date"
fi
while true; do
# get dates
rundate=$(cat "$date")
currentdate=$(date +%s)
# handle showing
if [ "$rundate" = "$currentdate" ] && [ "$lock" -eq 0 ]; then
eww open osd
eww update osd-volume=true
lock=1
elif [ "$((currentdate - rundate))" = "2" ] && [ "$lock" -eq 1 ]; then
eww update osd-volume=false
lock=0
if [ "$(eww get osd-volume)" = "false" ] && [ "$(eww get osd-brightness)" = "false" ]; then
eww close osd
fi
fi
sleep 0.1
done
eww close osd
}
if [ "$1" = "mute" ]; then
if [ "$2" != "SOURCE" ] && [ "$2" != "SINK" ]; then
echo "Can only mute SINK or SOURCE"; exit 1
fi
setmute "$2"
elif [ "$1" = "setvol" ]; then
if [ "$2" != "SOURCE" ] && [ "$2" != "SINK" ]; then
echo "Can only set volume for SINK or SOURCE"; exit 1
elif [ "$3" -lt 1 ] || [ "$3" -gt 100 ]; then
echo "Volume must be between 1 and 100"; exit 1
fi
setvol "$2" "$3"
elif [ "$1" = "osd" ]; then
osd
else
# initial values
lvl=$(awk -v n="$(vol "SINK")" 'BEGIN{print int(n/34)}')
ismuted=$(ismuted "SINK")
if [ "$ismuted" = 1 ]; then
icon="${volicons[$lvl]}"
else
icon=""
fi
echo '{ "icon": "'"$icon"'", "percent": "'"$(vol "SINK")"'", "microphone": "'"$(vol "SOURCE")"'" }'
osd_handler &
# event loop
pactl subscribe | rg --line-buffered "change" | while read -r _; do
lvl=$(awk -v n="$(vol "SINK")" 'BEGIN{print int(n/34)}')
ismuted=$(ismuted "SINK")
if [ "$ismuted" = 1 ]; then
icon="${volicons[$lvl]}"
else
icon=""
fi
echo '{ "icon": "'"$icon"'", "percent": "'"$(vol "SINK")"'", "microphone": "'"$(vol "SOURCE")"'" }'
done
fi

View file

@ -0,0 +1,99 @@
#!/usr/bin/env bash
# define colors
# red peach green blue
colors=("#f38ba8" "#fab387" "#a6e3a1" "#89b4fa")
# pink yellow teal lavender
dimmed=("#f5c2e7" "#f9e2af" "#94e2d5" "#b4befe")
empty="#313244"
# get initial focused workspace
focusedws=$(hyprctl -j monitors | jaq -r '.[] | select(.focused == true) | .activeWorkspace.id')
declare -A o=([1]=0 [2]=0 [3]=0 [4]=0)
declare -A monitormap
declare -A workspaces
# set color for each workspace
status() {
if [ "${o[$1]}" -eq 1 ]; then
mon=${monitormap[${workspaces[$1]}]}
if [ "$focusedws" -eq "$1" ]; then
echo -n "#27ae60"
# echo -n "${colors[$mon]}"
else
# echo -n "${dimmed[$mon]}"
echo -n "#fdbc4b"
fi
else
# echo -n "$empty"
echo -n "#2f343f"
fi
}
# handle workspace create/destroy
workspace_event() {
o[$1]=$2
while read -r k v; do workspaces[$k]="$v"; done < <(hyprctl -j workspaces | gojq -r '.[]|"\(.id) \(.monitor)"')
}
# handle monitor (dis)connects
monitor_event() {
while read -r k v; do monitormap["$k"]=$v; done < <(hyprctl -j monitors | gojq -r '.[]|"\(.name) \(.id) "')
}
# get all apps titles in a workspace
applist() {
ws="$1"
apps=$(hyprctl -j clients | jaq -jr '.[] | select(.workspace.id == '"$ws"') | .title + "\\n"')
echo -En "${apps%"\n"}"
}
# generate the json for eww
generate() {
echo -n '['
for i in {1..4}; do
echo -n ''"$([ "$i" -eq 1 ] || echo ,)" '{ "number": "'"$i"'", "color": "'"$(status "$i")"'" }' #, "tooltip": "'$(applist "$i")'" }'
done
echo ']'
}
# setup
# add monitors
monitor_event
# add workspaces
while read -r k v; do workspaces[$k]="$v"; done < <(hyprctl -j workspaces | gojq -r '.[]|"\(.id) \(.monitor)"')
# check occupied workspaces
for num in "${!workspaces[@]}"; do
o[$num]=1
done
# generate initial widget
generate
# main loop
socat -u UNIX-CONNECT:/tmp/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock - | rg --line-buffered "workspace|mon(itor)?" | while read -r line; do
case ${line%>>*} in
"workspace")
focusedws=${line#*>>}
;;
"focusedmon")
focusedws=${line#*,}
;;
"createworkspace")
workspace_event "${line#*>>}" 1
;;
"destroyworkspace")
workspace_event "${line#*>>}" 0
;;
"monitor"*)
monitor_event
;;
esac
generate
done

View file

@ -0,0 +1,14 @@
(defwidget calendar-win []
(box
:class "calendar-win"
(calendar)))
(defwindow calendar
:monitor 0
:geometry (geometry
:x "0%"
:y "0%"
:anchor "top right"
:width "0px"
:height "0px")
(calendar-win))

View file

@ -0,0 +1,55 @@
(defwidget music []
(box
:class "music-window"
:space-evenly false
:style "background-color: ${music.color1}; border: 1px solid ${music.color2};"
(box
:class "music-cover-art"
:style "background-image: url(\"${music.cover}\");")
(box
:orientation "v"
:class "music-box"
(label
:class "music-title"
:wrap true
:text {music.title})
(label
:class "music-artist"
:wrap true
:text {music.artist})
(centerbox
:halign "center"
:class "music-button-box icon"
(button :class "music-button" :onclick "playerctl previous" "")
(button :class "music-button" :onclick "playerctl play-pause" {music.status})
(button :class "music-button" :onclick "playerctl next" ""))
(box
:orientation "v"
(box
(label
:xalign 0
:class "music-time"
:text {music.position_time})
(label
:xalign 1
:class "music-time"
:text {music.length}))
(box
:class "music-bar"
(scale
; doesn't work, looking for other ways
; :style "background: linear-gradient(to right, ${music.color1}, ${music.color2});"
:onchange "playerctl position `bc <<< \"{} * $(playerctl metadata mpris:length) / 1000000 / 100\"`"
:value {music.position}))))))
(defwindow music
:stacking "fg"
:focusable false
:monitor 0
:geometry (geometry
:x "0%"
:y "0%"
:width "0%"
:height "0%"
:anchor "top center")
(music))

View file

@ -0,0 +1,43 @@
(defwidget osd-part [icon value class]
(box
:class "osd-part osd-${class}"
:orientation "v"
:space-evenly false
(scale
:flipped true
:orientation "v"
:value value)
(label
:text icon)))
(defwidget osd []
(box
:class "osd-container"
:space-evenly false
(revealer
:reveal {osd-brightness}
:transition "slideright"
(osd-part
:class "brightness"
:icon {brightness.icon}
:value {brightness.percent}))
(revealer
:reveal {osd-volume}
:transition "slideright"
(osd-part
:class "volume"
:icon {volume.icon}
:value {volume.percent})))
)
(defwindow osd
:stacking "fg"
:focusable false
:monitor 0
:geometry (geometry
:x "1%"
:y "0%"
:width "0%"
:height "0%"
:anchor "center left")
(osd))

View file

@ -0,0 +1,204 @@
(defwidget system-menu []
(box
:class "system-menu-box"
:space-evenly false
:orientation "v"
(box
:class "top-row"
:space-evenly false
(label
:class "time"
:text "${time.hour}:${time.minute}")
(box
:class "date-box"
:space-evenly false
(label
:class "date"
:text {time.date})
(label
:class "day"
:text {time.day})))
(centerbox
:class "system-row"
(box
:class "wifi-box"
:space-evenly false
:orientation "v"
(box
:class "element icon ${net.class}"
:space-evenly false
(button
:class "wifi-button"
:onclick "scripts/net toggle"
{net.icon})
(label
:class "separator"
:text "│")
(button
:class "wifi-arrow-btn"
:onclick "eww close system-menu && gnome-control-center &"
""))
(label
:text {net.essid}
:xalign 0.5
:limit-width 15))
(box
:class "bluetooth-box"
:space-evenly false
:orientation "v"
(box
:class "element icon ${bluetooth.class}"
:space-evenly false
(button
:class "bluetooth-button"
:onclick "scripts/bluetooth toggle"
{bluetooth.icon})
(label
:class "separator"
:text "│")
(button
:class "bluetooth-arrow-btn"
:onclick "eww close system-menu && blueberry"
""))
(label
:text {bluetooth.text}
:xalign 0.5
:tooltip "${bluetooth.text} ${bluetooth.battery}"
:limit-width 15))
(box
:class "airplane-box"
:space-evenly false
:orientation "v"
(box
:class "element"
(button
:class "airplane-button"
:onclick "scripts/airplane toggle"
airplane))
(label
:text "Airplane Mode"
:xalign 0.5
:limit-width 16)))
(box
:class "sliders"
:orientation "v"
(box
:class "volume-slider-box"
:space-evenly false
(button
:class "volume-icon icon"
:onclick "scripts/volume mute SINK"
{volume.icon})
(scale
:class "volume-bar"
:value {volume.percent}
:tooltip "volume on ${volume.percent}%"
:onchange "scripts/volume setvol SINK {}"))
(box
:class "brightness-slider-box"
:space-evenly false
(button
:class "brightness-slider-icon icon"
{brightness.icon})
(scale
:class "brightness-slider"
:value {brightness.percent}
:marks true
:onchange "light -S {}")))
(box
:class "system-info-box"
; cpu
(box
:class "sys-box"
:space-evenly false
:halign "start"
(circular-progress
:value "${EWW_CPU.avg}"
:class "sys-cpu"
:thickness 3
(label
:text ""
:class "sys-icon-cpu icon"))
(box
:orientation "v"
:vexpand false
(label
:text "cpu"
:halign "start"
:class "sys-text-cpu")
(label
:text "${round(EWW_CPU.avg,2)}%"
:halign "start"
:class "sys-text-sub")
(label
:text "${EWW_CPU.cores[0].freq} MHz"
:halign "start"
:class "sys-text-sub")))
; memory
(box
:class "sys-box"
:space-evenly false
:halign "end"
(circular-progress
:value {memory.percent}
:class "sys-mem"
:thickness 3
(label
:text ""
:class "sys-icon-mem icon"))
(box
:orientation "v"
(label
:text "memory"
:halign "start"
:class "sys-text-mem")
(label
:text "${memory.used} | ${memory.total}"
:halign "start"
:class "sys-text-sub"))))
(centerbox
:class "bottom-row"
(box
:class "battery-box"
:space-evenly false
:halign "start"
(label
:class "battery-icon icon"
:style "color: ${battery.color}"
:text {battery.icon})
(label
:text {EWW_BATTERY["BAT0"].capacity})
(label
:class "battery-status"
:text {battery.status})
(label
:class "battery-wattage"
:text {battery.wattage}))
(label)
(box
:space-evenly false
:halign "end"
(button
:halign "end"
:class "power-button icon"
:onclick "wlogout -p layer-shell &"
"")))))
(defwindow system-menu
:stacking "fg"
:monitor 0
:geometry (geometry
:x "0"
:y "0"
:width "0%"
:height "0%"
:anchor "right top")
(system-menu))

View file

@ -0,0 +1,7 @@
width=40%
height=30%
show=drun
prompt=Search
allow_images=true
allow_markup=true
insensitive=true

View file

@ -0,0 +1,25 @@
# youtube-dl config file
# use .netrc for logins
-n
# ignore errors (unavailable videos, etc)
-i
# don't overwrite
-w
# make an archive of downloaded videos and only download unlisted items, then list them
# useful for music playlists you update often
--download-archive ~/Music/untagged/ignore.these
# convert all downloads to 192kbps mp3
-x
--audio-format mp3 #opus
--audio-quality 192K
# embed thumbnail into audio
#--embed-thumbnail
# save all music in the following folder and format
-o '~/Music/untagged/%(artist)s - %(title)s.%(ext)s'

View file

@ -0,0 +1,34 @@
{
pkgs,
lib,
config,
...
}:
# manage files in ~
{
imports = [
./nix-index-update-db.nix
./wlogout.nix
./wofi-style.nix
];
home.file.".config" = {
source = ./config;
recursive = true;
};
xdg.configFile = {
"btop/themes/catppuccin_mocha.theme".source = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/catppuccin/btop/main/catppuccin_mocha.theme";
hash = "sha256-MGK5ECB5sXiHdi2A3Y4s/Sx7nSRQ+KLyZjEKElRPKf0=";
};
"xilinx/nix.sh" = {
executable = true;
text = ''
INSTALL_DIR=$HOME/Documents/code/xilinx/tools/Xilinx
VERSION=2022.2
'';
};
};
}

View file

@ -0,0 +1,35 @@
{
pkgs,
lib,
...
}: {
# set up nix-index
systemd.user.timers.nix-index-db-update = {
Timer = {
OnCalendar = "weekly";
Persistent = true;
RandomizedDelaySec = 0;
};
};
systemd.user.services.nix-index-db-update = {
Unit = {
Description = "nix-index database update";
PartOf = ["multi-user.target"];
};
Service = let
script = pkgs.writeShellScript "nix-index-update-db" ''
export filename="index-x86_64-$(uname | tr A-Z a-z)"
mkdir -p ~/.cache/nix-index
cd ~/.cache/nix-index
# -N will only download a new version if there is an update.
wget -N https://github.com/Mic92/nix-index-database/releases/latest/download/$filename
ln -f $filename files
'';
in {
Environment = "PATH=/run/wrappers/bin:${lib.makeBinPath [pkgs.wget pkgs.coreutils]}";
ExecStart = "${script}";
};
Install.WantedBy = ["multi-user.target"];
};
}

View file

@ -0,0 +1,57 @@
{
default,
pkgs,
...
}: let
w = pkgs.wlogout;
in {
xdg.configFile."wlogout/style.css".text = ''
* {
background-image: none;
font-family: "Jost *", Roboto, sans-serif;
}
window {
background-color: rgba(12, 12, 12, 0.9);
}
button {
background: unset;
border-radius: 16px;
border: 1px solid #28283d;
color: ${default.xcolors.text};
margin: 1rem;
background-repeat: no-repeat;
background-position: center;
background-size: 25%;
}
button:focus, button:active, button:hover {
background-color: ${default.xcolors.blue};
color: ${default.xcolors.base};
outline-style: none;
}
#lock {
background-image: image(url("${w}/share/wlogout/icons/lock.png"), url("${w}/local/share/wlogout/icons/lock.png"));
}
#logout {
background-image: image(url("${w}/share/wlogout/icons/logout.png"), url("${w}/local/share/wlogout/icons/logout.png"));
}
#suspend {
background-image: image(url("${w}/share/wlogout/icons/suspend.png"), url("${w}/local/share/wlogout/icons/suspend.png"));
}
#hibernate {
background-image: image(url("${w}/share/wlogout/icons/hibernate.png"), url("${w}/local/share/wlogout/icons/hibernate.png"));
}
#shutdown {
background-image: image(url("${w}/share/wlogout/icons/shutdown.png"), url("${w}/local/share/wlogout/icons/shutdown.png"));
}
#reboot {
background-image: image(url("${w}/share/wlogout/icons/reboot.png"), url("${w}/local/share/wlogout/icons/reboot.png"));
}
'';
}

View file

@ -0,0 +1,46 @@
{default, ...}: {
xdg.configFile."wofi/style.css".text = ''
window { background: unset; }
flowboxchild { outline-width: 0; }
#outer-box {
background: ${default.xcolors.base};
border: 1px solid ${default.xcolors.border};
border-radius: 24px;
box-shadow: 0 2px 3px ${default.xcolors.crust};
margin: 5px 5px 10px;
padding: 5px 5px 10px;
}
#input {
background-color: ${default.xcolors.crust};
border: none;
border-radius: 16px;
color: ${default.xcolors.text};
margin: 5px;
}
#inner-box {
background-color: ${default.xcolors.base};
border: none;
border-radius: 16px;
margin: 5px;
}
#scroll {
border: none;
margin: 0px;
}
#text {
color: ${default.xcolors.text};
margin: 5px;
}
#entry { border-radius: 16px; }
#entry:selected {
background-color: ${default.xcolors.surface0};
}
'';
}

View file

@ -0,0 +1,12 @@
{
pkgs,
inputs,
...
}:
# games
{
home.packages = with pkgs; [
inputs.nix-gaming.packages.${pkgs.hostPlatform.system}.osu-lazer-bin
gamescope
];
}

View file

@ -0,0 +1,52 @@
{
pkgs,
default,
...
}: {
home.packages = [pkgs.gh];
programs.git = {
enable = true;
delta = {
enable = true;
options.map-styles = "bold purple => syntax ${default.xcolors.mauve}, bold cyan => syntax ${default.xcolors.blue}";
};
extraConfig = {
diff.colorMoved = "default";
merge.conflictstyle = "diff3";
};
aliases = {
a = "add";
b = "branch";
c = "commit";
ca = "commit --amend";
cm = "commit -m";
co = "checkout";
d = "diff";
ds = "diff --staged";
p = "push";
pf = "push --force-with-lease";
pl = "pull";
l = "log";
r = "rebase";
s = "status --short";
ss = "status";
forgor = "commit --amend --no-edit";
graph = "log --all --decorate --graph --oneline";
oops = "checkout --";
};
ignores = ["*~" "*.swp" "*result*" ".direnv" "node_modules"];
signing = {
key = "5899325F2F120900";
signByDefault = true;
};
userEmail = "fufexan@protonmail.com";
userName = "Mihai Fufezan";
};
}

View file

@ -0,0 +1,38 @@
{
pkgs,
config,
...
}: {
home.pointerCursor = {
package = pkgs.bibata-cursors;
name = "Bibata-Modern-Classic";
size = 24;
gtk.enable = true;
x11.enable = true;
};
gtk = {
enable = true;
font = {
name = "Roboto";
package = pkgs.roboto;
};
gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc";
iconTheme = {
name = "Papirus-Dark";
package = pkgs.papirus-icon-theme;
};
theme = {
name = "Catppuccin-Mocha-Compact-Mauve-Dark";
package = pkgs.catppuccin-gtk.override {
accents = ["mauve"];
size = "compact";
variant = "mocha";
};
};
};
}

View file

@ -0,0 +1,55 @@
{
pkgs,
config,
...
}:
# media - control and enjoy audio/video
{
imports = [
./spicetify.nix
];
home.packages = with pkgs; [
# audio control
pavucontrol
playerctl
pulsemixer
# images
imv
spotify-tui
];
programs = {
mpv = {
enable = true;
defaultProfiles = ["gpu-hq"];
scripts = [pkgs.mpvScripts.mpris];
};
obs-studio.enable = true;
};
services = {
playerctld.enable = true;
spotifyd = {
enable = true;
package = pkgs.spotifyd.override {withMpris = true;};
settings.global = {
autoplay = true;
backend = "pulseaudio";
bitrate = 320;
cache_path = "${config.xdg.cacheHome}/spotifyd";
device_type = "computer";
initial_volume = "100";
password_cmd = "tail -1 /run/agenix/spotify";
use_mpris = true;
username_cmd = "head -1 /run/agenix/spotify";
volume_normalisation = false;
};
};
udiskie.enable = true;
};
}

View file

@ -0,0 +1,33 @@
{
pkgs,
inputs,
...
}: {
home.packages = with pkgs; [
# archives
zip
unzip
unrar
# office
libreoffice
# messaging
tdesktop
# school stuff
inputs.nix-xilinx.packages.${pkgs.hostPlatform.system}.vivado
jetbrains.idea-community
# torrents
transmission-remote-gtk
# misc
libnotify
xdg-utils
# productivity
obsidian
xournalpp
];
}

View file

@ -0,0 +1,18 @@
{pkgs, ...}:
# Qt theming with Kvantum
{
home.packages = with pkgs; [
libsForQt5.qtstyleplugin-kvantum
(catppuccin-kvantum.override {
accent = "Mauve";
variant = "Mocha";
})
];
home.sessionVariables = {
QT_STYLE_OVERRIDE = "kvantum";
};
xdg.configFile."Kvantum/kvantum.kvconfig".source = (pkgs.formats.ini {}).generate "kvantum.kvconfig" {
General.Theme = "Catppuccin-Mocha-Mauve";
};
}

View file

@ -0,0 +1,24 @@
{
pkgs,
inputs,
...
}: {
# themable spotify
programs.spicetify = let
spicePkgs = inputs.spicetify-nix.packages.${pkgs.hostPlatform.system}.default;
in {
enable = true;
spotifyPackage = inputs.self.packages.${pkgs.hostPlatform.system}.spotify;
theme = spicePkgs.themes.catppuccin-mocha;
colorScheme = "flamingo";
enabledExtensions = with spicePkgs.extensions; [
fullAppDisplay
hidePodcasts
shuffle
];
};
}

View file

@ -0,0 +1,47 @@
{config, ...}: let
browser = ["firefox.desktop"];
# XDG MIME types
associations = {
"application/x-extension-htm" = browser;
"application/x-extension-html" = browser;
"application/x-extension-shtml" = browser;
"application/x-extension-xht" = browser;
"application/x-extension-xhtml" = browser;
"application/xhtml+xml" = browser;
"text/html" = browser;
"x-scheme-handler/about" = browser;
"x-scheme-handler/chrome" = ["chromium-browser.desktop"];
"x-scheme-handler/ftp" = browser;
"x-scheme-handler/http" = browser;
"x-scheme-handler/https" = browser;
"x-scheme-handler/unknown" = browser;
"audio/*" = ["mpv.desktop"];
"video/*" = ["mpv.dekstop"];
"image/*" = ["imv.desktop"];
"application/json" = browser;
"application/pdf" = ["org.pwmt.zathura.desktop.desktop"];
"x-scheme-handler/discord" = ["discordcanary.desktop"];
"x-scheme-handler/spotify" = ["spotify.desktop"];
"x-scheme-handler/tg" = ["telegramdesktop.desktop"];
};
in {
xdg = {
enable = true;
cacheHome = config.home.homeDirectory + "/.local/cache";
mimeApps = {
enable = true;
defaultApplications = associations;
};
userDirs = {
enable = true;
createDirectories = true;
extraConfig = {
XDG_SCREENSHOTS_DIR = "${config.xdg.userDirs.pictures}/Screenshots";
};
};
};
}

View file

@ -0,0 +1,27 @@
{pkgs, ...}: {
programs.zathura = {
enable = true;
options = {
recolor-lightcolor = "rgba(0,0,0,0)";
default-bg = "rgba(0,0,0,0.7)";
font = "Lexend 12";
selection-notification = true;
selection-clipboard = "clipboard";
adjust-open = "best-fit";
pages-per-row = "1";
scroll-page-aware = "true";
scroll-full-overlap = "0.01";
scroll-step = "100";
zoom-min = "10";
};
extraConfig = "include catppuccin-mocha";
};
xdg.configFile."zathura/catppuccin-mocha".source = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/catppuccin/zathura/main/src/catppuccin-mocha";
hash = "sha256-/HXecio3My2eXTpY7JoYiN9mnXsps4PAThDPs4OCsAk=";
};
}

View file

@ -0,0 +1,49 @@
{pkgs, ...}: {
home.packages = with pkgs; [
# archives
zip
unzip
unrar
# utils
file
du-dust
duf
fd
ripgrep
# file managers
joshuto
ranger
];
programs = {
bat = {
enable = true;
config = {
pager = "less -FR";
theme = "Catppuccin-mocha";
};
themes = {
Catppuccin-mocha = builtins.readFile (pkgs.fetchurl {
url = "https://raw.githubusercontent.com/catppuccin/bat/main/Catppuccin-mocha.tmTheme";
hash = "sha256-qMQNJGZImmjrqzy7IiEkY5IhvPAMZpq0W6skLLsng/w=";
});
};
};
btop.enable = true;
exa.enable = true;
ssh.enable = true;
skim = {
enable = true;
enableZshIntegration = true;
defaultCommand = "rg --files --hidden";
changeDirWidgetOptions = [
"--preview 'exa --icons --git --color always -T -L 3 {} | head -200'"
"--exact"
];
};
};
}

View file

@ -0,0 +1,28 @@
{config, ...}: let
d = config.xdg.dataHome;
c = config.xdg.configHome;
cache = config.xdg.cacheHome;
in {
imports = [
./cli.nix
./nushell
./starship.nix
./transient-services.nix
./zsh.nix
];
# add environment variables
home.sessionVariables = {
# clean up ~
LESSHISTFILE = cache + "/less/history";
LESSKEY = c + "/less/lesskey";
WINEPREFIX = d + "/wine";
XAUTHORITY = "$XDG_RUNTIME_DIR/Xauthority";
# enable scrolling in git diff
DELTA_PAGER = "less -R";
EDITOR = "hx";
MANPAGER = "sh -c 'col -bx | bat -l man -p'";
};
}

View file

@ -0,0 +1,21 @@
{
pkgs,
inputs,
...
}:
# nix tooling
{
home.packages = with pkgs; [
alejandra
deadnix
nix-index
statix
inputs.self.packages.${pkgs.hostPlatform.system}.repl
];
programs.direnv = {
enable = true;
nix-direnv.enable = true;
enableZshIntegration = true;
};
}

View file

@ -0,0 +1,514 @@
# Nushell Config File
module completions {
# Custom completions for external commands (those outside of Nushell)
# Each completions has two parts: the form of the external command, including its flags and parameters
# and a helper command that knows how to complete values for those flags and parameters
#
# This is a simplified version of completions for git branches and git remotes
def "nu-complete git branches" [] {
^git branch | lines | each { |line| $line | str replace '[\*\+] ' '' | str trim }
}
def "nu-complete git remotes" [] {
^git remote | lines | each { |line| $line | str trim }
}
# Download objects and refs from another repository
export extern "git fetch" [
repository?: string@"nu-complete git remotes" # name of the repository to fetch
branch?: string@"nu-complete git branches" # name of the branch to fetch
--all # Fetch all remotes
--append(-a) # Append ref names and object names to .git/FETCH_HEAD
--atomic # Use an atomic transaction to update local refs.
--depth: int # Limit fetching to n commits from the tip
--deepen: int # Limit fetching to n commits from the current shallow boundary
--shallow-since: string # Deepen or shorten the history by date
--shallow-exclude: string # Deepen or shorten the history by branch/tag
--unshallow # Fetch all available history
--update-shallow # Update .git/shallow to accept new refs
--negotiation-tip: string # Specify which commit/glob to report while fetching
--negotiate-only # Do not fetch, only print common ancestors
--dry-run # Show what would be done
--write-fetch-head # Write fetched refs in FETCH_HEAD (default)
--no-write-fetch-head # Do not write FETCH_HEAD
--force(-f) # Always update the local branch
--keep(-k) # Keep dowloaded pack
--multiple # Allow several arguments to be specified
--auto-maintenance # Run 'git maintenance run --auto' at the end (default)
--no-auto-maintenance # Don't run 'git maintenance' at the end
--auto-gc # Run 'git maintenance run --auto' at the end (default)
--no-auto-gc # Don't run 'git maintenance' at the end
--write-commit-graph # Write a commit-graph after fetching
--no-write-commit-graph # Don't write a commit-graph after fetching
--prefetch # Place all refs into the refs/prefetch/ namespace
--prune(-p) # Remove obsolete remote-tracking references
--prune-tags(-P) # Remove any local tags that do not exist on the remote
--no-tags(-n) # Disable automatic tag following
--refmap: string # Use this refspec to map the refs to remote-tracking branches
--tags(-t) # Fetch all tags
--recurse-submodules: string # Fetch new commits of populated submodules (yes/on-demand/no)
--jobs(-j): int # Number of parallel children
--no-recurse-submodules # Disable recursive fetching of submodules
--set-upstream # Add upstream (tracking) reference
--submodule-prefix: string # Prepend to paths printed in informative messages
--upload-pack: string # Non-default path for remote command
--quiet(-q) # Silence internally used git commands
--verbose(-v) # Be verbose
--progress # Report progress on stderr
--server-option(-o): string # Pass options for the server to handle
--show-forced-updates # Check if a branch is force-updated
--no-show-forced-updates # Don't check if a branch is force-updated
-4 # Use IPv4 addresses, ignore IPv6 addresses
-6 # Use IPv6 addresses, ignore IPv4 addresses
--help # Display this help message
]
# Check out git branches and files
export extern "git checkout" [
...targets: string@"nu-complete git branches" # name of the branch or files to checkout
--conflict: string # conflict style (merge or diff3)
--detach(-d) # detach HEAD at named commit
--force(-f) # force checkout (throw away local modifications)
--guess # second guess 'git checkout <no-such-branch>' (default)
--ignore-other-worktrees # do not check if another worktree is holding the given ref
--ignore-skip-worktree-bits # do not limit pathspecs to sparse entries only
--merge(-m) # perform a 3-way merge with the new branch
--orphan: string # new unparented branch
--ours(-2) # checkout our version for unmerged files
--overlay # use overlay mode (default)
--overwrite-ignore # update ignored files (default)
--patch(-p) # select hunks interactively
--pathspec-from-file: string # read pathspec from file
--progress # force progress reporting
--quiet(-q) # suppress progress reporting
--recurse-submodules: string # control recursive updating of submodules
--theirs(-3) # checkout their version for unmerged files
--track(-t) # set upstream info for new branch
-b: string # create and checkout a new branch
-B: string # create/reset and checkout a branch
-l # create reflog for new branch
--help # Display this help message
]
# Push changes
export extern "git push" [
remote?: string@"nu-complete git remotes", # the name of the remote
...refs: string@"nu-complete git branches" # the branch / refspec
--all # push all refs
--atomic # request atomic transaction on remote side
--delete(-d) # delete refs
--dry-run(-n) # dry run
--exec: string # receive pack program
--follow-tags # push missing but relevant tags
--force-with-lease # require old value of ref to be at this value
--force(-f) # force updates
--ipv4(-4) # use IPv4 addresses only
--ipv6(-6) # use IPv6 addresses only
--mirror # mirror all refs
--no-verify # bypass pre-push hook
--porcelain # machine-readable output
--progress # force progress reporting
--prune # prune locally removed refs
--push-option(-o): string # option to transmit
--quiet(-q) # be more quiet
--receive-pack: string # receive pack program
--recurse-submodules: string # control recursive pushing of submodules
--repo: string # repository
--set-upstream(-u) # set upstream for git pull/status
--signed: string # GPG sign the push
--tags # push tags (can't be used with --all or --mirror)
--thin # use thin pack
--verbose(-v) # be more verbose
--help # Display this help message
]
}
# Get just the extern definitions without the custom completion commands
use completions *
# for more information on themes see
# https://www.nushell.sh/book/coloring_and_theming.html
let dark_theme = {
# color for nushell primitives
separator: white
leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off
header: green_bold
empty: blue
bool: white
int: white
filesize: white
duration: white
date: white
range: white
float: white
string: white
nothing: white
binary: white
cellpath: white
row_index: green_bold
record: white
list: white
block: white
hints: dark_gray
# shapes are used to change the cli syntax highlighting
shape_garbage: { fg: "#FFFFFF" bg: "#FF0000" attr: b}
shape_binary: purple_bold
shape_bool: light_cyan
shape_int: purple_bold
shape_float: purple_bold
shape_range: yellow_bold
shape_internalcall: cyan_bold
shape_external: cyan
shape_externalarg: green_bold
shape_literal: blue
shape_operator: yellow
shape_signature: green_bold
shape_string: green
shape_string_interpolation: cyan_bold
shape_datetime: cyan_bold
shape_list: cyan_bold
shape_table: blue_bold
shape_record: cyan_bold
shape_block: blue_bold
shape_filepath: cyan
shape_globpattern: cyan_bold
shape_variable: purple
shape_flag: blue_bold
shape_custom: green
shape_nothing: light_cyan
}
let light_theme = {
# color for nushell primitives
separator: dark_gray
leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off
header: green_bold
empty: blue
bool: dark_gray
int: dark_gray
filesize: dark_gray
duration: dark_gray
date: dark_gray
range: dark_gray
float: dark_gray
string: dark_gray
nothing: dark_gray
binary: dark_gray
cellpath: dark_gray
row_index: green_bold
record: white
list: white
block: white
hints: dark_gray
# shapes are used to change the cli syntax highlighting
shape_garbage: { fg: "#FFFFFF" bg: "#FF0000" attr: b}
shape_binary: purple_bold
shape_bool: light_cyan
shape_int: purple_bold
shape_float: purple_bold
shape_range: yellow_bold
shape_internalcall: cyan_bold
shape_external: cyan
shape_externalarg: green_bold
shape_literal: blue
shape_operator: yellow
shape_signature: green_bold
shape_string: green
shape_string_interpolation: cyan_bold
shape_datetime: cyan_bold
shape_list: cyan_bold
shape_table: blue_bold
shape_record: cyan_bold
shape_block: blue_bold
shape_filepath: cyan
shape_globpattern: cyan_bold
shape_variable: purple
shape_flag: blue_bold
shape_custom: green
shape_nothing: light_cyan
}
# External completer example
# let carapace_completer = {|spans|
# carapace $spans.0 nushell $spans | from json
# }
# The default config record. This is where much of your global configuration is setup.
let-env config = {
external_completer: $nothing # check 'carapace_completer' above to as example
filesize_metric: false # true => (KB, MB, GB), false => (KiB, MiB, GiB)
table_mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other
use_ls_colors: true
rm_always_trash: false
color_config: $dark_theme # if you want a light theme, replace `$dark_theme` to `$light_theme`
use_grid_icons: true
footer_mode: "25" # always, never, number_of_rows, auto
quick_completions: true # set this to false to prevent auto-selecting completions when only one remains
partial_completions: true # set this to false to prevent partial filling of the prompt
completion_algorithm: "prefix" # prefix, fuzzy
float_precision: 2
# buffer_editor: "emacs" # command that will be used to edit the current line buffer with ctrl+o, if unset fallback to $env.EDITOR and $env.VISUAL
use_ansi_coloring: true
filesize_format: "auto" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib, auto
edit_mode: emacs # emacs, vi
max_history_size: 10000 # Session has to be reloaded for this to take effect
sync_history_on_enter: true # Enable to share the history between multiple sessions, else you have to close the session to persist history to file
history_file_format: "plaintext" # "sqlite" or "plaintext"
shell_integration: true # enables terminal markers and a workaround to arrow keys stop working issue
table_index_mode: always # "always" show indexes, "never" show indexes, "auto" = show indexes when a table has "index" column
cd_with_abbreviations: false # set to true to allow you to do things like cd s/o/f and nushell expand it to cd some/other/folder
case_sensitive_completions: false # set to true to enable case-sensitive completions
enable_external_completion: true # set to false to prevent nushell looking into $env.PATH to find more suggestions, `false` recommended for WSL users as this look up my be very slow
max_external_completion_results: 100 # setting it lower can improve completion performance at the cost of omitting some options
# A strategy of managing table view in case of limited space.
table_trim: {
methodology: wrapping, # truncating
# A strategy which will be used by 'wrapping' methodology
wrapping_try_keep_words: true,
# A suffix which will be used with 'truncating' methodology
# truncating_suffix: "..."
}
show_banner: false # true or false to enable or disable the banner
show_clickable_links_in_ls: true # true or false to enable or disable clickable links in the ls listing. your terminal has to support links.
hooks: {
pre_prompt: [{
$nothing # replace with source code to run before the prompt is shown
}]
pre_execution: [{
$nothing # replace with source code to run before the repl input is run
}]
env_change: {
PWD: [{|before, after|
$nothing # replace with source code to run if the PWD environment is different since the last repl input
}]
}
}
menus: [
# Configuration for default nushell menus
# Note the lack of souce parameter
{
name: completion_menu
only_buffer_difference: false
marker: "| "
type: {
layout: columnar
columns: 4
col_width: 20 # Optional value. If missing all the screen width is used to calculate column width
col_padding: 2
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
}
{
name: history_menu
only_buffer_difference: true
marker: "? "
type: {
layout: list
page_size: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
}
{
name: help_menu
only_buffer_difference: true
marker: "? "
type: {
layout: description
columns: 4
col_width: 20 # Optional value. If missing all the screen width is used to calculate column width
col_padding: 2
selection_rows: 4
description_rows: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
}
# Example of extra menus created using a nushell source
# Use the source field to create a list of records that populates
# the menu
{
name: commands_menu
only_buffer_difference: false
marker: "# "
type: {
layout: columnar
columns: 4
col_width: 20
col_padding: 2
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.commands
| where command =~ $buffer
| each { |it| {value: $it.command description: $it.usage} }
}
}
{
name: vars_menu
only_buffer_difference: true
marker: "# "
type: {
layout: list
page_size: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.vars
| where name =~ $buffer
| sort-by name
| each { |it| {value: $it.name description: $it.type} }
}
}
{
name: commands_with_description
only_buffer_difference: true
marker: "# "
type: {
layout: description
columns: 4
col_width: 20
col_padding: 2
selection_rows: 4
description_rows: 10
}
style: {
text: green
selected_text: green_reverse
description_text: yellow
}
source: { |buffer, position|
$nu.scope.commands
| where command =~ $buffer
| each { |it| {value: $it.command description: $it.usage} }
}
}
]
keybindings: [
{
name: completion_menu
modifier: none
keycode: tab
mode: emacs # Options: emacs vi_normal vi_insert
event: {
until: [
{ send: menu name: completion_menu }
{ send: menunext }
]
}
}
{
name: completion_previous
modifier: shift
keycode: backtab
mode: [emacs, vi_normal, vi_insert] # Note: You can add the same keybinding to all modes by using a list
event: { send: menuprevious }
}
{
name: history_menu
modifier: control
keycode: char_r
mode: emacs
event: { send: menu name: history_menu }
}
{
name: next_page
modifier: control
keycode: char_x
mode: emacs
event: { send: menupagenext }
}
{
name: undo_or_previous_page
modifier: control
keycode: char_z
mode: emacs
event: {
until: [
{ send: menupageprevious }
{ edit: undo }
]
}
}
{
name: yank
modifier: control
keycode: char_y
mode: emacs
event: {
until: [
{edit: pastecutbufferafter}
]
}
}
{
name: unix-line-discard
modifier: control
keycode: char_u
mode: [emacs, vi_normal, vi_insert]
event: {
until: [
{edit: cutfromlinestart}
]
}
}
{
name: kill-line
modifier: control
keycode: char_k
mode: [emacs, vi_normal, vi_insert]
event: {
until: [
{edit: cuttolineend}
]
}
}
# Keybindings used to trigger the user defined menus
{
name: commands_menu
modifier: control
keycode: char_t
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: commands_menu }
}
{
name: vars_menu
modifier: alt
keycode: char_o
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: vars_menu }
}
{
name: commands_with_description
modifier: control
keycode: char_s
mode: [emacs, vi_normal, vi_insert]
event: { send: menu name: commands_with_description }
}
]
}
source ~/.cache/starship/init.nu

View file

@ -0,0 +1,7 @@
{
programs.nushell = {
enable = true;
configFile.source = ./config.nu;
envFile.source = ./env.nu;
};
}

View file

@ -0,0 +1,36 @@
# Nushell Environment Config File
# Specifies how environment variables are:
# - converted from a string to a value on Nushell startup (from_string)
# - converted from a value back to a string when running external commands (to_string)
# Note: The conversions happen *after* config.nu is loaded
let-env ENV_CONVERSIONS = {
"PATH": {
from_string: { |s| $s | split row (char esep) | path expand -n }
to_string: { |v| $v | path expand -n | str join (char esep) }
}
"Path": {
from_string: { |s| $s | split row (char esep) | path expand -n }
to_string: { |v| $v | path expand -n | str join (char esep) }
}
}
# Directories to search for scripts when calling source or use
#
# By default, <nushell-config-dir>/scripts is added
let-env NU_LIB_DIRS = [
($nu.config-path | path dirname | path join 'scripts')
]
# Directories to search for plugin binaries when calling register
#
# By default, <nushell-config-dir>/plugins is added
let-env NU_PLUGIN_DIRS = [
($nu.config-path | path dirname | path join 'plugins')
]
# To add entries to PATH (on Windows you might use Path), you can use the following pattern:
# let-env PATH = ($env.PATH | split row (char esep) | prepend '/some/path')
mkdir ~/.cache/starship
starship init nu | sed "s/size -c/size/" | save ~/.cache/starship/init.nu

View file

@ -0,0 +1,13 @@
{config, ...}: {
home.sessionVariables.STARSHIP_CACHE = "${config.xdg.cacheHome}/starship";
programs.starship = {
enable = true;
settings = {
character = {
success_symbol = "[](bold green)";
error_symbol = "[](bold red)";
};
};
};
}

View file

@ -0,0 +1,30 @@
{
pkgs,
config,
lib,
...
}: let
apply-hm-env = pkgs.writeShellScript "apply-hm-env" ''
${lib.optionalString (config.home.sessionPath != []) ''
export PATH=${builtins.concatStringsSep ":" config.home.sessionPath}:$PATH
''}
${builtins.concatStringsSep "\n" (lib.mapAttrsToList (k: v: ''
export ${k}=${toString v}
'')
config.home.sessionVariables)}
${config.home.sessionVariablesExtra}
exec "$@"
'';
# runs processes as systemd transient services
run-as-service = pkgs.writeShellScriptBin "run-as-service" ''
exec ${pkgs.systemd}/bin/systemd-run \
--slice=app-manual.slice \
--property=ExitType=cgroup \
--user \
--wait \
bash -lc "exec ${apply-hm-env} $@"
'';
in {
home.packages = [run-as-service];
}

View file

@ -0,0 +1,76 @@
{
config,
pkgs,
lib,
...
}: {
programs.zsh = {
enable = true;
enableAutosuggestions = true;
autocd = true;
dirHashes = {
dl = "$HOME/Downloads";
docs = "$HOME/Documents";
code = "$HOME/Documents/code";
dots = "$HOME/Documents/code/dotfiles";
pics = "$HOME/Pictures";
vids = "$HOME/Videos";
nixpkgs = "$HOME/Documents/code/git/nixpkgs";
};
dotDir = ".config/zsh";
history = {
expireDuplicatesFirst = true;
path = "${config.xdg.dataHome}/zsh_history";
};
initExtra = ''
# search history based on what's typed in the prompt
autoload -U history-search-end
zle -N history-beginning-search-backward-end history-search-end
zle -N history-beginning-search-forward-end history-search-end
bindkey "^[OA" history-beginning-search-backward-end
bindkey "^[OB" history-beginning-search-forward-end
# case insensitive tab completion
zstyle ':completion:*' completer _complete _ignored _approximate
zstyle ':completion:*' list-colors '\'
zstyle ':completion:*' list-prompt %SAt %p: Hit TAB for more, or the character to insert%s
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
zstyle ':completion:*' menu select
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
zstyle ':completion:*' verbose true
_comp_options+=(globdots)
${lib.optionalString config.services.gpg-agent.enable ''
gnupg_path=$(ls $XDG_RUNTIME_DIR/gnupg)
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/gnupg/$gnupg_path/S.gpg-agent.ssh"
''}
${lib.optionalString config.programs.kitty.enable ''
if test -n "$KITTY_INSTALLATION_DIR"; then
export KITTY_SHELL_INTEGRATION="enabled"
autoload -Uz -- "$KITTY_INSTALLATION_DIR"/shell-integration/zsh/kitty-integration
kitty-integration
unfunction kitty-integration
fi
''}
# run programs that are not in PATH with comma
command_not_found_handler() {
${pkgs.comma}/bin/comma "$@"
}
'';
shellAliases = {
grep = "grep --color";
ip = "ip --color";
l = "exa -l";
la = "exa -la";
md = "mkdir -p";
us = "systemctl --user";
rs = "sudo systemctl";
};
shellGlobalAliases = {exa = "exa --icons --git";};
};
}

View file

@ -0,0 +1,52 @@
{default, ...}:
# terminals
let
inherit (default.terminal) font size opacity;
inherit (default) xcolors;
in {
programs.alacritty = {
enable = true;
settings = {
window = {
decorations = "none";
dynamic_padding = true;
padding = {
x = 5;
y = 5;
};
startup_mode = "Maximized";
};
scrolling.history = 10000;
font = {
normal.family = font;
bold.family = font;
italic.family = font;
inherit size;
};
draw_bold_text_with_bright_colors = true;
colors = rec {
primary = {
background = xcolors.crust;
foreground = xcolors.fg;
};
normal = {
inherit (xcolors) red green yellow blue;
black = xcolors.mantle;
magenta = xcolors.mauve;
cyan = xcolors.sky;
white = xcolors.text;
};
bright =
normal
// {
black = xcolors.base;
white = xcolors.rosewater;
};
};
window.opacity = opacity;
};
};
}

View file

@ -0,0 +1,54 @@
{default, ...}: let
inherit (default) xcolors;
in {
programs.kitty = {
enable = true;
font = {
inherit (default.terminal) size;
name = default.terminal.font;
};
settings = {
scrollback_lines = 10000;
placement_strategy = "center";
allow_remote_control = "yes";
enable_audio_bell = "no";
visual_bell_duration = "0.1";
visual_bell_color = xcolors.rosewater;
copy_on_select = "clipboard";
selection_foreground = "none";
selection_background = "none";
# colors
background_opacity = toString default.terminal.opacity;
foreground = xcolors.fg;
background = xcolors.crust;
# black
color0 = xcolors.mantle;
color8 = xcolors.base;
# red
color1 = xcolors.red;
color9 = xcolors.red;
# green
color2 = xcolors.green;
color10 = xcolors.green;
# yellow
color3 = xcolors.yellow;
color11 = xcolors.yellow;
# blue
color4 = xcolors.blue;
color12 = xcolors.blue;
# magenta
color5 = xcolors.pink;
color13 = xcolors.pink;
# cyan
color6 = xcolors.sky;
color14 = xcolors.sky;
# white
color7 = xcolors.text;
color15 = xcolors.rosewater;
};
};
}

View file

@ -0,0 +1,28 @@
{default, ...}: {
programs.wezterm = {
enable = true;
extraConfig = ''
local wezterm = require "wezterm"
return {
font = wezterm.font_with_fallback({ "${default.terminal.font}", }, {
weight = "Regular",
}),
font_size = ${toString default.terminal.size},
color_scheme = "Catppuccin Mocha",
window_background_opacity = ${toString default.terminal.opacity},
enable_scroll_bar = false,
enable_tab_bar = false,
scrollback_lines = 10000,
window_padding = {
left = 10,
right = 10,
top = 10,
bottom = 10,
},
check_for_updates = false,
default_cursor_style = "SteadyBar",
}
'';
};
}

View file

@ -0,0 +1,68 @@
{
pkgs,
lib,
inputs,
...
}:
# Wayland config
let
# use OCR and copy to clipboard
ocrScript = let
inherit (pkgs) grim libnotify slurp tesseract5 wl-clipboard;
_ = lib.getExe;
in
pkgs.writeShellScriptBin "wl-ocr" ''
${_ grim} -g "$(${_ slurp})" -t ppm - | ${_ tesseract5} - - | ${wl-clipboard}/bin/wl-copy
${_ libnotify} "$(${wl-clipboard}/bin/wl-paste)"
'';
in {
imports = [
../programs/eww
./hyprland
./sway.nix
./swaybg.nix
./swayidle.nix
./swaylock.nix
];
programs.eww-hyprland = {
enable = true;
package = inputs.eww.packages.${pkgs.hostPlatform.system}.eww-wayland;
};
home.packages = with pkgs; [
# screenshot
grim
slurp
# idle/lock
swaybg
swaylock-effects
# utils
ocrScript
wf-recorder
wl-clipboard
wlogout
wlr-randr
wofi
];
# make stuff work on wayland
home.sessionVariables = {
QT_QPA_PLATFORM = "wayland";
SDL_VIDEODRIVER = "wayland";
XDG_SESSION_TYPE = "wayland";
};
programs.obs-studio.plugins = with pkgs.obs-studio-plugins; [wlrobs];
# fake a tray to let apps start
# https://github.com/nix-community/home-manager/issues/2064
systemd.user.targets.tray = {
Unit = {
Description = "Home Manager System Tray";
Requires = ["graphical-session-pre.target"];
};
};
}

View file

@ -0,0 +1,248 @@
{
config,
pkgs,
default,
...
}: let
inherit (default) colors;
pointer = config.home.pointerCursor;
homeDir = config.home.homeDirectory;
emoji = "${pkgs.wofi-emoji}/bin/wofi-emoji";
launcher = "wofi";
in {
wayland.windowManager.hyprland.extraConfig = ''
$mod = SUPER
env = _JAVA_AWT_WM_NONREPARENTING,1
env = QT_WAYLAND_DISABLE_WINDOWDECORATION,1
# scale apps
env = GDK_SCALE,2
exec-once = xprop -root -f _XWAYLAND_GLOBAL_OUTPUT_SCALE 32c -set _XWAYLAND_GLOBAL_OUTPUT_SCALE 2
# set cursor for HL itself
exec-once = hyprctl setcursor ${pointer.name} ${toString pointer.size}
exec-once = systemctl --user start clight
exec-once = eww open bar
misc {
# disable auto polling for config file changes
disable_autoreload = true
focus_on_activate = true
# disable dragging animation
animate_mouse_windowdragging = false
}
# touchpad gestures
gestures {
workspace_swipe = true
workspace_swipe_forever = true
}
input {
kb_layout = ro
# focus change on cursor move
follow_mouse = 1
accel_profile = flat
touchpad {
scroll_factor = 0.3
}
}
device:MSFT0001:00 04F3:31EB Touchpad {
accel_profile = adaptive
natural_scroll = true
sensitivity = 0.1
}
general {
gaps_in = 5
gaps_out = 5
border_size = 2
col.active_border = rgb(${colors.blue}) rgb(${colors.mauve}) 270deg
col.inactive_border = rgb(${colors.crust}) rgb(${colors.lavender}) 270deg
# group borders
col.group_border_active = rgb(${colors.pink})
col.group_border = rgb(${colors.surface0})
}
decoration {
rounding = 16
blur = true
blur_size = 3
blur_passes = 3
blur_new_optimizations = true
drop_shadow = true
shadow_ignore_window = true
shadow_offset = 0 5
shadow_range = 50
shadow_render_power = 3
col.shadow = rgba(00000099)
}
animations {
enabled = true
animation = border, 1, 2, default
animation = fade, 1, 4, default
animation = windows, 1, 3, default, popin 80%
animation = workspaces, 1, 2, default, slide
}
dwindle {
# keep floating dimentions while tiling
pseudotile = true
preserve_split = true
}
# only allow shadows for floating windows
windowrulev2 = noshadow, floating:0
# telegram media viewer
windowrulev2 = float, title:^(Media viewer)$
# make Firefox PiP window floating and sticky
windowrulev2 = float, title:^(Picture-in-Picture)$
windowrulev2 = pin, title:^(Picture-in-Picture)$
# throw sharing indicators away
windowrulev2 = workspace special silent, title:^(Firefox Sharing Indicator)$
windowrulev2 = workspace special silent, title:^(.*is sharing (your screen|a window)\.)$
# start spotify tiled in ws9
windowrulev2 = tile, class:^(Spotify)$
windowrulev2 = workspace 9 silent, class:^(Spotify)$
# start Discord/WebCord in ws2
windowrulev2 = workspace 2, title:^(.*(Disc|WebC)ord.*)$
# idle inhibit while watching videos
windowrulev2 = idleinhibit focus, class:^(mpv|.+exe)$
windowrulev2 = idleinhibit focus, class:^(firefox)$, title:^(.*YouTube.*)$
windowrulev2 = idleinhibit fullscreen, class:^(firefox)$
windowrulev2 = dimaround, class:^(gcr-prompter)$
# fix xwayland apps
windowrulev2 = rounding 0, xwayland:1, floating:1
windowrulev2 = center, class:^(.*jetbrains.*)$, title:^(Confirm Exit|Open Project|win424|win201|splash)$
windowrulev2 = size 640 400, class:^(.*jetbrains.*)$, title:^(splash)$
layerrule = blur, ^(gtk-layer-shell)$
layerrule = ignorezero, ^(gtk-layer-shell)$
# mouse movements
bindm = $mod, mouse:272, movewindow
bindm = $mod, mouse:273, resizewindow
bindm = $mod ALT, mouse:272, resizewindow
# compositor commands
bind = $mod SHIFT, E, exec, pkill Hyprland
bind = $mod, Q, killactive,
bind = $mod, F, fullscreen,
bind = $mod, G, togglegroup,
bind = $mod SHIFT, N, changegroupactive, f
bind = $mod SHIFT, P, changegroupactive, b
bind = $mod, R, togglesplit,
bind = $mod, T, togglefloating,
bind = $mod, P, pseudo,
bind = $mod ALT, ,resizeactive,
# toggle "monocle" (no_gaps_when_only)
$kw = dwindle:no_gaps_when_only
bind = $mod, M, exec, hyprctl keyword $kw $(($(hyprctl getoption $kw -j | jaq -r '.int') ^ 1))
# utility
# launcher
bindr = $mod, SUPER_L, exec, pkill .${launcher}-wrapped || run-as-service ${launcher}
# terminal
bind = $mod, Return, exec, run-as-service ${default.terminal.name}
# logout menu
bind = $mod, Escape, exec, wlogout -p layer-shell
# lock screen
bind = $mod, L, exec, loginctl lock-session
# emoji picker
bind = $mod, E, exec, ${emoji}
# select area to perform OCR on
bind = $mod, O, exec, run-as-service wl-ocr
# move focus
bind = $mod, left, movefocus, l
bind = $mod, right, movefocus, r
bind = $mod, up, movefocus, u
bind = $mod, down, movefocus, d
# window resize
bind = $mod, S, submap, resize
submap = resize
binde = , right, resizeactive, 10 0
binde = , left, resizeactive, -10 0
binde = , up, resizeactive, 0 -10
binde = , down, resizeactive, 0 10
bind = , escape, submap, reset
submap = reset
# media controls
bindl = , XF86AudioPlay, exec, playerctl play-pause
bindl = , XF86AudioPrev, exec, playerctl previous
bindl = , XF86AudioNext, exec, playerctl next
# volume
bindle = , XF86AudioRaiseVolume, exec, wpctl set-volume -l "1.0" @DEFAULT_AUDIO_SINK@ 6%+
binde = , XF86AudioRaiseVolume, exec, ${homeDir}/.config/eww/scripts/volume osd
bindle = , XF86AudioLowerVolume, exec, wpctl set-volume -l "1.0" @DEFAULT_AUDIO_SINK@ 6%-
binde = , XF86AudioLowerVolume, exec, ${homeDir}/.config/eww/scripts/volume osd
bindl = , XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
bind = , XF86AudioMute, exec, ${homeDir}/.config/eww/scripts/volume osd
bindl = , XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
# backlight
bindle = , XF86MonBrightnessUp, exec, light -A 5
binde = , XF86MonBrightnessUp, exec, ${homeDir}/.config/eww/scripts/brightness osd
bindle = , XF86MonBrightnessDown, exec, light -U 5
binde = , XF86MonBrightnessDown, exec, ${homeDir}/.config/eww/scripts/brightness osd
# screenshot
# stop animations while screenshotting; makes black border go away
$screenshotarea = hyprctl keyword animation "fadeOut,0,0,default"; grimblast --notify copysave area; hyprctl keyword animation "fadeOut,1,4,default"
bind = , Print, exec, $screenshotarea
bind = $mod SHIFT, R, exec, $screenshotarea
bind = CTRL, Print, exec, grimblast --notify --cursor copysave output
bind = $mod SHIFT CTRL, R, exec, grimblast --notify --cursor copysave output
bind = ALT, Print, exec, grimblast --notify --cursor copysave screen
bind = $mod SHIFT ALT, R, exec, grimblast --notify --cursor copysave screen
# workspaces
# binds mod + [shift +] {1..10} to [move to] ws {1..10}
${builtins.concatStringsSep "\n" (builtins.genList (
x: let
ws = let
c = (x + 1) / 10;
in
builtins.toString (x + 1 - (c * 10));
in ''
bind = $mod, ${ws}, workspace, ${toString (x + 1)}
bind = $mod SHIFT, ${ws}, movetoworkspace, ${toString (x + 1)}
''
)
10)}
# special workspace
bind = $mod SHIFT, grave, movetoworkspace, special
bind = $mod, grave, togglespecialworkspace, eDP-1
# cycle workspaces
bind = $mod, bracketleft, workspace, m-1
bind = $mod, bracketright, workspace, m+1
# cycle monitors
bind = $mod SHIFT, braceleft, focusmonitor, l
bind = $mod SHIFT, braceright, focusmonitor, r
'';
}

View file

@ -0,0 +1,20 @@
{
inputs,
lib,
pkgs,
...
}: {
imports = [./config.nix];
home.packages = with pkgs; [
jaq
xorg.xprop
inputs.hyprland-contrib.packages.${pkgs.hostPlatform.system}.grimblast
];
# start swayidle as part of hyprland, not sway
systemd.user.services.swayidle.Install.WantedBy = lib.mkForce ["hyprland-session.target"];
# enable hyprland
wayland.windowManager.hyprland.enable = true;
}

View file

@ -0,0 +1,74 @@
{
config,
pkgs,
lib,
inputs,
default,
...
}: {
wayland.windowManager.sway = {
enable = true;
package = inputs.self.packages.${pkgs.hostPlatform.system}.sway-hidpi;
config = {
keybindings = let
m = config.wayland.windowManager.sway.config.modifier;
in
lib.mkOptionDefault {
"${m}+Return" = "exec ${default.terminal.name}";
"${m}+q" = "kill";
"${m}+space" = "exec wofi";
"${m}+t" = "floating toggle";
# screenshots
"Print" = "grim -g \"$(slurp)\" - | wl-copy -t image/png";
"${m}+Shift+r" = "grim -g \"$(slurp)\" - | wl-copy -t image/png";
"Alt+Print" = "grim - | wl-copy -t image/png";
"${m}+Alt+Shift+r" = "grim - | wl-copy -t image/png";
};
keycodebindings = {
"--locked --no-repeat 121" = "exec wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; # mute
"--locked 122" = "exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 6%-"; # vol-
"--locked 123" = "exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 6%+"; # vol+
"--locked 171" = "exec playerctl next"; # next song
"--locked --no-repeat 172" = "exec playerctl play-pause"; # play/pause
"--locked 173" = "exec playerctl previous"; # prev song
"--locked --no-repeat 198" = "exec wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"; # mic mute
"--locked 232" = "exec light -U 5"; # brightness-
"--locked 233" = "exec light -A 5"; # brightness+
};
menu = "wofi";
terminal = default.terminal.name;
modifier = "Mod4";
bars = [];
gaps = {
smartBorders = "on";
outer = 5;
inner = 5;
};
startup = [{command = "dbus-update-activation-environment --systemd WAYLAND_DISPLAY DISPLAY";}];
input = {
"type:pointer" = {
accel_profile = "flat";
pointer_accel = "0";
};
"type:touchpad" = {
middle_emulation = "enabled";
natural_scroll = "enabled";
tap = "enabled";
};
};
output."*".bg = "~/.config/wallpaper.png fill";
};
extraConfig = ''
exec ${pkgs.xorg.xprop}/bin/xprop -root -f _XWAYLAND_GLOBAL_OUTPUT_SCALE 32c -set _XWAYLAND_GLOBAL_OUTPUT_SCALE 2
'';
wrapperFeatures.gtk = true;
};
}

View file

@ -0,0 +1,18 @@
{
pkgs,
lib,
default,
...
}: {
systemd.user.services.swaybg = {
Unit = {
Description = "Wayland wallpaper daemon";
PartOf = ["graphical-session.target"];
};
Service = {
ExecStart = "${lib.getExe pkgs.swaybg} -i ${default.wallpaper} -m fill";
Restart = "on-failure";
};
Install.WantedBy = ["graphical-session.target"];
};
}

View file

@ -0,0 +1,34 @@
{pkgs, ...}: let
suspendScript = pkgs.writeShellScript "suspend-script" ''
${pkgs.pipewire}/bin/pw-cli i all | ${pkgs.ripgrep}/bin/rg running
# only suspend if audio isn't running
if [ $? == 1 ]; then
${pkgs.systemd}/bin/systemctl suspend
fi
'';
in {
# screen idle
services.swayidle = {
enable = true;
events = [
{
event = "before-sleep";
command = "${pkgs.systemd}/bin/loginctl lock-session";
}
{
event = "lock";
command = "${pkgs.swaylock-effects}/bin/swaylock -fF";
}
];
timeouts = [
{
timeout = 310;
command = "${pkgs.systemd}/bin/loginctl lock-session";
}
{
timeout = 310;
command = suspendScript.outPath;
}
];
};
}

View file

@ -0,0 +1,31 @@
{default, ...}: {
programs.swaylock.settings = let
inherit (default) xcolors;
in {
clock = true;
font = "Jost *";
image = default.wallpaper;
indicator = true;
bs-hl-color = xcolors.red;
key-hl-color = xcolors.text;
separator-color = xcolors.base;
text-color = xcolors.base;
inside-color = xcolors.mauve;
line-color = xcolors.mauve;
ring-color = xcolors.base;
inside-clear-color = xcolors.yellow;
line-clear-color = xcolors.yellow;
ring-clear-color = xcolors.base;
inside-ver-color = xcolors.lavender;
line-ver-color = xcolors.lavender;
ring-ver-color = xcolors.base;
inside-wrong-color = xcolors.red;
line-wrong-color = xcolors.red;
ring-wrong-color = xcolors.base;
};
}

View file

@ -0,0 +1,340 @@
{
pkgs,
default,
...
}: let
inherit (default) xrgbaColors;
in {
home.packages = [pkgs.wayfire];
xdg.configFile."wayfire.ini".text = ''
[alpha]
min_value = 0.100000
modifier = <alt> <super>
[animate]
close_animation = fade
open_animation = zoom
startup_duration = 300
duration = 300
enabled_for = type equals "toplevel" | (type equals "x-or" & focusable equals true))
fade_duration = 400
fade_enabled_for = type equals "overlay"
[autostart]
0_environment = dbus-update-activation-environment --systemd WAYLAND_DISPLAY DISPLAY XAUTHORITY
1_hm = systemctl --user start graphical-session.target
2_eww = eww daemon
autostart_wf_shell = false
background = swaybg -i ~/.config/wallpaper.png
idle = swayidle -w \
timeout 360 'swaylock' \
before-sleep 'swaylock'
panel = eww open bar
[blur]
blur_by_default = type is "toplevel"
bokeh_degrade = 1
bokeh_iterations = 5
bokeh_offset = 5.000000
box_degrade = 1
box_iterations = 2
box_offset = 1.000000
gaussian_degrade = 1
gaussian_iterations = 2
gaussian_offset = 1.000000
kawase_degrade = 3
kawase_iterations = 3
kawase_offset = 1.000000
method = kawase
saturation = 1.000000
#toggle = <super> KEY_B
[command]
binding_launcher = <super> KEY_SPACE
binding_lock = <super> KEY_L
binding_logout = <super> KEY_ESC
binding_mute = KEY_MUTE
binding_mic_mute = KEY_F20
binding_next = KEY_NEXTSONG
binding_pause = KEY_PLAYPAUSE
binding_prev = KEY_PREVIOUSSONG
binding_screenshot = KEY_PRINT | <super> <shift> KEY_R
binding_screenshot_interactive = <ctrl> KEY_PRINT | <super> <shift> <ctrl> KEY_R
binding_terminal = <super> KEY_ENTER
command_launcher = wofi --show=drun -I
command_light_down = light -U 5
command_light_up = light -A 5
command_lock = swaylock
command_logout = wlogout -p layer-shell
command_mute = wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
command_mic_mute = wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
command_next = playerctl next
command_pause = playerctl play-pause
command_prev = playerctl previous
command_screenshot = screenshot area
command_screenshot_interactive = screenshot monitor
command_terminal = ${default.terminal.name}
command_volume_down = pulsemixer --change-volume -6
command_volume_up = pulsemixer --change-volume +6
repeatable_binding_light_down = KEY_BRIGHTNESSDOWN
repeatable_binding_light_up = KEY_BRIGHTNESSUP
repeatable_binding_volume_down = KEY_VOLUMEDOWN
repeatable_binding_volume_up = KEY_VOLUMEUP
[core]
background_color = #${xrgbaColors.base00}
close_top_view = <super> KEY_Q | <alt> KEY_F4
focus_button_with_modifiers = false
focus_buttons = BTN_LEFT | BTN_MIDDLE | BTN_RIGHT
focus_buttons_passthrough = true
plugins = autostart \
blur \
command \
decoration \
expo \
fast-switcher \
idle \
matcher \
move \
oswitch \
place \
resize \
simple-tile \
vswipe \
window-rules \
wrot \
zoom
vheight = 3
vwidth = 3
xwayland = true
[cube]
activate = <alt> <ctrl> BTN_LEFT
background = #${xrgbaColors.base00}
background_mode = simple
cubemap_image =
deform = 0
initial_animation = 350
light = true
rotate_left = <alt> <ctrl> KEY_LEFT
rotate_right = <alt> <ctrl> KEY_RIGHT
skydome_mirror = true
skydome_texture =
speed_spin_horiz = 0.020000
speed_spin_vert = 0.020000
speed_zoom = 0.070000
zoom = 0.100000
[decoration]
active_color = #${xrgbaColors.base00}
border_size = 0
button_order = minimize maximize close
font = Roboto
ignore_views = none
inactive_color = #${xrgbaColors.base04}
title_height = 20
[expo]
background = #${xrgbaColors.base00}
duration = 50
offset = 10
select_workspace_1 = KEY_1
select_workspace_2 = KEY_2
select_workspace_3 = KEY_3
select_workspace_4 = KEY_4
select_workspace_5 = KEY_5
select_workspace_6 = KEY_6
select_workspace_7 = KEY_7
select_workspace_8 = KEY_8
select_workspace_9 = KEY_9
toggle = <super>
[extra-gestures]
close_fingers = 5
move_delay = 500
move_fingers = 3
[fast-switcher]
activate = <alt> KEY_ESC
activate_backward = <alt> <shift> KEY_ESC
[fisheye]
radius = 450.000000
toggle = <ctrl> <super> KEY_F
zoom = 7.000000
[grid]
duration = 300
restore = <super> KEY_DOWN | <super> KEY_KP0
slot_b = <super> KEY_KP2
slot_bl = <super> KEY_KP1
slot_br = <super> KEY_KP3
slot_c = <super> KEY_UP | <super> KEY_KP5
slot_l = <super> KEY_LEFT | <super> KEY_KP4
slot_r = <super> KEY_RIGHT | <super> KEY_KP6
slot_t = <super> KEY_KP8
slot_tl = <super> KEY_KP7
slot_tr = <super> KEY_KP9
type = crossfade
[idle]
cube_max_zoom = 1.500000
cube_rotate_speed = 1.000000
cube_zoom_speed = 1000
disable_on_fullscreen = true
dpms_timeout = 300
screensaver_timeout = -1
toggle = none
[input]
click_method = default
cursor_size = 24
cursor_theme = "Bibata-Modern-Classic"
disable_touchpad_while_mouse = false
disable_touchpad_while_typing = false
gesture_sensitivity = 1.000000
middle_emulation = false
modifier_binding_timeout = 400
mouse_accel_profile = flat
natural_scroll = true
touchpad_scroll_speed = 0.3
xkb_layout = ro
xkb_rules = evdev
[invert]
preserve_hue = false
toggle = <super> KEY_I
[move]
activate = <super> BTN_LEFT
enable_snap = true
enable_snap_off = true
join_views = false
quarter_snap_threshold = 50
snap_off_threshold = 10
snap_threshold = 10
workspace_switch_after = -1
[oswitch]
next_output = <super> KEY_O
next_output_with_win = <shift> <super> KEY_O
[output]
mode = auto
position = auto
scale = 1.000000
transform = normal
[place]
mode = center
[preserve-output]
last_output_focus_timeout = 10000
[resize]
activate = <super> BTN_RIGHT
[scale]
allow_zoom = false
bg_color = #${xrgbaColors.base00}
duration = 750
inactive_alpha = 0.750000
interact = false
middle_click_close = false
spacing = 50
text_color = #${xrgbaColors.base00}
title_font_size = 14
title_overlay = all
title_position = center
toggle = <super> KEY_P
toggle_all =
[switcher]
next_view = <alt> KEY_TAB
prev_view = <alt> <shift> KEY_TAB
speed = 500
view_thumbnail_scale = 1.000000
[vswipe]
background = #${xrgbaColors.base00}
duration = 180
enable_smooth_transition = true
enable_vertical = true
fingers = 3
gap = 32.000000
speed_cap = 0.500000
speed_factor = 500.000000
#threshold = 0.250000
[vswitch]
background = #${xrgbaColors.base00}
binding_down = <ctrl> <super> KEY_DOWN
binding_left = <ctrl> <super> KEY_LEFT
binding_right = <ctrl> <super> KEY_RIGHT
binding_up = <ctrl> <super> KEY_UP
binding_win_down = <ctrl> <shift> <super> KEY_DOWN
binding_win_left = <ctrl> <shift> <super> KEY_LEFT
binding_win_right = <ctrl> <shift> <super> KEY_RIGHT
binding_win_up = <ctrl> <shift> <super> KEY_UP
duration = 300
gap = 20
wraparound = false
[window-rules]
[wm-actions]
minimize = none
toggle_always_on_top = none
toggle_fullscreen = <super> KEY_F
toggle_maximize = none
toggle_showdesktop = none
toggle_sticky = none
[wobbly]
friction = 3.000000
grid_resolution = 6
spring_k = 8.000000
[workarounds]
all_dialogs_modal = true
app_id_mode = stock
dynamic_repaint_delay = false
[wrot]
activate = <ctrl> <super> BTN_RIGHT
activate-3d = <shift> <super> BTN_RIGHT
invert = false
reset = <ctrl> <super> KEY_R
reset-one = <super> KEY_R
reset_radius = 25.000000
sensitivity = 24
[zoom]
modifier = <super>
smoothing_duration = 300
speed = 0.010000
[simple-tile]
button_move = <super> BTN_LEFT
button_resize = <super> BTN_RIGHT
inner_gap_size = 2
keep_fullscreen_on_adjacent = true
key_focus_above = <super> KEY_K
key_focus_below = <super> KEY_J
key_focus_left = <super> KEY_H
key_focus_right = <super> KEY_L
key_toggle = <super> KEY_T
tile_by_default = type is "toplevel"
#wm-actions.toggle_always_on_top
'';
}

View file

@ -0,0 +1,9 @@
# Hosts config
Name | Description
------------ | -----------
`io` | Lenovo laptop, main machine
`kiiro` | Previous main machine, retired and rarely used server now
All the hosts have a shared config in `modules/minimal.nix`.
Host specific configs are stored inside the specific host dir.

View file

@ -0,0 +1,38 @@
{
inputs,
withSystem,
sharedModules,
desktopModules,
homeImports,
...
}: {
flake.nixosConfigurations = withSystem "x86_64-linux" ({system, ...}: {
io = inputs.nixpkgs.lib.nixosSystem {
inherit system;
modules =
[
./io
../modules/greetd.nix
../modules/desktop.nix
../modules/gamemode.nix
../modules/howdy
../modules/linux-enable-ir-emitter.nix
{home-manager.users.mihai.imports = homeImports."mihai@io";}
]
++ sharedModules
++ desktopModules;
};
kiiro = inputs.nixpkgs.lib.nixosSystem {
inherit system;
modules =
[
./kiiro
{home-manager.users.mihai.imports = homeImports.server;}
]
++ sharedModules;
};
});
}

View file

@ -0,0 +1,162 @@
{
config,
pkgs,
inputs,
...
} @ args: {
imports = [./hardware-configuration.nix];
age.secrets.spotify = {
file = "${inputs.self}/secrets/spotify.age";
owner = "mihai";
group = "users";
};
boot = {
initrd = {
systemd.enable = true;
supportedFilesystems = ["ext4"];
};
# load modules on boot
kernelModules = ["acpi_call" "amdgpu" "amd_pstate"];
# use latest kernel
kernelPackages = pkgs.linuxPackages_xanmod_latest;
# Panel Self Refresh
kernelParams = ["amdgpu.dcfeaturemask=0x8" "initcall_blacklist=acpi_cpufreq_init" "amd_pstate=passive" "amd_pstate.shared_mem=1"];
loader = {
# systemd-boot on UEFI
efi.canTouchEfiVariables = true;
systemd-boot.enable = true;
};
plymouth = {
enable = true;
themePackages = [inputs.self.packages.${pkgs.hostPlatform.system}.catppuccin-plymouth];
# theme = "catppuccin-mocha";
# font = "${pkgs.noto-fonts}/share/fonts/truetype/noto/NotoSans-Light.ttf";
};
};
environment.systemPackages = [config.boot.kernelPackages.cpupower];
hardware = {
bluetooth = {
enable = true;
# battery info support
package = pkgs.bluez5-experimental;
settings = {
# make Xbox Series X controller work
General = {
Class = "0x000100";
ControllerMode = "bredr";
FastConnectable = true;
JustWorksRepairing = "always";
Privacy = "device";
Experimental = true;
};
};
};
cpu.amd.updateMicrocode = true;
enableRedistributableFirmware = true;
opentabletdriver.enable = true;
video.hidpi.enable = true;
xpadneo.enable = true;
};
networking = {
hostName = "io";
firewall = {
allowedTCPPorts = [42355];
allowedUDPPorts = [5353];
};
};
programs = {
# enable hyprland and required options
hyprland.enable = true;
# backlight control
light.enable = true;
steam.enable = true;
};
security.tpm2 = {
enable = true;
abrmd.enable = true;
};
services = {
# for SSD/NVME
fstrim.enable = true;
howdy = {
enable = true;
package = inputs.self.packages.${pkgs.system}.howdy;
settings = {
core.no_confirmation = true;
video.device_path = "/dev/video2";
video.dark_threshold = 90;
};
};
linux-enable-ir-emitter.enable = true;
kmonad.keyboards = {
io = {
name = "io";
device = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
defcfg = {
enable = true;
fallthrough = true;
allowCommands = false;
};
config = builtins.readFile "${inputs.self}/modules/main.kbd";
};
};
# see https://github.com/fufexan/nix-gaming/#pipewire-low-latency
pipewire.lowLatency.enable = true;
printing.enable = true;
# configure mice
ratbagd.enable = true;
# power saving
tlp = {
enable = true;
settings = {
PCIE_ASPM_ON_BAT = "powersupersave";
CPU_SCALING_GOVERNOR_ON_AC = "performance";
CPU_SCALING_GOVERNOR_ON_BAT = "conservative";
NMI_WATCHDOG = 0;
};
};
udev.extraRules = let
inherit (import ./plugged.nix args) plugged unplugged;
in ''
# add my android device to adbusers
SUBSYSTEM=="usb", ATTR{idVendor}=="22d9", MODE="0666", GROUP="adbusers"
# start/stop services on power (un)plug
SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="${plugged}"
SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="${unplugged}"
'';
# add hyprland to display manager sessions
xserver.displayManager.sessionPackages = [inputs.hyprland.packages.${pkgs.hostPlatform.system}.default];
};
# https://github.com/NixOS/nixpkgs/issues/114222
systemd.user.services.telephony_client.enable = false;
}

View file

@ -0,0 +1,35 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
modulesPath,
...
}: {
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "usb_storage" "sd_mod"];
boot.initrd.kernelModules = [];
boot.kernelModules = ["kvm-amd"];
boot.extraModulePackages = [];
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/boot";
fsType = "vfat";
};
swapDevices = [];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# high-resolution display
hardware.video.hidpi.enable = lib.mkDefault true;
}

View file

@ -0,0 +1,24 @@
{
pkgs,
lib,
inputs,
...
}: let
programs = lib.makeBinPath [inputs.hyprland.packages.${pkgs.hostPlatform.system}.default];
in {
unplugged = pkgs.writeShellScript "unplugged" ''
export PATH=$PATH:${programs}
export HYPRLAND_INSTANCE_SIGNATURE=$(ls -w1 /tmp/hypr | tail -1)
systemctl --user --machine=1000@ stop easyeffects syncthing
hyprctl --batch 'keyword decoration:drop_shadow 0 ; keyword animations:enabled 0'
'';
plugged = pkgs.writeShellScript "plugged" ''
export PATH=$PATH:${programs}
export HYPRLAND_INSTANCE_SIGNATURE=$(ls -w1 /tmp/hypr | tail -1)
systemctl --user --machine=1000@ start easyeffects syncthing
hyprctl --batch 'keyword decoration:drop_shadow 1 ; keyword animations:enabled 1'
'';
}

View file

@ -0,0 +1,31 @@
# biggest homeserver
{lib, ...}: {
imports = [
./hardware-configuration.nix
./services.nix
];
# used by tailscale for exit node
boot.kernel.sysctl = {
"net.ipv4.ip_forward" = 1;
"net.ipv6.conf.all.forwarding" = 1;
};
# bootloader
boot.loader = {
efi.canTouchEfiVariables = true;
systemd-boot.enable = true;
};
hardware = {
cpu.intel.updateMicrocode = true;
enableRedistributableFirmware = true;
};
networking.hostName = "kiiro";
services.btrfs.autoScrub.enable = true;
system.stateVersion = lib.mkForce "21.11";
}

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