refactor: implement component-based architecture for enhanced maintainability

- Reorganize directory structure into core/, features/, and themes/
- Colocate application Nix logic, configs, scripts, and theme overrides
- Implement 'Inversion of Control' for theming: apps now pull theme-specific layouts
- Update flake.nix and shared library paths to match the new structure
- Document the new Feature-Centric architecture in README.md
This commit is contained in:
Bernardo Magri
2026-04-12 14:51:15 +01:00
parent a9ee79a5ce
commit bbdf34ced8
535 changed files with 119 additions and 127 deletions

View File

@@ -0,0 +1,2 @@
# Extra autostart processes
# exec-once = uwsm-app -- my-service

View File

@@ -0,0 +1,34 @@
# Application bindings
bindd = SUPER, RETURN, Terminal, exec, uwsm-app -- xdg-terminal-exec --dir="$(nomarchy-cmd-terminal-cwd)"
bindd = SUPER ALT, RETURN, Tmux, exec, uwsm-app -- xdg-terminal-exec --dir="$(nomarchy-cmd-terminal-cwd)" bash -c "tmux attach || tmux new -s Work"
bindd = SUPER SHIFT, RETURN, Browser, exec, nomarchy-launch-browser
bindd = SUPER SHIFT, F, File manager, exec, uwsm-app -- nautilus --new-window
bindd = SUPER ALT SHIFT, F, File manager (cwd), exec, uwsm-app -- nautilus --new-window "$(nomarchy-cmd-terminal-cwd)"
bindd = SUPER SHIFT, B, Browser, exec, nomarchy-launch-browser
bindd = SUPER SHIFT ALT, B, Browser (private), exec, nomarchy-launch-browser --private
bindd = SUPER SHIFT, M, Music, exec, nomarchy-launch-or-focus spotify
bindd = SUPER SHIFT, N, Editor, exec, nomarchy-launch-editor
bindd = SUPER SHIFT, D, Docker, exec, nomarchy-launch-tui lazydocker
bindd = SUPER SHIFT, G, Signal, exec, nomarchy-launch-or-focus ^signal$ "uwsm-app -- signal-desktop"
bindd = SUPER SHIFT, O, Obsidian, exec, nomarchy-launch-or-focus ^obsidian$ "uwsm-app -- obsidian -disable-gpu --enable-wayland-ime"
bindd = SUPER SHIFT, W, Typora, exec, uwsm-app -- typora --enable-wayland-ime
bindd = SUPER SHIFT, SLASH, Passwords, exec, uwsm-app -- 1password
# If your web app url contains #, type it as ## to prevent hyprland treating it as a comment
bindd = SUPER SHIFT, A, ChatGPT, exec, nomarchy-launch-webapp "https://chatgpt.com"
bindd = SUPER SHIFT ALT, A, Grok, exec, nomarchy-launch-webapp "https://grok.com"
bindd = SUPER SHIFT, C, Calendar, exec, nomarchy-launch-webapp "https://app.hey.com/calendar/weeks/"
bindd = SUPER SHIFT, E, Email, exec, nomarchy-launch-webapp "https://app.hey.com"
bindd = SUPER SHIFT, Y, YouTube, exec, nomarchy-launch-webapp "https://youtube.com/"
bindd = SUPER SHIFT ALT, G, WhatsApp, exec, nomarchy-launch-or-focus-webapp WhatsApp "https://web.whatsapp.com/"
bindd = SUPER SHIFT CTRL, G, Google Messages, exec, nomarchy-launch-or-focus-webapp "Google Messages" "https://messages.google.com/web/conversations"
bindd = SUPER SHIFT, P, Google Photos, exec, nomarchy-launch-or-focus-webapp "Google Photos" "https://photos.google.com/"
bindd = SUPER SHIFT, X, X, exec, nomarchy-launch-webapp "https://x.com/"
bindd = SUPER SHIFT ALT, X, X Post, exec, nomarchy-launch-webapp "https://x.com/compose/post"
# Add extra bindings
# bind = SUPER SHIFT, R, exec, alacritty -e ssh your-server
# Overwrite existing bindings, like putting Nomarchy Menu on Super + Space
# unbind = SUPER, SPACE
# bindd = SUPER, SPACE, Nomarchy menu, exec, nomarchy-menu

View File

@@ -0,0 +1,43 @@
source = ~/.config/nomarchy/current/theme/hyprlock.conf
general {
ignore_empty_input = true
}
background {
monitor =
color = $color
path = ~/.config/nomarchy/current/background
blur_passes = 3
}
animations {
enabled = false
}
input-field {
monitor =
size = 650, 100
position = 0, 0
halign = center
valign = center
inner_color = $inner_color
outer_color = $outer_color
outline_thickness = 4
font_family = JetBrainsMono Nerd Font
font_color = $font_color
placeholder_text = Enter Password
check_color = $check_color
fail_text = <i>$FAIL ($ATTEMPTS)</i>
rounding = 0
shadow_passes = 0
fade_on_empty = false
}
auth {
fingerprint:enabled = false
}

View File

@@ -0,0 +1,14 @@
# Makes hyprsunset do nothing to the screen by default
# Without this, the default applies some tint to the monitor
profile {
time = 07:00
identity = true
}
# To enable auto switch to nightlight, set in your .config/hypr/autostart:
# exec-once = uwsm app -- hyprsunset
# and use the following:
# profile {
# time = 20:00
# temperature = 4000
# }

View File

@@ -0,0 +1,53 @@
# Control your input devices
# See https://wiki.hypr.land/Configuring/Variables/#input
input {
# Use multiple keyboard layouts and switch between them with Left Alt + Right Alt
# kb_layout = us,dk,eu
# Use a specific keyboard variant if needed (e.g. intl for international keyboards)
# kb_variant = intl
kb_options = compose:caps # ,grp:alts_toggle
# Change speed of keyboard repeat
repeat_rate = 40
repeat_delay = 600
# Start with numlock on by default
numlock_by_default = true
# Increase sensitivity for mouse/trackpad (default: 0)
# sensitivity = 0.35
# Turn off mouse acceleration (default: false)
# force_no_accel = true
touchpad {
# Use natural (inverse) scrolling
# natural_scroll = true
# Use two-finger clicks for right-click instead of lower-right corner
# clickfinger_behavior = true
# Control the speed of your scrolling
scroll_factor = 0.4
# Enable the touchpad while typing
# disable_while_typing = false
# Left-click-and-drag with three fingers
# drag_3fg = 1
}
}
# Scroll nicely in the terminal
#windowrulev2 = match:class (Alacritty|kitty), scroll_touchpad 1.5
#windowrulev2 = match:class com.mitchellh.ghostty, scroll_touchpad 0.2
# Enable touchpad gestures for changing workspaces
# See https://wiki.hyprland.org/Configuring/Gestures/
# gesture = 3, horizontal, workspace
# Enable touchpad gestures for moving focus (helpful on scrolling layout)
# gesture = 3, left, dispatcher, movefocus, l
# gesture = 3, right, dispatcher, movefocus, r

View File

@@ -0,0 +1,34 @@
# Change the default Nomarchy look'n'feel
# https://wiki.hyprland.org/Configuring/Variables/#general
general {
# No gaps between windows or borders
# gaps_in = 0
# gaps_out = 0
# border_size = 0
# Change to niri-like side-scrolling layout
# layout = scrolling
}
# https://wiki.hyprland.org/Configuring/Variables/#decoration
decoration {
# Use round window corners
# rounding = 8
# Dim unfocused windows (0.0 = no dim, 1.0 = fully dimmed)
# dim_inactive = true
# dim_strength = 0.15
}
# https://wiki.hyprland.org/Configuring/Variables/#animations
animations {
# Disable all animations
# enabled = no
}
# https://wiki.hypr.land/Configuring/Variables/#layout
layout {
# Avoid overly wide single-window layouts on wide screens
# single_window_aspect_ratio = 1 1
}

View File

@@ -0,0 +1,23 @@
# See https://wiki.hyprland.org/Configuring/Monitors/
# List current monitors and resolutions possible: hyprctl monitors
# Format: monitor = [port], resolution, position, scale
# Optimized for retina-class 2x displays, like 13" 2.8K, 27" 5K, 32" 6K.
env = GDK_SCALE,2
monitor=,preferred,auto,auto
# Good compromise for 27" or 32" 4K monitors (but fractional!)
# env = GDK_SCALE,1.75
# monitor=,preferred,auto,1.6
# Straight 1x setup for low-resolution displays like 1080p or 1440p
# Or for ultrawide monitors like 34" 3440x1440 or 49" 5120x1440
# env = GDK_SCALE,1
# monitor=,preferred,auto,1
# Portrait/rotated secondary monitor (transform: 1 = 90°, 3 = 270°)
# monitor = DP-2, preferred, auto, 1, transform, 1
# Example for Framework 13 w/ 6K XDR Apple display
# monitor = DP-5, 6016x3384@60, auto, 2
# monitor = eDP-1, 2880x1920@120, auto, 2

View File

@@ -0,0 +1,47 @@
# Learn how to configure Hyprland: https://wiki.hyprland.org/Configuring/
# ============================================================================
# BEHAVIOR CONFIGS (keybindings, input, rules - non-visual)
# ============================================================================
# These are the Nomarchy defaults - don't edit these directly!
# Environment variables
source = ~/.config/nomarchy/default/hypr/envs.conf
# Keybindings
source = ~/.config/nomarchy/default/hypr/bindings/media.conf
source = ~/.config/nomarchy/default/hypr/bindings/clipboard.conf
source = ~/.config/nomarchy/default/hypr/bindings/tiling-v2.conf
source = ~/.config/nomarchy/default/hypr/bindings/utilities.conf
# Input settings
source = ~/.config/nomarchy/default/hypr/input.conf
# Window rules and layout
source = ~/.config/nomarchy/default/hypr/windows.conf
# Autostart applications
source = ~/.config/nomarchy/default/hypr/autostart.conf
# Look and feel (animations, layout behavior)
source = ~/.config/nomarchy/default/hypr/looknfeel.conf
# ============================================================================
# VISUAL CONFIGS (colors, theming)
# ============================================================================
# Theme colors - loaded from the currently active theme
source = ~/.config/nomarchy/current/theme/hyprland.conf
# ============================================================================
# USER OVERRIDES
# ============================================================================
# Your personal overrides - edit these files to customize Nomarchy!
source = ~/.config/hypr/monitors.conf
source = ~/.config/hypr/input.conf
source = ~/.config/hypr/bindings.conf
source = ~/.config/hypr/looknfeel.conf
source = ~/.config/hypr/autostart.conf
# Add any other personal Hyprland configuration below
# windowrule = workspace 5, match:class qemu

View File

@@ -0,0 +1,4 @@
screencopy {
allow_token_by_default = true
custom_picker_binary = hyprland-preview-share-picker
}

View File

@@ -0,0 +1,44 @@
{ config, pkgs, lib, ... }:
let
nomarchyLib = import ../lib { inherit lib; };
assetsPath = ../../assets/themes;
# Use shared wallpaper resolver
activeWallpaper = nomarchyLib.resolveWallpaper {
wallpaperPath = config.nomarchy.wallpaper;
themeName = config.nomarchy.theme;
inherit assetsPath;
};
hyprlandState = config.nomarchy.hyprland;
in
{
home.sessionVariables = lib.mkDefault {
WLR_NO_HARDWARE_CURSORS = "1";
HYPRLAND_LOG_WLR = "1";
};
wayland.windowManager.hyprland = {
enable = lib.mkDefault true;
settings = lib.mkDefault {
"debug" = {
"disable_logs" = false;
"enable_stdout_logs" = true;
};
"cursor" = {
"no_hardware_cursors" = true;
};
"general" = {
"gaps_in" = hyprlandState.gaps_in;
"gaps_out" = hyprlandState.gaps_out;
"border_size" = hyprlandState.border_size;
"col.active_border" = "rgb(${config.colorScheme.palette.base0E})";
"col.inactive_border" = "rgb(${config.colorScheme.palette.base03})";
};
};
extraConfig = lib.mkDefault ''
source = ~/.config/hypr/nomarchy.conf
'';
};
}

View File

@@ -0,0 +1,12 @@
$activeBorderColor = rgb(dcd7ba)
general {
col.active_border = $activeBorderColor
}
group {
col.border_active = $activeBorderColor
}
# Kanagawa backdrop is too strong for detault opacity
windowrule = opacity 0.98 0.95, match:tag terminal

View File

@@ -0,0 +1,26 @@
$activeBorderColor = rgb(f2fcff)
$activeShadowColor = rgb(6fb8e3)
$inactiveBorderColor = rgba(30486099)
$inactiveShadowColor = rgba(30486077)
general {
col.active_border = $activeBorderColor
col.inactive_border = $inactiveBorderColor
gaps_in = 8
gaps_out = 16
}
group {
col.border_active = $activeBorderColor
col.border_inactive = $inactiveBorderColor
}
decoration {
shadow {
enabled = true
range = 16
render_power = 4
color = $activeShadowColor
color_inactive = $inactiveShadowColor
}
}

View File

@@ -0,0 +1,9 @@
$activeBorderColor = rgb(81a1c1)
general {
col.active_border = $activeBorderColor
}
group {
col.border_active = $activeBorderColor
}

View File

@@ -0,0 +1,9 @@
$activeBorderColor = rgb(faa968)
general {
col.active_border = $activeBorderColor
}
group {
col.border_active = $activeBorderColor
}

View File

@@ -0,0 +1,61 @@
# --- Everforest Color Palette ---
$bg0 = rgba(2d353bee)
$bg1 = rgba(343f44ee)
$bg2 = rgba(3d484dee)
$bg3 = rgba(475258ee)
$bg4 = rgba(4f585eee)
$bg5 = rgba(56635fee)
$fg = rgba(d3c6aaee)
$red = rgba(e67e80ee)
$orange = rgba(e69875ee)
$yellow = rgba(dbbc7fee)
$green = rgba(a7c080ee)
$aqua = rgba(83c092ee)
$blue = rgba(7fbbb3ee)
$purple = rgba(d699b6ee)
$grey0 = rgba(7a8478ee)
$grey1 = rgba(859289ee)
$grey2 = rgba(9da9a0ee)
general {
gaps_in = 6
gaps_out = 12
border_size = 3
col.active_border = $fg
col.inactive_border = $bg5
layout = dwindle
resize_on_border = true
}
decoration {
rounding = 10
blur {
enabled = true
size = 5
passes = 3
new_optimizations = true
ignore_opacity = true
}
shadow {
enabled = true
range = 20
render_power = 3
color = rgba(00000044)
}
}
animations {
enabled = true
bezier = overshot, 0.05, 0.9, 0.1, 1.05
bezier = smoothOut, 0.36, 0, 0.66, -0.56
bezier = smoothIn, 0.25, 1, 0.5, 1
animation = windows, 1, 3, overshot, slide
animation = windowsOut, 1, 3, smoothOut, slide
animation = windowsMove, 1, 3, default
animation = border, 1, 3, default
animation = fade, 1, 3, smoothIn
animation = workspaces, 1, 3, smoothIn, slide
}