refactor: hand active dotfiles to Decman

This commit is contained in:
2026-08-13 22:57:25 +02:00
parent 9647feebfa
commit 34acd648c9
14 changed files with 0 additions and 652 deletions
@@ -1,3 +0,0 @@
# Used by the Noctalia Pi Status Bridge adapter and the Hyprland launcher.
PI_STATUS_BRIDGE_CLIENT=/home/alex/.npm-global/bin/pi-status-bridge-client
PI_STATUS_UI_BINARY=/home/alex/.local/bin/pi-status-ui
-44
View File
@@ -1,44 +0,0 @@
starship init fish | source
set fish_greeting ""
# Prefer Neovim for both explicit and editor-variable invocations.
alias vim nvim
set -gx EDITOR nvim
set -gx VISUAL nvim
# pyenv setup
while set pyenv_index (contains -i -- "/home/alex/.pyenv/shims" $PATH)
set -eg PATH[$pyenv_index]
end
set -e pyenv_index
set -gx PATH '/home/alex/.pyenv/shims' $PATH
set -gx PYENV_SHELL fish
command pyenv rehash 2>/dev/null
function pyenv
set command $argv[1]
set -e argv[1]
switch "$command"
case rehash shell
source (pyenv "sh-$command" $argv|psub)
case "*"
command pyenv "$command" $argv
end
end
# bun
set --export BUN_INSTALL "$HOME/.bun"
set --export PATH $BUN_INSTALL/bin $PATH
# opencode
fish_add_path /home/alex/.opencode/bin
# Yazi wrapper that keeps the shell in its selected directory.
function y
set tmp (mktemp -t "yazi-cwd.XXXXXX")
command yazi $argv --cwd-file="$tmp"
if read -z cwd <"$tmp"; and [ "$cwd" != "$PWD" ]; and test -d "$cwd"
builtin cd -- "$cwd"
end
command rm -f -- "$tmp"
end
-6
View File
@@ -1,6 +0,0 @@
# Non-locking Wayland screen blanker. It covers every monitor in black and
# dismisses itself on any key press or mouse click; it never changes DPMS.
listener {
timeout = 300
on-timeout = /home/alex/.local/bin/wayshell-blanker
}
-164
View File
@@ -1,164 +0,0 @@
-- Shared Hyprland profile. yadm deploys machine.lua for the active class.
--
-- Scope: preserve launch, media, directional focus/move, workspace, scratchpad,
-- floating, fullscreen, and window-placement muscle memory. i3's split-tree,
-- stacking/tabbed, and resize-mode behavior is intentionally deferred.
local machine = dofile(os.getenv("HOME") .. "/.config/hypr/machine.lua")
for _, monitor in ipairs(machine.monitors or {}) do
hl.monitor(monitor)
end
local main_mod = "SUPER"
local terminal = "kitty"
local input = {
kb_layout = "us",
kb_variant = "intl",
numlock_by_default = true,
}
for key, value in pairs(machine.input or {}) do
input[key] = value
end
hl.config({
input = input,
general = {
gaps_in = 4,
-- Keep a thin black perimeter so the bottom border remains on-screen.
gaps_out = 2,
border_size = 2,
col = {
-- Muted Ember tones: visible focus without a high-brightness OLED edge.
active_border = "rgba(c9782ed9)",
inactive_border = "rgba(2a190fa6)",
},
},
decoration = {
rounding = 0,
},
animations = {
enabled = false,
},
binds = {
-- Selecting the current workspace again returns to the last workspace.
workspace_back_and_forth = true,
},
})
-- Three-finger horizontal swipes change workspaces; touchscreens remain excluded
-- by Hyprland's default workspace_swipe_touch = false behavior.
hl.gesture({
fingers = 3,
direction = "horizontal",
action = "workspace",
})
-- Dynamically hide the border when a workspace has exactly one tiled app.
hl.workspace_rule({
workspace = "w[t1]",
no_border = true,
})
-- Application and session bindings.
local noctalia_ipc = "noctalia msg "
local pi_status_ui_toggle = 'ui="${PI_STATUS_UI_BINARY:-$HOME/.local/bin/pi-status-ui}"; if test -x "$ui"; then setsid -f env TMPDIR=/tmp "$ui" --toggle >/tmp/pi-status-ui.log 2>&1; fi'
-- Tap and release Super on its own to open Noctalia's control-center home.
hl.bind(main_mod .. " + SUPER_L", hl.dsp.exec_cmd(noctalia_ipc .. "panel-toggle control-center"), { release = true })
hl.bind(main_mod .. " + RETURN", hl.dsp.exec_cmd(terminal))
hl.bind(main_mod .. " + CTRL + RETURN", hl.dsp.exec_cmd(terminal .. " -e zellij"))
hl.bind(main_mod .. " + SHIFT + RETURN", hl.dsp.exec_cmd("rofi -show combi"))
hl.bind(main_mod .. " + SPACE", hl.dsp.exec_cmd(pi_status_ui_toggle))
hl.bind(main_mod .. " + N", hl.dsp.exec_cmd(noctalia_ipc .. "panel-toggle alex/knowledge-lookup:panel"))
hl.bind(main_mod .. " + S", hl.dsp.exec_cmd(noctalia_ipc .. "panel-toggle control-center"))
hl.bind(main_mod .. " + SHIFT + F", hl.dsp.exec_cmd(noctalia_ipc .. "bar-toggle main"))
hl.bind(main_mod .. " + SHIFT + R", hl.dsp.exec_cmd("hyprctl reload"))
hl.bind(main_mod .. " + CTRL + L", hl.dsp.exec_cmd("command -v hyprlock >/dev/null && hyprlock || loginctl lock-session"))
hl.bind(main_mod .. " + CTRL + SHIFT + ALT + S", hl.dsp.exec_cmd("systemctl suspend"))
hl.bind(main_mod .. " + CTRL + SHIFT + ALT + H", hl.dsp.exec_cmd("systemctl hibernate"))
hl.bind(main_mod .. " + SHIFT + C", hl.dsp.window.close())
hl.bind(main_mod .. " + CTRL + SHIFT + F", hl.dsp.exec_cmd("/home/alex/.local/bin/screenshot-select"))
-- Audio, media, brightness, and calculator keys.
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true })
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true })
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { locked = true })
hl.bind(main_mod .. " + XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true })
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true })
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
hl.bind(main_mod .. " + XF86AudioRaiseVolume", hl.dsp.exec_cmd("playerctl next"), { locked = true })
hl.bind(main_mod .. " + XF86AudioLowerVolume", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd('light -A 5'), { locked = true })
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd('light -U 5'), { locked = true })
hl.bind(main_mod .. " + XF86MonBrightnessDown", hl.dsp.exec_cmd('light -S 0.0'), { locked = true })
hl.bind(main_mod .. " + XF86MonBrightnessUp", hl.dsp.exec_cmd('light -S 100'), { locked = true })
hl.bind("XF86Calculator", hl.dsp.exec_cmd("qalculate-qt"), { locked = true })
-- Retain i3's hjkl and arrow-key directional workflow.
for _, direction in ipairs({ "left", "down", "up", "right" }) do
local key = ({ left = "H", down = "J", up = "K", right = "L" })[direction]
hl.bind(main_mod .. " + " .. key, hl.dsp.focus({ direction = direction }))
hl.bind(main_mod .. " + " .. direction, hl.dsp.focus({ direction = direction }))
end
for key, direction in pairs({ H = "l", J = "d", K = "u", L = "r", LEFT = "l", DOWN = "d", UP = "u", RIGHT = "r" }) do
hl.bind(main_mod .. " + SHIFT + " .. key, hl.dsp.window.move({ direction = direction }))
end
-- Numbered workspaces match the i3 profile. Shift moves; Ctrl moves and follows.
for workspace = 1, 9 do
local key = tostring(workspace)
hl.bind(main_mod .. " + " .. key, hl.dsp.focus({ workspace = workspace }))
hl.bind(main_mod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = workspace }))
hl.bind(main_mod .. " + CTRL + " .. key, hl.dsp.window.move({ workspace = workspace, follow = true }))
end
-- Match i3's back-and-forth workflow: Super+Tab switches to the last workspace;
-- selecting the current numbered workspace also returns to it.
hl.bind(main_mod .. " + TAB", hl.dsp.focus({ workspace = "previous" }))
hl.bind(main_mod .. " + CTRL + RIGHT", hl.dsp.focus({ workspace = "+1" }))
hl.bind(main_mod .. " + CTRL + LEFT", hl.dsp.focus({ workspace = "-1" }))
-- Hyprland special workspaces are the Wayland analogue of the i3 scratchpad.
hl.bind(main_mod .. " + MINUS", hl.dsp.workspace.toggle_special("scratchpad"))
hl.bind(main_mod .. " + SHIFT + MINUS", hl.dsp.window.move({ workspace = "special:scratchpad" }))
-- Keep the i3 floating and fullscreen shortcuts. Layout-specific binds are deferred.
hl.bind(main_mod .. " + F", hl.dsp.window.fullscreen({ action = "toggle" }))
hl.bind(main_mod .. " + SHIFT + SPACE", hl.dsp.window.float({ action = "toggle" }))
hl.bind(main_mod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind(main_mod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
-- i3 for_window/assign translations. Verify Wayland class/title values with `hyprctl clients`.
local function float_rule(name, match, border_size)
hl.window_rule({
name = name,
match = match,
float = true,
border_size = border_size,
})
end
hl.window_rule({ name = "obsidian-workspace", match = { class = "^obsidian$" }, workspace = "8" })
hl.window_rule({ name = "thunderbird-workspace", match = { class = "^Thunderbird$" }, workspace = "9" })
float_rule("pi-status-ui", { class = "^(pi-status-ui|Pi-status-ui)$" }, 1)
float_rule("alsamixer", { title = "^alsamixer$" }, 1)
float_rule("qalculate", { title = "^Qalculate!$" })
float_rule("psensor", { class = "^Psensor$" })
float_rule("lxrandr", { title = "^lxrandr$" })
float_rule("blueman", { class = "^Blueman-manager$" })
float_rule("gparted", { class = "^GParted$" })
float_rule("pavucontrol", { class = "^pavucontrol$" })
float_rule("volume-control", { title = "^Volume Control$" })
float_rule("virtualbox", { class = ".*VirtualBox.*" })
hl.window_rule({ name = "virtualbox-manager-tiles", match = { class = ".*VirtualBox Manager.*" }, tile = true })
hl.window_rule({ name = "virtualbox-machine-tiles", match = { class = ".*VirtualBox Machine.*" }, tile = true })
-- Send music clients to the existing scratchpad without stealing startup focus.
hl.window_rule({ name = "spotify-music", match = { class = "^Spotify$" }, workspace = "special:scratchpad silent", no_initial_focus = true })
hl.window_rule({ name = "deezer-music", match = { class = "^Deezer$" }, workspace = "special:scratchpad silent", no_initial_focus = true })
hl.on("hyprland.start", function()
for _, command in ipairs(machine.startup or {}) do
hl.exec_cmd(command)
end
end)
-45
View File
@@ -1,45 +0,0 @@
# Minimal Hyprlock screen using the current desktop as a blurred backdrop.
$font = Sans
general {
hide_cursor = true
}
background {
monitor =
path = screenshot
blur_passes = 3
}
input-field {
monitor =
size = 20%, 5%
outline_thickness = 2
inner_color = rgba(0, 0, 0, 0.25)
outer_color = rgba(eeeeeecc)
check_color = rgba(8ec07ccc)
fail_color = rgba(fb4934cc)
font_color = rgb(eeeeee)
fade_on_empty = false
rounding = 12
font_family = $font
placeholder_text = Input password...
fail_text = $PAMFAIL
position = 0, -20
halign = center
valign = center
}
label {
monitor =
text = $TIME
font_size = 72
font_family = $font
position = 0, 120
halign = center
valign = center
}
@@ -1,23 +0,0 @@
-- Desktop-only display and startup profile.
return {
monitors = {
{
output = "HDMI-A-1",
mode = "3840x2160@120",
position = "0x0",
scale = 1,
},
},
startup = {
"noctalia",
"hypridle",
-- Electron's tray icon registers only when the SNI watcher already exists.
"sh -c 'sleep 2; exec mullvad-vpn'",
"obsidian",
"thunderbird",
"nextcloud",
"spotify",
"brave",
"alacritty -e tmux",
},
}
@@ -1,30 +0,0 @@
-- Laptop profile: leave monitor selection to Hyprland's hotplug support.
-- Noctalia replaces the i3-era Redshift, Polybar, Blueman Applet, and Picom stack.
return {
input = {
touchpad = {
-- Standard laptop behavior: one/two/three-finger taps map to
-- left/right/middle click, and a second tap held down starts a drag.
tap_to_click = true,
tap_button_map = "lrm",
tap_and_drag = true,
drag_lock = false,
clickfinger_behavior = true,
disable_while_typing = true,
-- Preserve natural two-finger scrolling at the default sensitivity.
natural_scroll = true,
scroll_factor = 1.0,
},
},
monitors = {},
startup = {
"noctalia",
-- Start after Noctalia has claimed the StatusNotifier watcher.
"sh -c 'sleep 2; exec mullvad-vpn'",
"obsidian",
"thunderbird",
"nextcloud",
"spotify",
},
}
-84
View File
@@ -1,84 +0,0 @@
# Shared Noctalia defaults. Keep GUI experiments in state; promote durable choices here.
[shell]
setup_wizard_enabled = false
offline_mode = true
external_ip_enabled = false
telemetry_enabled = false
# Noctalia owns idle handling so ScreenSaver/Wayland idle inhibitors (such as
# browser video playback) prevent these actions. Power displays down after five
# minutes, lock after ten minutes, then suspend-then-hibernate after thirty.
[idle]
behavior_order = ["lock", "screen-off", "suspend-then-hibernate"]
pre_action_fade_seconds = 2.0
[idle.behavior.lock]
action = "lock"
enabled = true
timeout = 600
[idle.behavior.screen-off]
action = "screen_off"
enabled = true
timeout = 300
[idle.behavior.suspend-then-hibernate]
action = "command"
command = "loginctl lock-session && systemctl suspend-then-hibernate"
enabled = true
timeout = 1800
[theme]
mode = "dark"
source = "custom"
custom_palette = "Ember OLED"
pure_black_dark = true
# Noctalia merges files alphabetically. Keep reusable modules here; machine-specific
# layout and hardware settings live in 90-machine.toml, while 99-extend.toml is local.
[plugins]
enabled = ["alex/system-status", "alex/knowledge-lookup"]
[widget.cpu]
type = "alex/system-status:cpu"
[widget.ram]
type = "alex/system-status:memory"
[widget.network-rate]
type = "alex/system-status:network-rate"
[widget.idle-inhibitors]
type = "alex/system-status:inhibitors"
[widget.knowledge-lookup]
type = "alex/knowledge-lookup:bar"
[widget.temp]
type = "sysmon"
stat = "cpu_temp"
visualization = "none"
show_value = true
[widget.disk]
type = "sysmon"
stat = "disk_used_pct"
visualization = "none"
show_value = true
path = "/"
[desktop_widgets]
enabled = false
[wallpaper]
enabled = true
fill_color = "#000000"
[wallpaper.default]
path = "color:#000000"
[nightlight]
enabled = true
force = false
temperature_day = 6500
temperature_night = 2500
@@ -1,91 +0,0 @@
# Desktop-specific shell layout and hardware telemetry.
# Pi Status Bridge is installed locally from ~/projects/pi-status-bridge.
[plugins]
enabled = ["alex/system-status", "alex/pi-status-bridge", "alex/knowledge-lookup"]
[widget.pi-status]
type = "alex/pi-status-bridge:bridge"
[bar.main]
position = "bottom"
layer = "top"
scale = 0.95
capsule_radius = 5
center = ["group:g3", "notifications"]
end = ["group:g2", "group:g6", "group:g1", "session"]
font_weight = 400
margin_ends = 0
padding = 0
panel_overlap = 3
radius = 0
shadow = false
# Keep the desktop status bar visible and reserve its screen edge.
auto_hide = false
smart_auto_hide = false
reserve_space = true
start = ["tray", "group:g4", "privacy"]
thickness = 39
widget_spacing = 10
[[bar.main.capsule_group]]
enabled = true
fill = "surface_variant"
id = "g1"
members = ["idle-inhibitors", "caffeine", "date", "clock"]
opacity = 1.0
padding = 6.0
[[bar.main.capsule_group]]
enabled = true
fill = "surface_variant"
id = "g2"
members = ["network", "bluetooth"]
opacity = 1.0
padding = 6.0
[[bar.main.capsule_group]]
enabled = true
fill = "surface_variant"
id = "g3"
members = ["launcher", "media", "control-center", "clipboard"]
opacity = 1.0
padding = 6.0
radius = 5.0
[[bar.main.capsule_group]]
enabled = true
fill = "surface_variant"
id = "g4"
members = ["pi-status", "cpu", "temp", "ram", "gpu", "gpu_temp", "disk"]
opacity = 1.0
padding = 6.0
[[bar.main.capsule_group]]
enabled = true
fill = "surface_variant"
id = "g6"
members = ["input_volume", "volume"]
opacity = 1.0
padding = 6.0
radius = 5.0
[widget.gpu]
type = "sysmon"
stat = "gpu_usage"
visualization = "graph"
show_value = true
[widget.gpu_temp]
type = "sysmon"
stat = "gpu_temp"
visualization = "none"
show_value = true
[control_center]
sidebar = "full"
sidebar_section = "full"
width = 880
[system.monitor]
# GPU polling is disabled by Noctalia by default; enable it for the RTX 3090 widgets.
gpu_poll_seconds = 2.0
@@ -1,88 +0,0 @@
# Laptop-specific Noctalia layout. Shared privacy/theme defaults live in 10-base.toml.
[bar.main]
position = "top"
layer = "top"
scale = 0.95
capsule_radius = 5
center = ["group:g3", "notifications"]
end = ["group:g2", "group:g6", "group:g5", "group:g1", "session"]
font_weight = 400
margin_ends = 0
padding = 0
panel_overlap = 3
radius = 0
shadow = false
auto_hide = false
smart_auto_hide = false
reserve_space = true
start = ["tray", "group:g4"]
# Accommodate the battery-rate widget's wattage + ETA lines without clipping.
thickness = 39
widget_spacing = 10
[[bar.main.capsule_group]]
enabled = true
fill = "surface_variant"
id = "g1"
members = ["idle-inhibitors", "caffeine", "date", "clock"]
opacity = 1.0
padding = 6.0
[[bar.main.capsule_group]]
enabled = true
fill = "surface_variant"
id = "g2"
members = ["network", "bluetooth"]
opacity = 1.0
padding = 6.0
[[bar.main.capsule_group]]
enabled = true
fill = "surface_variant"
id = "g3"
members = ["launcher", "media", "control-center", "clipboard"]
opacity = 1.0
padding = 6.0
radius = 5.0
[[bar.main.capsule_group]]
enabled = true
fill = "surface_variant"
id = "g4"
members = ["cpu", "temp", "ram", "gpu-mode", "disk"]
opacity = 1.0
padding = 6.0
[[bar.main.capsule_group]]
enabled = true
fill = "surface_variant"
id = "g5"
members = ["battery-rate", "battery", "power_profile"]
opacity = 1.0
padding = 6.0
radius = 5.0
[[bar.main.capsule_group]]
enabled = true
fill = "surface_variant"
id = "g6"
members = ["input_volume", "volume"]
opacity = 1.0
padding = 6.0
radius = 5.0
[widget.battery-rate]
type = "alex/system-status:battery-rate"
[widget.gpu-mode]
type = "alex/system-status:gpu-mode"
# Only suspend-then-hibernate after 30 minutes when UPower confirms battery power.
# The command fails closed on AC or when UPower is unavailable.
[idle.behavior.suspend-then-hibernate]
command = "busctl get-property org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.UPower OnBattery 2>/dev/null | grep -qx 'b true' && loginctl lock-session && systemctl suspend-then-hibernate"
[control_center]
sidebar = "full"
sidebar_section = "full"
width = 720
-48
View File
@@ -1,48 +0,0 @@
{
"dark": {
"mPrimary": "#ff8800",
"mOnPrimary": "#1a0d00",
"mSecondary": "#ffb05c",
"mOnSecondary": "#2b1600",
"mTertiary": "#ffcc99",
"mOnTertiary": "#2b1600",
"mError": "#ff6b4a",
"mOnError": "#2b0700",
"mSurface": "#050403",
"mOnSurface": "#fff1e6",
"mSurfaceVariant": "#1a110c",
"mOnSurfaceVariant": "#f4c7a1",
"mOutline": "#6e4a31",
"mShadow": "#000000",
"mHover": "#2a190f",
"mOnHover": "#fff1e6",
"terminal": {
"background": "#050403",
"foreground": "#fff1e6",
"cursor": "#fff1e6",
"cursorText": "#050403",
"selectionBg": "#3b220f",
"selectionFg": "#fff1e6",
"normal": {
"black": "#050403",
"red": "#ff6b4a",
"green": "#c98a45",
"yellow": "#ffb05c",
"blue": "#c97c45",
"magenta": "#d98a5c",
"cyan": "#e8a76a",
"white": "#fff1e6"
},
"bright": {
"black": "#6e4a31",
"red": "#ff8f72",
"green": "#e8ad68",
"yellow": "#ffca80",
"blue": "#e8a06a",
"magenta": "#f0ad82",
"cyan": "#ffd0a0",
"white": "#ffffff"
}
}
}
}
@@ -1 +0,0 @@
../idle-inhibitor-monitor.service
@@ -1,12 +0,0 @@
[Unit]
Description=Track session ScreenSaver idle inhibitors for Noctalia
After=graphical-session.target
PartOf=graphical-session.target
[Service]
ExecStart=%h/.local/bin/idle-inhibitor-monitor
Restart=on-failure
RestartSec=2
[Install]
WantedBy=default.target
@@ -1,13 +0,0 @@
[Unit]
Description=Pi Status Bridge home agent
After=graphical-session.target
[Service]
Type=simple
Environment=PATH=/home/alex/.npm-global/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/usr/bin/env pi-status-bridge --session-root %h/.local/state/pi-status-bridge/sessions
Restart=on-failure
RestartSec=3
[Install]
WantedBy=default.target