nixos/hosts/frame12/modules/home-manager/home.nix

622 lines
22 KiB
Nix

{
inputs,
config,
pkgs,
lib,
osConfig,
...
}:
let
unstable = import inputs.nixpkgs-unstable {
system = "x86_64-linux";
config.allowUnfree = true;
};
in
{
imports = [
../../../../shared/modules/home-manager/base-home.nix
];
baseHome = {
enable = true;
userName = "nate";
fullName = "Nate Anderson";
email = "n8r@tuta.io";
stateVersion = "25.05";
hostDir = "frame12";
};
# Additional zsh config — direnv hook + yt-audio function
programs.zsh.initContent = ''
eval "$(direnv hook zsh)"
yt-audio() {
nix-shell -p yt-dlp --run "yt-dlp -x $1 --audio-format mp3"
}
'';
# Additional shell aliases beyond base
programs.zsh.shellAliases = {
grep = "rg";
ccat = "cat";
catp = "bat --paging=never -p";
};
programs.zsh.profileExtra = ''
export XDG_DATA_DIRS=$XDG_DATA_DIRS:/usr/share:/var/lib/flatpak/exports/share:$HOME/.local/share/flatpak/exports/share
'';
# Additional programs
programs.direnv = {
enable = true;
enableZshIntegration = true;
nix-direnv.enable = true;
};
programs.delta = {
enable = true;
enableGitIntegration = true;
};
# KDEConnect (HM-level indicator)
services.kdeconnect = {
enable = true;
indicator = true;
};
# Additional user packages
home.packages = with pkgs; [
#
# Dev Tools
#
jq
python3
unstable.claude-code
nodejs_24
docker-compose
### LSP's
nil
nodePackages_latest.bash-language-server
openscad-lsp
vscode-langservers-extracted # provides eslint, markdown, json, css, and html lsp
ltex-ls
python313Packages.python-lsp-server
### Misc
usbutils
fw-ectool
# Colemak-DH EC remap scripts
(writeShellScriptBin "colemak-dh" ''
# Apply Colemak-DH layout via EC
CURRENT=$(sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d0,b7,b8,w0 2>/dev/null | grep '|' | head -1 | awk '{print $11}')
if [ "$CURRENT" = "2b" ]; then
echo "Colemak-DH already active, skipping."
exit 0
fi
echo "Applying Colemak-DH layout..."
# Top row remaps (QWERTY Colemak-DH)
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b8,w2b # e(7,8) f
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b9,w4d # r(7,9) p
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b2,b3,w32 # t(2,3) b
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b2,b6,w3b # y(2,6) j
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b1,w4b # u(7,1) l
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b2,w3c # i(7,2) u
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b3,w35 # o(7,3) y
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b4,w4c # p(7,4) ;
# Home row remaps (QWERTY Colemak-DH)
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b3,b4,w2d # s(3,4) r
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b2,w1b # d(4,2) s
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b3,w2c # f(4,3) t
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b1,b6,w3a # h(1,6) m
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b6,w31 # j(4,6) n
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b5,w24 # k(4,5) e
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b9,w43 # l(4,9) i
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b8,w44 # ;(4,8) o
# Bottom row with angle mod (QWERTY Colemak-DH)
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b6,b1,w22 # z(6,1) x
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b5,b8,w21 # x(5,8) c
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b5,b5,w23 # c(5,5) d
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b0,b3,w1a # b(0,3) z
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b0,b5,w42 # n(0,5) k
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b5,bb,w33 # m(5,b) h
echo "Colemak-DH layout applied."
'')
(writeShellScriptBin "qwerty" ''
# Restore QWERTY layout via EC
CURRENT=$(sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d0,b7,b8,w0 2>/dev/null | grep '|' | head -1 | awk '{print $11}')
if [ "$CURRENT" = "24" ]; then
echo "QWERTY already active, skipping."
exit 0
fi
echo "Restoring QWERTY layout..."
# Top row - restore original scancodes
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b8,w24 # e(7,8) e
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b9,w2d # r(7,9) r
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b2,b3,w2c # t(2,3) t
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b2,b6,w35 # y(2,6) y
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b1,w3c # u(7,1) u
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b2,w43 # i(7,2) i
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b3,w44 # o(7,3) o
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b7,b4,w4d # p(7,4) p
# Home row - restore original scancodes
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b3,b4,w1b # s(3,4) s
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b2,w23 # d(4,2) d
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b3,w2b # f(4,3) f
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b1,b6,w33 # h(1,6) h
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b6,w3b # j(4,6) j
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b5,w42 # k(4,5) k
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b9,w4b # l(4,9) l
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b4,b8,w4c # ;(4,8) ;
# Bottom row - restore original scancodes
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b6,b1,w1a # z(6,1) z
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b5,b8,w22 # x(5,8) x
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b5,b5,w21 # c(5,5) c
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b0,b3,w32 # b(0,3) b
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b0,b5,w31 # n(0,5) n
sudo ${fw-ectool}/bin/ectool raw 0x3E0C d1,d1,b5,bb,w3a # m(5,b) m
echo "QWERTY layout restored."
'')
#
# Unix tools
#
duf
dust
fd
ripgrep
tre-command
gtop
neofetch
nmap
gnupg
pinentry-tty
#
# Photo / Video
#
imv
ffmpeg
yt-dlp
#
# Other
#
keepassxc
yubioath-flutter
#
# Style — additional fonts
#
unstable.nerd-fonts.hurmit
unstable.nerd-fonts.overpass
recursive
];
# Local dotfiles (host-specific, override shared)
home.file = lib.mkMerge [
(
let
localDotfilesPath = ../../dotfiles;
in
if builtins.pathExists localDotfilesPath && builtins.readDir localDotfilesPath != { } then
builtins.listToAttrs (
map (name: {
name = "${config.xdg.configHome}/${name}";
value = {
source = localDotfilesPath + "/${name}";
};
}) (builtins.attrNames (builtins.readDir localDotfilesPath))
)
else
{ }
)
];
# Override Flatpak Steam to disable GPU acceleration (fixes black window on Niri)
xdg.desktopEntries."com.valvesoftware.Steam" = {
name = "Steam";
exec = "flatpak run com.valvesoftware.Steam -cef-disable-gpu %U";
icon = "steam";
terminal = false;
categories = [ "Game" ];
mimeType = [
"x-scheme-handler/steam"
"x-scheme-handler/steamlink"
];
};
# Git autosync for star-command
services.git-autosync = {
enable = true;
repos.star-command = {
path = "/home/nate/source/star-command";
gitName = "Nate Anderson";
gitEmail = "n8r@tuta.io";
};
};
# Enable Noctalia shell (replaces Waybar, SwayNC, SwayOSD, wlsunset)
noctaliaShell = {
enable = true;
settings = {
settingsVersion = 51;
bar = {
barType = "simple";
position = "top";
monitors = [ ];
density = "spacious";
showOutline = false;
showCapsule = true;
capsuleOpacity = 1.0;
capsuleColorKey = "none";
backgroundOpacity = 1.0;
useSeparateOpacity = false;
floating = false;
marginVertical = 4;
marginHorizontal = 4;
frameThickness = 8;
frameRadius = 12;
outerCorners = true;
hideOnOverview = false;
displayMode = "always_visible";
autoHideDelay = 500;
autoShowDelay = 150;
widgets = {
left = [
{ icon = "rocket"; iconColor = "none"; id = "Launcher"; }
{ clockColor = "none"; customFont = ""; formatHorizontal = "HH:mm ddd, MMM dd"; formatVertical = "HH mm - dd MM"; id = "Clock"; tooltipFormat = "HH:mm ddd, MMM dd"; useCustomFont = false; }
{ id = "plugin:weekly-calendar"; }
{ compactMode = true; diskPath = "/"; iconColor = "none"; id = "SystemMonitor"; showCpuFreq = false; showCpuTemp = true; showCpuUsage = true; showDiskAvailable = false; showDiskUsage = false; showDiskUsageAsPercent = false; showGpuTemp = false; showLoadAverage = false; showMemoryAsPercent = false; showMemoryUsage = true; showNetworkStats = false; showSwapUsage = false; textColor = "none"; useMonospaceFont = true; }
{ colorizeIcons = false; hideMode = "hidden"; id = "ActiveWindow"; maxWidth = 145; scrollingMode = "hover"; showIcon = true; textColor = "none"; useFixedWidth = false; }
{ compactMode = false; compactShowAlbumArt = true; compactShowVisualizer = false; hideMode = "hidden"; hideWhenIdle = false; id = "MediaMini"; maxWidth = 145; panelShowAlbumArt = true; panelShowVisualizer = true; scrollingMode = "hover"; showAlbumArt = true; showArtistFirst = true; showProgressRing = true; showVisualizer = false; textColor = "none"; useFixedWidth = false; visualizerType = "linear"; }
];
center = [
{ characterCount = 2; colorizeIcons = false; emptyColor = "secondary"; enableScrollWheel = true; focusedColor = "primary"; followFocusedScreen = false; groupedBorderOpacity = 1.0; hideUnoccupied = false; iconScale = 0.8; id = "Workspace"; labelMode = "index"; occupiedColor = "secondary"; pillSize = 0.6; reverseScroll = false; showApplications = false; showBadge = true; showLabelsOnlyWhenOccupied = true; unfocusedIconsOpacity = 1.0; }
];
right = [
{ blacklist = [ ]; chevronColor = "none"; colorizeIcons = false; drawerEnabled = true; hidePassive = false; id = "Tray"; pinned = [ ]; }
{ hideWhenZero = false; hideWhenZeroUnread = false; iconColor = "none"; id = "NotificationHistory"; showUnreadBadge = true; unreadBadgeColor = "primary"; }
{ deviceNativePath = "__default__"; displayMode = "graphic-clean"; hideIfIdle = false; hideIfNotDetected = true; id = "Battery"; showNoctaliaPerformance = false; showPowerProfiles = false; }
{ displayMode = "onhover"; iconColor = "none"; id = "Volume"; middleClickCommand = "pwvucontrol || pavucontrol"; textColor = "none"; }
{ displayMode = "onhover"; iconColor = "none"; id = "Brightness"; textColor = "none"; }
{ colorizeDistroLogo = false; colorizeSystemIcon = "none"; customIconPath = ""; enableColorization = false; icon = "noctalia"; id = "ControlCenter"; useDistroLogo = false; }
];
};
screenOverrides = [ ];
};
general = {
avatarImage = "/home/nate/.face";
dimmerOpacity = 0.3;
showScreenCorners = false;
forceBlackScreenCorners = false;
scaleRatio = 1;
radiusRatio = 1;
iRadiusRatio = 1;
boxRadiusRatio = 1;
screenRadiusRatio = 1;
animationSpeed = 1;
animationDisabled = false;
compactLockScreen = false;
lockScreenAnimations = false;
lockOnSuspend = true;
showSessionButtonsOnLockScreen = true;
showHibernateOnLockScreen = false;
enableShadows = true;
shadowDirection = "bottom_right";
shadowOffsetX = 2;
shadowOffsetY = 3;
language = "";
allowPanelsOnScreenWithoutBar = true;
showChangelogOnStartup = true;
telemetryEnabled = false;
enableLockScreenCountdown = true;
lockScreenCountdownDuration = 10000;
autoStartAuth = false;
allowPasswordWithFprintd = false;
clockStyle = "custom";
clockFormat = "hh\\nmm";
lockScreenMonitors = [ ];
lockScreenBlur = 0;
lockScreenTint = 0;
keybinds = {
keyUp = [ "Up" ];
keyDown = [ "Down" ];
keyLeft = [ "Left" ];
keyRight = [ "Right" ];
keyEnter = [ "Return" ];
keyEscape = [ "Esc" ];
};
};
ui = {
fontDefault = "Lato";
fontFixed = "Maple Mono NF";
fontDefaultScale = 1.2;
fontFixedScale = 1.2;
tooltipsEnabled = true;
panelBackgroundOpacity = 1.0;
panelsAttachedToBar = true;
settingsPanelMode = "attached";
wifiDetailsViewMode = "grid";
bluetoothDetailsViewMode = "grid";
networkPanelView = "wifi";
bluetoothHideUnnamedDevices = false;
boxBorderEnabled = false;
};
location = {
name = "Saratoga Springs, UT";
weatherEnabled = true;
weatherShowEffects = true;
useFahrenheit = true;
use12hourFormat = true;
showWeekNumberInCalendar = false;
showCalendarEvents = true;
showCalendarWeather = true;
analogClockInCalendar = false;
firstDayOfWeek = -1;
hideWeatherTimezone = false;
hideWeatherCityName = false;
};
calendar = {
cards = [
{ enabled = true; id = "calendar-header-card"; }
{ enabled = true; id = "calendar-month-card"; }
{ enabled = true; id = "weather-card"; }
];
};
wallpaper = {
enabled = true;
overviewEnabled = true;
directory = "/home/nate/Pictures/Wallpapers";
monitorDirectories = [ ];
enableMultiMonitorDirectories = false;
showHiddenFiles = false;
viewMode = "browse";
setWallpaperOnAllMonitors = true;
fillMode = "crop";
fillColor = config.lib.stylix.colors.withHashtag.base00;
useSolidColor = false;
solidColor = "#1a1a2e";
automationEnabled = true;
wallpaperChangeMode = "random";
randomIntervalSec = 300;
transitionDuration = 2000;
transitionType = "random";
transitionEdgeSmoothness = 0.05;
panelPosition = "follow_bar";
hideWallpaperFilenames = false;
overviewBlur = 0.4;
overviewTint = 0.6;
useWallhaven = false;
wallhavenQuery = "";
wallhavenSorting = "relevance";
wallhavenOrder = "desc";
wallhavenCategories = "111";
wallhavenPurity = "100";
wallhavenRatios = "";
wallhavenApiKey = "";
wallhavenResolutionMode = "atleast";
wallhavenResolutionWidth = "";
wallhavenResolutionHeight = "";
sortOrder = "name";
};
appLauncher = {
enableClipboardHistory = false;
autoPasteClipboard = false;
enableClipPreview = true;
clipboardWrapText = true;
clipboardWatchTextCommand = "wl-paste --type text --watch cliphist store";
clipboardWatchImageCommand = "wl-paste --type image --watch cliphist store";
position = "center";
pinnedApps = [ ];
useApp2Unit = false;
sortByMostUsed = true;
terminalCommand = "ghostty -e";
customLaunchPrefixEnabled = false;
customLaunchPrefix = "";
viewMode = "list";
showCategories = true;
iconMode = "tabler";
showIconBackground = false;
enableSettingsSearch = true;
enableWindowsSearch = true;
ignoreMouseInput = false;
screenshotAnnotationTool = "";
overviewLayer = false;
density = "default";
};
controlCenter = {
position = "close_to_bar_button";
diskPath = "/";
shortcuts = {
left = [
{ id = "Network"; }
{ id = "Bluetooth"; }
{ id = "WallpaperSelector"; }
{ id = "NoctaliaPerformance"; }
];
right = [
{ id = "Notifications"; }
{ id = "PowerProfile"; }
{ id = "KeepAwake"; }
{ id = "NightLight"; }
];
};
cards = [
{ enabled = true; id = "profile-card"; }
{ enabled = true; id = "shortcuts-card"; }
{ enabled = true; id = "audio-card"; }
{ enabled = false; id = "brightness-card"; }
{ enabled = true; id = "weather-card"; }
{ enabled = true; id = "media-sysmon-card"; }
];
};
systemMonitor = {
cpuWarningThreshold = 80;
cpuCriticalThreshold = 90;
tempWarningThreshold = 80;
tempCriticalThreshold = 90;
gpuWarningThreshold = 80;
gpuCriticalThreshold = 90;
memWarningThreshold = 80;
memCriticalThreshold = 90;
swapWarningThreshold = 80;
swapCriticalThreshold = 90;
diskWarningThreshold = 80;
diskCriticalThreshold = 90;
diskAvailWarningThreshold = 20;
diskAvailCriticalThreshold = 10;
batteryWarningThreshold = 20;
batteryCriticalThreshold = 5;
cpuPollingInterval = 1000;
gpuPollingInterval = 3000;
enableDgpuMonitoring = false;
memPollingInterval = 1000;
diskPollingInterval = 30000;
networkPollingInterval = 1000;
loadAvgPollingInterval = 3000;
useCustomColors = false;
warningColor = "";
criticalColor = "";
externalMonitor = "resources || missioncenter || jdsystemmonitor || corestats || system-monitoring-center || gnome-system-monitor || plasma-systemmonitor || mate-system-monitor || ukui-system-monitor || deepin-system-monitor || pantheon-system-monitor";
};
dock = {
enabled = true;
position = "bottom";
displayMode = "auto_hide";
backgroundOpacity = 1.0;
floatingRatio = 1;
size = 1;
onlySameOutput = true;
monitors = [ ];
pinnedApps = [ ];
colorizeIcons = false;
pinnedStatic = false;
inactiveIndicators = false;
deadOpacity = 0.6;
animationSpeed = 1;
};
network = {
wifiEnabled = true;
bluetoothRssiPollingEnabled = false;
bluetoothRssiPollIntervalMs = 10000;
wifiDetailsViewMode = "grid";
bluetoothDetailsViewMode = "grid";
bluetoothHideUnnamedDevices = false;
};
sessionMenu = {
enableCountdown = true;
countdownDuration = 10000;
position = "center";
showHeader = true;
largeButtonsStyle = true;
largeButtonsLayout = "single-row";
showNumberLabels = true;
powerOptions = [
{ action = "lock"; command = ""; countdownEnabled = true; enabled = true; keybind = ""; }
{ action = "suspend"; command = ""; countdownEnabled = true; enabled = true; keybind = ""; }
{ action = "hibernate"; command = ""; countdownEnabled = true; enabled = true; keybind = ""; }
{ action = "reboot"; command = ""; countdownEnabled = true; enabled = true; keybind = ""; }
{ action = "logout"; command = ""; countdownEnabled = true; enabled = true; keybind = ""; }
{ action = "shutdown"; command = ""; countdownEnabled = true; enabled = true; keybind = ""; }
];
};
notifications = {
enabled = true;
monitors = [ ];
location = "top";
overlayLayer = true;
backgroundOpacity = 1.0;
respectExpireTimeout = false;
lowUrgencyDuration = 3;
normalUrgencyDuration = 8;
criticalUrgencyDuration = 15;
saveToHistory = { low = true; normal = true; critical = true; };
sounds = {
enabled = false;
volume = 0.5;
separateSounds = false;
criticalSoundFile = "";
normalSoundFile = "";
lowSoundFile = "";
excludedApps = "discord,firefox,chrome,chromium,edge";
};
enableMediaToast = false;
enableKeyboardLayoutToast = true;
enableBatteryToast = true;
};
osd = {
enabled = true;
location = "bottom";
autoHideMs = 2000;
overlayLayer = true;
backgroundOpacity = 1.0;
enabledTypes = [ 0 1 2 3 ];
monitors = [ ];
};
audio = {
volumeStep = 5;
volumeOverdrive = false;
cavaFrameRate = 30;
visualizerType = "linear";
mprisBlacklist = [ ];
preferredPlayer = "";
volumeFeedback = false;
};
brightness = {
brightnessStep = 5;
enforceMinimum = true;
enableDdcSupport = false;
};
colorSchemes = {
useWallpaperColors = false;
predefinedScheme = "Noctalia (default)";
darkMode = true;
schedulingMode = "off";
manualSunrise = "06:30";
manualSunset = "18:30";
generationMethod = "tonal-spot";
monitorForColors = "";
};
templates = {
activeTemplates = [ ];
enableUserTheming = false;
};
nightLight = {
enabled = true;
forced = false;
autoSchedule = true;
nightTemp = "4000";
dayTemp = "6500";
manualSunrise = "06:30";
manualSunset = "18:30";
};
hooks = {
enabled = false;
wallpaperChange = "";
darkModeChange = "";
screenLock = "";
screenUnlock = "";
performanceModeEnabled = "";
performanceModeDisabled = "";
startup = "";
session = "";
};
plugins = {
autoUpdate = true;
};
desktopWidgets = {
enabled = false;
gridSnap = false;
monitorWidgets = [ ];
};
};
};
}