perf: Home-manager to module

feat: Optionise config
This commit is contained in:
2025-02-02 14:57:36 +03:00
parent f2c215460b
commit ea39ab9992
97 changed files with 395 additions and 488 deletions

23
modules/host.nix Normal file
View File

@ -0,0 +1,23 @@
{
imports = [
./host/bluetooth.nix
./host/bootloader.nix
./host/console.nix
./host/env.nix
./host/gamemode.nix
./host/gpg.nix
./host/laptop.nix
./host/printing.nix
./host/shutdown-on-lan.nix
./host/sound.nix
./host/virtmanager.nix
./host/vpn.nix
];
programs.hyprland.enable = true;
services = {
udisks2.enable = true;
fstrim.enable = true;
};
networking.networkmanager.enable = true;
}

4
modules/host/adb.nix Normal file
View File

@ -0,0 +1,4 @@
{
programs.adb.enable = true;
users.users.sweetbread.extraGroups = ["adbusers"]; # FIXME: check users
}

View File

@ -0,0 +1,14 @@
{ config, lib, ... }: {
hardware.bluetooth =
lib.mkIf config.hardware.bluetooth.enable {
powerOnBoot = true;
settings = {
General = {
Enable = "Source,Sink,Media,Socket";
Experimental = true;
};
};
};
services.blueman.enable = true;
}

View File

@ -0,0 +1,37 @@
{ pkgs, ... }: {
boot = {
loader = {
timeout = 3;
efi = {
efiSysMountPoint = "/boot";
canTouchEfiVariables = true;
};
grub = {
enable = true;
efiSupport = true;
device = "nodev";
useOSProber = true;
};
};
consoleLogLevel = 0;
kernelParams = [
# "quiet"
"splash"
"boot.shell_on_fail"
"loglevel=3"
# "rd.systemd.show_status=false"
# "rd.udev.log_level=3"
"udev.log_priority=0"
];
plymouth = {
enable = true;
theme = "black_hud";
themePackages = with pkgs; [
(adi1090x-plymouth-themes.override {
selected_themes = [ "black_hud" ];
})
];
};
};
}

23
modules/host/console.nix Normal file
View File

@ -0,0 +1,23 @@
{ pkgs, ... }: {
console = {
font = "${pkgs.kbd}/share/consolefonts/LatArCyrHeb-19.psfu.gz";
colors = [
"16161E"
"1A1B26"
"2F3549"
"444B6A"
"787C99"
"787C99"
"CBCCD1"
"D5D6DB"
"F7768E"
"FF9E64"
"E0AF68"
"41A6B5"
"7DCFFF"
"7AA2F7"
"BB9AF7"
"D18616"
];
};
}

8
modules/host/env.nix Normal file
View File

@ -0,0 +1,8 @@
{
environment.variables = {
EDITOR = "hx";
RANGER_LOAD_DEFAULT_RC = "FALSE";
QT_QPA_PLATFORMTHEME = "qt5ct";
GSETTINGS_BACKEND = "keyfile";
};
}

20
modules/host/gamemode.nix Normal file
View File

@ -0,0 +1,20 @@
{ config, pkgs, pkgs-stable, lib, ... }:
lib.mkIf config.programs.gamemode.enable {
programs.steam = {
enable = true;
gamescopeSession.enable = true;
};
environment.systemPackages = with pkgs-stable; [
mangohud
protonup
pkgs.bottles
heroic
];
environment.sessionVariables = {
STEAM_EXTRA_COMPAT_TOOLS_PATHS =
"\${HOME}/.steam/root/compatibilitytools.d";
};
}

6
modules/host/gpg.nix Normal file
View File

@ -0,0 +1,6 @@
{ pkgs, ...}: {
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
};
}

19
modules/host/laptop.nix Normal file
View File

@ -0,0 +1,19 @@
{ config, lib, ... }:
lib.mkIf config.host.laptop {
services.tlp = {
enable = true;
settings = {
CPU_SCALING_GOVERNOR_ON_AC = "performance";
CPU_SCALING_GOVERNOR_ON_BAT = "powersave";
CPU_ENERGY_PERF_POLICY_ON_BAT = "power";
CPU_ENERGY_PERF_POLICY_ON_AC = "performance";
CPU_MIN_PERF_ON_AC = 0;
CPU_MAX_PERF_ON_AC = 100;
CPU_MIN_PERF_ON_BAT = 0;
CPU_MAX_PERF_ON_BAT = 75;
};
};
}

View File

@ -0,0 +1,9 @@
{ config, lib, ... }:
lib.mkIf config.services.printing.enable {
services.avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
}

View File

@ -0,0 +1,70 @@
{ pkgs, lib, ... }:
let
sol = pkgs.writers.writePython3 "shutdown-on-lan.py" {
libraries = [ pkgs.python312Packages.psutil ];
flakeIgnore = [ "E501" "E302" "E305" ];
} /*py*/ ''
# https://habr.com/ru/articles/816765/
import socket
import os
import logging
import psutil
from time import sleep
WOL_PORT = 9
logging.basicConfig(format='%(levelname)s: %(asctime)s %(message)s', level=logging.INFO)
logger = logging.getLogger(__name__)
def get_ip_mac_address() -> tuple:
ip_addr = mac_addr = None
while not ip_addr or not mac_addr or ip_addr == '127.0.0.1':
net = psutil.net_if_addrs()
for item in net[list(net.keys())[-1]]:
addr = item.address
# В IPv4-адресах разделители - точки
if '.' in addr:
ip_addr = addr
# В MAC-адресах разделители либо тире, либо одинарное двоеточие.
# Двойное двоеточие - это разделители для адресов IPv6
elif ('-' in addr or ':' in addr) and '::' not in addr:
# Приводим MAC-адрес к одному формату. Формат может меняться в зависимости от ОС
mac_addr = addr.replace(':', '-').upper()
if not ip_addr or not mac_addr or ip_addr == '127.0.0.1':
logger.debug('Не удалось получить IP или MAC-адрес сетевого интерфейса')
sleep(10)
return ip_addr, mac_addr
def assemble_wol_packet(mac_address: str) -> str:
return f'{"FF-" * 6}{(mac_address + "-") * 16}'
def check_is_wol_packet(raw_bytes: bytes, assembled_wol_packet: str) -> int:
return '-'.join(f'{byte:02x}' for byte in raw_bytes).upper() + '-' == assembled_wol_packet
def run_udp_port_listener(port: int):
ip_addr, mac_addr = get_ip_mac_address()
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind((ip_addr, port))
logger.info(f'Listening on {ip_addr}:{port}')
assembled_wol_packet = assemble_wol_packet(mac_addr)
while True:
data, _ = server_socket.recvfrom(1024)
if check_is_wol_packet(data, assembled_wol_packet):
if os.name == 'posix':
os.system('shutdown -h now')
elif os.name == 'nt':
os.system('shutdown -s -t 0 -f')
run_udp_port_listener(WOL_PORT)
'';
in {
systemd.services.shutdown-on-lan = {
enable = true;
after = [ "network.target" ];
wantedBy = [ "default.target" ];
serviceConfig.ExecStart = sol;
};
networking.firewall.allowedUDPPorts = [ 9 ];
}

17
modules/host/sound.nix Normal file
View File

@ -0,0 +1,17 @@
{
security.rtkit.enable = true;
services = {
pulseaudio.enable = false;
pipewire = {
enable = true;
alsa = {
enable = true;
support32Bit = true;
};
pulse.enable = true;
};
};
}

View File

@ -0,0 +1,5 @@
{ pkgs, ... }: {
virtualisation.libvirtd.enable = true;
programs.virt-manager.enable = true;
}

28
modules/host/vpn.nix Normal file
View File

@ -0,0 +1,28 @@
{pkgs, config, ...}: {
systemd.services.v2raya = {
enable = true;
description = "v2rayA gui client";
after = [ "network.target" ];
serviceConfig = {
Restart = "always";
ExecStart = "${pkgs.v2raya}/bin/v2rayA";
};
path = with pkgs; [ iptables bash iproute2 ];
wantedBy = [ "multi-user.target" ];
environment = {
V2RAYA_LOG_FILE = "/var/log/v2raya/v2raya.log";
V2RAY_LOCATION_ASSET = "/etc/v2raya";
XRAY_LOCATION_ASSET = "/etc/v2raya";
};
};
environment.etc = {
"v2raya/ru_geoip.dat".source = pkgs.fetchurl {
name = "geoip.dat";
url = "https://github.com/runetfreedom/russia-blocked-geoip/releases/download/202501260919/geoip.dat";
hash = "sha256-OZoWEyfp1AwIN1eQHaB5V3FP51gsUKKDbFBHtqs4UDM=";
};
"v2raya/bolt.db".source = config.sops.secrets.vpn_bolt.path;
};
}

20
modules/user.nix Normal file
View File

@ -0,0 +1,20 @@
{
imports = [
./user/kitty.nix
./user/qt.nix
./user/sops.nix
./user/neofetch.nix
./user/yazi.nix
./user/ags.nix
./user/zsh.nix
./user/helix.nix
./user/hyprlock.nix
./user/btop.nix
./user/wofi.nix
./user/mako.nix
./user/packages/art.nix
./user/packages/desktop.nix
./user/packages/coding.nix
./user/packages/utils.nix
];
}

22
modules/user/ags.nix Normal file
View File

@ -0,0 +1,22 @@
{ config, inputs, pkgs, ... }: {
imports = [ inputs.ags.homeManagerModules.default ];
programs.ags = {
enable = true;
configDir = null;
extraPackages = with inputs.ags.packages.${pkgs.system}; [
battery
mpris
hyprland
network
tray
wireplumber
];
};
wayland.windowManager.hyprland.settings.exec-once = [ "ags run" ];
xdg.configFile."ags".source = (pkgs.callPackage ./packages/drvs/ags.nix { colors = config.lib.stylix.colors; });
}

15
modules/user/btop.nix Normal file
View File

@ -0,0 +1,15 @@
{ pkgs, ... }: {
programs.btop = {
enable = true;
package = pkgs.btop.override { cudaSupport = true; };
settings = {
shown_boxes = "proc cpu gpu0 mem net";
# color_theme = "TTY";
update_ms = 1000;
cpu_single_graph = true;
only_physical = false;
net_auto = false;
net_iface = "eno1";
};
};
}

22
modules/user/helix.nix Normal file
View File

@ -0,0 +1,22 @@
{
programs.helix = {
enable = true;
defaultEditor = true;
settings = {
# theme = "catppuccin-mocha";
editor = {
insert-final-newline = false;
whitespace.render = {
space = "all";
tab = "all";
nbsp = "none";
nnbsp = "none";
newline = "none";
};
indent-guides.render = true;
};
};
};
}

82
modules/user/hyprlock.nix Normal file
View File

@ -0,0 +1,82 @@
{ config, pkgs, lib, ... }:
lib.mkIf config.programs.hyprlock.enable {
wayland.windowManager.hyprland.settings.exec-once = [ "hyprlock" ];
programs.hyprlock = let
image = pkgs.fetchurl {
name = "lock_background.jpg";
url = "https://w.wallhaven.cc/full/kx/wallhaven-kxwol7.jpg";
hash = "sha256-wRFs/Inw1wEzF5UKFn/o6e/xH5ZJ3SVNxxno+mDx2Fs=";
};
in {
settings = {
background = {
path = lib.mkForce "${image}";
color = "rgba(25, 20, 20, 1.0)";
blur_passes = 0;
blur_size = 7;
noise = 0.0117;
contrast = 0.8916;
brightness = 0.8172;
vibrancy = 0.1696;
vibrancy_darkness = 0.0;
};
shape = {
size = "360, 60";
color = "rgba(17, 17, 17, 1.0)";
rounding = -1;
border_size = 8;
border_color = "rgba(0, 207, 230, 1.0)";
rotate = 0;
xray = false;
position = "0, 80";
halign = "center";
valign = "center";
};
label = {
text = "Hi there, $USER";
text_align = "center";
color = "rgba(200, 200, 200, 1.0)";
font_size = 25;
font_family = "Noto Sans";
rotate = 0;
position = "0, 80";
halign = "center";
valign = "center";
};
input-field = {
size = "200, 50";
outline_thickness = 3;
dots_size = 0.33;
dots_spacing = 0.15;
dots_center = false;
dots_rounding = -1;
dots_fade_time = 200;
font_family = "Noto Sans";
fade_on_empty = true;
fade_timeout = 1000;
placeholder_text = "<i>Input Password...</i>";
hide_input = false;
rounding = -1;
fail_text = "<i>$FAIL <b>($ATTEMPTS)</b></i>";
fail_timeout = 2000;
fail_transition = 300;
capslock_color = -1;
numlock_color = -1;
bothlock_color = -1;
invert_numlock = false;
swap_font_color = false;
position = "0, -20";
halign = "center";
valign = "center";
};
};
};
}

14
modules/user/kitty.nix Normal file
View File

@ -0,0 +1,14 @@
{ lib, pkgs, ... }: {
programs.kitty = {
enable = true;
settings = lib.mkDefault {
dynamic_background_opacity = "yes";
background_opacity = 0.5;
background_blur = true;
background = "#1d2021";
font_size = 13.0;
cursor_blink_interval = "0.5 ease-in-out";
};
};
programs.zsh.envExtra = "TERM=xterm-256color";
}

21
modules/user/mako.nix Normal file
View File

@ -0,0 +1,21 @@
{ config, pkgs, ... }:
let
colors = config.lib.stylix.colors;
in {
home.packages = [ pkgs.mako ];
xdg.configFile."mako/config".text = ''
background-color=#${colors.base00}
text-color=#${colors.base05}
border-color=#${colors.base0B}
border-radius=10
margin=16
progress-color=over #${colors.base0A}
default-timeout=5000
[urgency=high]
border-color=#${colors.base09}
[urgency=low]
border-color=#${colors.base04}
'';
}

122
modules/user/neofetch.nix Normal file
View File

@ -0,0 +1,122 @@
{ config, pkgs, ... }: let
icon = pkgs.fetchurl {
url = "https://preview.redd.it/a2nga4jvjy291.png?width=640&crop=smart&auto=webp&s=7d1458b41101c960bc13c28a6b92c5a6ddc20210";
name = "nixos-chan.png";
sha256 = "sha256-9pleL+PiiylT8/aWw0iGve1iY3h0XohSQ7MVILzabHY=";
};
in {
home.packages = [ pkgs.neofetch ];
xdg.configFile."neofetch/config.conf".text = ''
print_info() {
info title
info underline
prin "Hardware"
info "- Host" model
info "- Resolution" resolution
info "- CPU" cpu
info "- GPU" gpu gpu_driver
info "- Memory" memory
info "- Disk" disk
info "- Battery" battery
echo
prin "Software"
info "- OS" distro kernel
# info "- Uptime" uptime
info "- Packages" packages
info "- Shell" shell
prin "- Prompt" "Starship"
info "- Terminal" term
info "- DE" de
info "- WM" wm
echo
prin "Style"
info "- WM Theme" wm_theme
info "- Theme" theme
prin "- Base16 Theme" "${baseNameOf config.stylix.base16Scheme}"
info "- Icons" icons
info "- Terminal Font" term_font
info "- Font" font
# info "- Song" song
[[ "$player" ]] && prin "- Music Player" "$player"
# info "- Local IP" local_ip
# info "- Public IP" public_ip
# info "- Users" users
info "- Locale" locale # This only works on glibc systems.
info cols
}
title_fqdn="on"
kernel_shorthand="on"
distro_shorthand="on"
os_arch="on"
uptime_shorthand="on"
memory_percent="off"
memory_unit="mib"
package_managers="on"
shell_path="off"
shell_version="on"
speed_type="bios_limit"
speed_shorthand="on"
cpu_brand="on"
cpu_speed="on"
cpu_cores="logical"
cpu_temp="off"
gpu_brand="on"
gpu_type="all"
refresh_rate="on"
gtk_shorthand="off"
gtk2="on"
gtk3="on"
public_ip_host="http://ident.me"
local_ip_interface=('auto')
de_version="on"
disk_show=('/' '/mnt/D')
disk_subtitle="mount"
disk_percent="on"
music_player="auto"
song_format="%artist% - %album% - %title%"
song_shorthand="off"
mpc_args=()
colors=(distro)
bold="on"
underline_enabled="on"
underline_char="-"
separator=":"
block_range=(0 15)
color_blocks="on"
block_width=3
block_height=1
col_offset="auto"
bar_char_elapsed="="
bar_char_total="."
bar_border="on"
bar_length=15
bar_color_elapsed="distro"
bar_color_total="distro"
memory_display="infobar"
battery_display="off"
disk_display="infobar"
image_backend="kitty"
image_source=${icon}
ascii_distro="auto"
ascii_colors=(distro)
ascii_bold="on"
image_loop="off"
thumbnail_dir="${config.xdg.cacheHome}/thumbnails/neofetch"
crop_mode="normal"
crop_offset="center"
image_size="auto"
catimg_size="2"
gap=3
yoffset=0
xoffset=0
background_color=
stdout="off"
'';
}

View File

@ -0,0 +1,6 @@
{ pkgs-stable, ... }: {
home.packages = with pkgs-stable; [
(blender.override { cudaSupport = true; })
aseprite
];
}

View File

@ -0,0 +1,8 @@
{ pkgs, pkgs-stable, ... }: {
home.packages = with pkgs-stable; [
vscode
jetbrains.pycharm-community
jetbrains.idea-community
android-studio
];
}

View File

@ -0,0 +1,12 @@
{ pkgs, pkgs-stable, inputs, ... }: {
home.packages = with pkgs; [
pkgs-stable.google-chrome
inputs.ayugram-desktop.packages.${pkgs.system}.ayugram-desktop
vesktop
obs-studio
mpv
obsidian
thunderbird
libreoffice
];
}

View File

@ -0,0 +1,21 @@
{ stdenv, lib, config, colors, ... }:
stdenv.mkDerivation {
name = "AGS theme";
src = ./ags;
dontUnpack = true;
patchPhase = ''
echo \$bg: \#${colors.base00}\; > colors.scss
echo \$surface0: \#${colors.base02}\; >> colors.scss
echo \$fg: \#${colors.base05}\; >> colors.scss
echo \$accent: \#${colors.base0B}\; >> colors.scss
'';
installPhase = ''
ls
mkdir $out
cp $src/* $out -r
mv colors.scss $out
'';
}

View File

@ -0,0 +1,12 @@
# Simple Bar Example
![simple-bar](https://github.com/user-attachments/assets/a306c864-56b7-44c4-8820-81f424f32b9b)
A simple bar for Hyprland using
- [Battery library](https://aylur.github.io/astal/guide/libraries/battery).
- [Hyprland library](https://aylur.github.io/astal/guide/libraries/hyprland).
- [Mpris library](https://aylur.github.io/astal/guide/libraries/mpris).
- [Network library](https://aylur.github.io/astal/guide/libraries/network).
- [Tray library](https://aylur.github.io/astal/guide/libraries/tray).
- [WirePlumber library](https://aylur.github.io/astal/guide/libraries/wireplumber).

View File

@ -0,0 +1,13 @@
import { App } from "astal/gtk3"
import style from "./style.scss"
import Bar from "./widget/Bar"
App.start({
css: style,
instanceName: "ags",
requestHandler(request, res) {
print(request)
res("ok")
},
main: () => App.get_monitors().map(Bar),
})

View File

@ -0,0 +1,97 @@
@use "sass:color";
@use "colors.scss" as *;
$radius: 10px;
%item {
all: unset;
background: $bg;
border-radius: $radius;
padding: 4px;
& + &, .item + & { margin-left: 4px; }
label { margin: 0 8px; }
}
window.Bar {
border: none;
box-shadow: none;
background-color: transparent;
color: $fg;
font-size: 1.1em;
font-weight: bold;
.Container {
margin: 10px 10px 0;
}
.Workspaces {
button {
all: unset;
&:hover label {
background: $surface0;
color: $accent;
}
&:active label {
background: $surface0;
color: $accent;
}
}
label {
transition: 200ms;
padding: 0 6px;
margin: 2px;
border-radius: $radius;
border: 1pt solid transparent;
}
.focused label {
background: $accent;
color: $bg;
border-color: $accent;
}
}
.Layout.en { color: $accent; }
.SysTray button {
all: unset;
padding: 8px;
border-radius: inherit;
&:hover {
background: $surface0;
}
}
.Media {
&.playing {
border: 2pt solid $accent;
}
.Cover {
min-height: 1.2em;
min-width: 1.2em;
border-radius: $radius;
background-position: center;
background-size: contain;
}
}
.Battery label {
padding-left: 0;
margin-left: 0;
}
.Time { padding: 0 8px; }
.AudioSlider icon { margin-left: 8px; }
.Workspaces, .Layout, .Media, .SysTray, .AudioSlider, .Time {
@extend %item;
}
}

View File

@ -0,0 +1,39 @@
import { App } from "astal/gtk3"
import { Astal, Gtk, Gdk } from "astal/gtk3"
import Time from "./elements/Time"
import Wifi from "./elements/Wifi"
import Audio from "./elements/Audio"
import Media from "./elements/Media"
import Layout from "./elements/Keyboard"
import SysTray from "./elements/SysTray"
import Workspaces from "./elements/Workspaces"
import BatteryLevel from "./elements/Battery"
export default function Bar(monitor: Gdk.Monitor) {
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor
return <window
className="Bar"
gdkmonitor={monitor}
exclusivity={Astal.Exclusivity.EXCLUSIVE}
anchor={TOP | LEFT | RIGHT}>
<centerbox className="Container">
<box hexpand halign={Gtk.Align.START}>
<Workspaces />
<Layout />
</box>
<box>
<Media />
</box>
<box hexpand halign={Gtk.Align.END} >
<SysTray />
<Wifi />
<Audio />
<BatteryLevel />
<Time />
</box>
</centerbox>
</window>
}

View File

@ -0,0 +1,11 @@
import { bind } from "astal"
import Wp from "gi://AstalWp"
export default function Audio() {
const speaker = Wp.get_default()?.audio.defaultSpeaker!
return <box className="AudioSlider">
<icon icon={bind(speaker, "volumeIcon")} />
<label label={bind(speaker, "volume").as(v => `${Math.floor(v*100)}%`)} />
</box>
}

View File

@ -0,0 +1,14 @@
import { bind } from "astal"
import Battery from "gi://AstalBattery"
export default function BatteryLevel() {
const bat = Battery.get_default()
return <box className="Battery"
visible={bind(bat, "isPresent")}>
<icon icon={bind(bat, "batteryIconName")} />
<label label={bind(bat, "percentage").as(p =>
`${Math.floor(p * 100)} %`
)} />
</box>
}

View File

@ -0,0 +1,12 @@
import { Variable, bind } from "astal"
import Hyprland from "gi://AstalHyprland"
export default function Layout() {
const hl = Hyprland.get_default();
let layout = Variable("en");
hl.connect("keyboard-layout", (_, __, l) => { layout.set(`${l}`.slice(0, 2).toLowerCase()) })
return <box className={bind(layout).as((l) => `Layout ${l}`)}>
<label label={bind(layout)}/>
</box>
}

View File

@ -0,0 +1,29 @@
import { Variable, bind } from "astal"
import { Gtk } from "astal/gtk3"
import Mpris from "gi://AstalMpris"
export default function Media() {
const mpris = Mpris.get_default()
// console.log(bind(mpris, "players").as(ps => ps[0] ? `${ps[0].title} ${ps[0].artist} ${ps[0].get_playback_status()}` : "-"));
return <box>
{bind(mpris, "players").as(ps => ps[0] ? (
<button
className={bind(ps[0], "playback-status").as(s => s == 0 ? "Media playing" : "Media")}
onClicked={() => ps[0].play_pause()}>
<box>
<box
className="Cover"
valign={Gtk.Align.CENTER}
css={bind(ps[0], "coverArt").as(cover =>
`background-image: url('${cover}');`
)}
/>
<label
label={bind(ps[0], "title").as(() =>ps[0].title.length < 80 ? ps[0].title : `${ps[0].title.slice(0, 77)}...`)}
/>
</box>
</button>
) : ("") )}
</box>
}

View File

@ -0,0 +1,22 @@
import { bind } from "astal"
import Tray from "gi://AstalTray"
export default function SysTray() {
const tray = Tray.get_default()
return <box className="item">
{bind(tray, "items").as(i => (i.length > 0) ? (
<box className="SysTray">
{bind(tray, "items").as(items => items.map(item => (
<menubutton
tooltipMarkup={bind(item, "tooltipMarkup")}
usePopover={false}
actionGroup={bind(item, "action-group").as(ag => ["dbusmenu", ag])}
menuModel={bind(item, "menu-model")}>
<icon gicon={bind(item, "gicon")} />
</menubutton>
)))}
</box>
) : ("") )}
</box>
}

View File

@ -0,0 +1,12 @@
import { Variable, GLib } from "astal"
export default function Time({ format = "%e %b - %H:%M %a" }) {
const time = Variable<string>("").poll(1000, () =>
GLib.DateTime.new_now_local().format(format)!)
return <label
className="Time"
onDestroy={() => time.drop()}
label={time()}
/>
}

View File

@ -0,0 +1,17 @@
import { bind } from "astal"
import Network from "gi://AstalNetwork"
export default function Wifi() {
const network = Network.get_default()
const wifi = bind(network, "wifi")
return <box visible={wifi.as(Boolean)}>
{wifi.as(wifi => wifi && (
<icon
tooltipText={bind(wifi, "ssid").as(String)}
className="Wifi"
icon={bind(wifi, "iconName")}
/>
))}
</box>
}

View File

@ -0,0 +1,21 @@
import { bind } from "astal"
import Hyprland from "gi://AstalHyprland"
export default function Workspaces() {
const hypr = Hyprland.get_default()
return <box className="Workspaces">
{bind(hypr, "workspaces").as(wss => wss
.filter(ws => !(ws.id >= -99 && ws.id <= -2)) // filter out special workspaces
.sort((a, b) => a.id - b.id)
.map(ws => (
<button
className={bind(hypr, "focusedWorkspace").as(fw =>
ws === fw ? "focused" : "")}
onClicked={() => ws.focus()}>
{ws.id}
</button>
))
)}
</box>
}

View File

@ -0,0 +1,22 @@
{ pkgs, inputs, ... }: {
home.packages = with pkgs; [
scrot
ffmpeg
yt-dlp
bat
fd
feh
imv
gromit-mpx
notify-desktop
rtorrent
gparted
git-lfs
unrar
inputs.tlock.packages.${system}.default
hexyl
jq
litecli
trashy
];
}

View File

@ -0,0 +1,232 @@
{ pkgs, lib, config, collection, swww_flags, inputs }: {
home.packages = with pkgs; [
kitty
pamixer
wofi
clipse
grimblast
wl-clipboard
cliphist
];
wayland.windowManager.hyprland =
let
colors = config.lib.stylix.colors;
wallpaper_changer = pkgs.writers.writePython3Bin "wallpaper_changer" {
libraries = [ pkgs.python3Packages.requests ];
flakeIgnore = [ "E501" "E111" "E701" "E241" "E731" ];
} /*py*/ ''
import requests as requests
from random import choice
from os import system, mkdir, listdir
from os.path import exists
notify = lambda s: system(f"notify-desktop Wallpaper '{s}'")
folder = "${config.home.homeDirectory}/Wallpapers"
url = "https://wallhaven.cc/api/v1/collections/${collection}"
with open("${config.sops.secrets."tokens/apis/wallhaven".path}") as f:
token = f.read()
notify("Updating wallpaper!")
try:
json = requests.get(url, params={'apikey': token}).json()
wallpaper = choice(json['data'])
link = wallpaper['path']
format = wallpaper['file_type']
id = wallpaper['id']
if format == "image/jpeg": ext = "jpg"
else: ext = "png"
filename = f"{id}.{ext}"
if not exists(f"{folder}/{filename}"):
if not exists(folder):
mkdir(f"{folder}")
notify("Downloading...")
with open(f"{folder}/{filename}", 'wb') as f:
r = requests.get(link)
f.write(r.content)
except requests.exceptions.ConnectionError:
notify("Offline mode")
filename = choice(listdir(folder))
finally:
system(f"${lib.getExe pkgs.swww} img {folder}/{filename} ${swww_flags}")
'';
clipsync = pkgs.writers.writeBash "clipsync" ''
while ${lib.getExe pkgs.clipnotify}; do
${lib.getExe pkgs.xclip} -q -sel clip -t image/png -o > /dev/null && \
${lib.getExe pkgs.xclip} -sel clip -t image/png -o | wl-copy
${lib.getExe pkgs.xclip} -q -sel clip -o > /dev/null && \
${lib.getExe pkgs.xclip} -sel clip -o | wl-copy
done
'';
in {
enable = true;
xwayland.enable = true;
package = inputs.hyprland.packages.${pkgs.system}.hyprland;
plugins = with inputs.hyprland-plugins.packages.${pkgs.system}; [
hyprbars
];
settings = {
"$mainMod" = "SUPER";
env = [
"LIBVA_DRIVER_NAME,nvidia"
"__GLX_VENDOR_LIBRARY_NAME,nvidia"
"GBM_BACKEND,nvidia"
"XDG_SESSION_TYPE,wayland"
"QT_QPA_PLATFORM,wayland"
"XDG_CURRENT_DESKTOP,Hyprland"
"XDG_SESSION_DESKTOP,Hyprland"
"WLR_NO_HARDWARE_CURSORS,1"
"XCURSOR_SIZE,36"
"XDG_SCREENSHOTS_DIR,~/screens"
];
cursor.no_hardware_cursors = true;
debug = {
disable_logs = false;
enable_stdout_logs = true;
};
input = {
kb_layout = "us,ru";
kb_variant = "lang";
kb_options = "grp:caps_toggle";
follow_mouse = 1;
touchpad = {
natural_scroll = false;
};
sensitivity = 0; # -1.0 - 1.0, 0 means no modification.
};
windowrule = [
"float, ^(imv)$"
"float, ^(feh)$"
"float, ^(mpv)$"
"float, ^(nmtui)$"
"float, title:^(Список друзей)"
"move onscreen cursor -50% -50%, ^(xdragon)$"
];
windowrulev2 = [
"float, class:(clipse)"
"size 622 652, class:(clipse)"
];
exec-once = [
"systemctl --user start plasma-polkit-agent"
"${lib.getExe' pkgs.swww "swww-daemon"}"
"${lib.getExe wallpaper_changer}"
"${clipsync}"
"clipse -listen"
"${lib.getExe' pkgs.udiskie "udiskie"}"
];
bind = [
"$mainMod, V, exec, kitty --class clipse -e clipse"
"$mainMod, Return, exec, kitty"
"$mainMod, Q, killactive,"
"$mainMod, M, exit,"
"$mainMod, E, exec, kitty -e sh -c yazi"
"$mainMod, F, togglefloating,"
"$mainMod, D, exec, wofi --show drun"
"$mainMod, P, pseudo, # dwindle"
"$mainMod, J, togglesplit, # dwindle"
# Move focus with mainMod + arrow keys
"$mainMod, left, movefocus, l"
"$mainMod, right, movefocus, r"
"$mainMod, up, movefocus, u"
"$mainMod, down, movefocus, d"
# Moving windows
"$mainMod SHIFT, left, swapwindow, l"
"$mainMod SHIFT, right, swapwindow, r"
"$mainMod SHIFT, up, swapwindow, u"
"$mainMod SHIFT, down, swapwindow, d"
# Window resizing X Y
"$mainMod CTRL, left, resizeactive, -60 0"
"$mainMod CTRL, right, resizeactive, 60 0"
"$mainMod CTRL, up, resizeactive, 0 -60"
"$mainMod CTRL, down, resizeactive, 0 60"
# Switch workspaces with mainMod + [0-9]
"$mainMod, 1, workspace, 1"
"$mainMod, 2, workspace, 2"
"$mainMod, 3, workspace, 3"
"$mainMod, 4, workspace, 4"
"$mainMod, 5, workspace, 5"
"$mainMod, 6, workspace, 6"
"$mainMod, 7, workspace, 7"
"$mainMod, 8, workspace, 8"
"$mainMod, 9, workspace, 9"
"$mainMod, 0, workspace, 10"
# Move active window to a workspace with mainMod + SHIFT + [0-9]
"$mainMod SHIFT, 1, movetoworkspacesilent, 1"
"$mainMod SHIFT, 2, movetoworkspacesilent, 2"
"$mainMod SHIFT, 3, movetoworkspacesilent, 3"
"$mainMod SHIFT, 4, movetoworkspacesilent, 4"
"$mainMod SHIFT, 5, movetoworkspacesilent, 5"
"$mainMod SHIFT, 6, movetoworkspacesilent, 6"
"$mainMod SHIFT, 7, movetoworkspacesilent, 7"
"$mainMod SHIFT, 8, movetoworkspacesilent, 8"
"$mainMod SHIFT, 9, movetoworkspacesilent, 9"
"$mainMod SHIFT, 0, movetoworkspacesilent, 10"
"$mainMod SHIFT, F, fullscreen"
# Scroll through existing workspaces with mainMod + scroll
"$mainMod, mouse_down, workspace, e+1"
"$mainMod, mouse_up, workspace, e-1"
# Keyboard backlight
"$mainMod, F3, exec, brightnessctl -d *::kbd_backlight set +33%"
"$mainMod, F2, exec, brightnessctl -d *::kbd_backlight set 33%-"
# Volume and Media Control
", XF86AudioRaiseVolume, exec, pamixer -i 5 "
", XF86AudioLowerVolume, exec, pamixer -d 5 "
", XF86AudioMute, exec, pamixer -t"
", XF86AudioMicMute, exec, pamixer --default-source -m"
# Brightness control
", XF86MonBrightnessDown, exec, brightnessctl set 5%- "
", XF86MonBrightnessUp, exec, brightnessctl set +5% "
# Waybar
"$mainMod, B, exec, pkill -SIGUSR1 waybar"
#"$mainMod, W, exec, pkill -SIGUSR2 waybar"
"$mainMod, W, exec, ${lib.getExe wallpaper_changer}"
];
# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = [
"$mainMod, mouse:272, movewindow"
"$mainMod, mouse:273, resizewindow"
];
};
};
}

7
modules/user/qt.nix Normal file
View File

@ -0,0 +1,7 @@
{
qt = {
enable = true;
platformTheme.name = "qtct";
style.name = "kvantum";
};
}

8
modules/user/sops.nix Normal file
View File

@ -0,0 +1,8 @@
{ config, ... }: {
sops = {
defaultSopsFile = ../../user/${config.home.username}/secrets.yaml;
age.keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
secrets."tokens/apis/wallhaven" = {};
};
}

7
modules/user/wofi.nix Normal file
View File

@ -0,0 +1,7 @@
{ pkgs, ... }: {
xdg.configFile."wofi/style.css".source = pkgs.fetchurl {
name = "style.css";
url = "https://github.com/joao-vitor-sr/wofi-themes-collection/raw/main/themes/nord.css";
sha256 = "sha256-rMDtE7Q0hmqd9LD+Ur/QR6cMan9ev6e9IyzpwY367c0=";
};
}

60
modules/user/yazi.nix Normal file
View File

@ -0,0 +1,60 @@
{ pkgs, lib, ... }: let
yazi-plugins = pkgs.fetchFromGitHub {
owner = "yazi-rs";
repo = "plugins";
rev = "7afba3a73cdd69f346408b77ea5aac26fe09e551";
hash = "sha256-w9dSXW0NpgMOTnBlL/tzlNSCyRpZNT4XIcWZW5NlIUQ=";
};
in {
programs.yazi = {
enable = true;
enableZshIntegration = true;
shellWrapperName = "y";
settings = {
manager = {
show_hidden = true;
};
preview = {
max_width = 1000;
max_height = 1000;
};
};
plugins = {
chmod = "${yazi-plugins}/chmod.yazi";
full-border = "${yazi-plugins}/full-border.yazi";
max-preview = "${yazi-plugins}/max-preview.yazi";
starship = pkgs.fetchFromGitHub {
owner = "Rolv-Apneseth";
repo = "starship.yazi";
rev = "247f49da1c408235202848c0897289ed51b69343";
sha256 = "sha256-0J6hxcdDX9b63adVlNVWysRR5htwAtP5WhIJ2AK2+Gs=";
};
};
initLua = ''
require("full-border"):setup()
require("starship"):setup()
'';
keymap = {
manager.prepend_keymap = [
{
on = "T";
run = "plugin --sync max-preview";
desc = "Maximize or restore the preview pane";
}
{
on = ["c" "m"];
run = "plugin chmod";
desc = "Chmod on selected files";
}
{
on = [ "<C-n>" ];
run = ''shell '${lib.getExe pkgs.xdragon} -x -i -T "$@"' --confirm'';
}
];
};
};
}

91
modules/user/zsh.nix Normal file
View File

@ -0,0 +1,91 @@
{ config, pkgs, ... }: {
home.packages = [ pkgs.nh ];
programs = {
zoxide.enable = true;
fzf.enable = true;
starship = {
enable = true;
enableZshIntegration = true;
settings = {
add_newline = true;
format = ''
$os$directory$git_branch$git_status
$nix_shell$status$character
'';
right_format = "$all";
cmake.disabled = true;
cmd_duration = {
format = "";
show_notifications = true;
notification_timeout = 10000;
};
git_branch.format = "on [$branch(:$remote_branch)]($style) ";
git_metrics.disabled = false;
git_status = {
conflicted = "!";
up_to_date = "ok";
stashed = "S";
modified = "M";
};
directory = {
truncation_length = 3;
fish_style_pwd_dir_length = 1;
read_only = " RO";
};
nix_shell.format = "[nix-shell]($style) ";
os.disabled = false;
python = {
symbol = "py ";
python_binary = ["python3" "python"];
};
status.disabled = false;
};
};
zellij.enable = true;
zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
shellAliases =
let
flakeDir = "~/nix";
in {
rb = "nh os switch ${flakeDir}";
upd = "nix flake update --flake ${flakeDir}";
upg = "sudo nixos-rebuild switch --upgrade --flake ${flakeDir}";
hms = "nh home switch ${flakeDir}";
rhms = ''${pkgs.bash} $(home-manager generations | fzf | awk -F '-> ' '{print $2 "/activate"}')''; #https://github.com/nix-community/home-manager/issues/1114#issuecomment-2067785129
conf = "$EDITOR ${flakeDir}/nixos/hosts/$(hostname)/configuration.nix";
pkgs = "$EDITOR ${flakeDir}/nixos/packages.nix";
ll = "ls -l";
se = "sudoedit";
ff = "fastfetch";
cat = "${pkgs.lib.getExe pkgs.bat}";
cd = "z";
lg = "lazygit";
};
initExtra = ''
eval "$(zoxide init zsh)"
eval "$(nh completions --shell zsh)"
source "$(fzf-share)/key-bindings.zsh"
source "$(fzf-share)/completion.zsh"
'';
history.size = 10000;
history.path = "${config.xdg.dataHome}/zsh/history";
oh-my-zsh.enable = true;
};
};
}