commit d1e1c5b60cae230d008368d700c915cb62ebb65c Author: joshashtondev Date: Thu Jul 16 00:05:44 2026 -0600 init commit, ly, i3, polybar, neovim, alacritty, NixOS Flakes + Home-Manager diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..737564c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +nix-pad.qcow2 +result diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..5a85087 --- /dev/null +++ b/flake.lock @@ -0,0 +1,49 @@ +{ + "nodes": { + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1779506708, + "narHash": "sha256-QOD/CNm196nCJRheux/URi4/HE66fthdOMqCJoPP1Y0=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "3ee51fbdac8c8bdfe1e7e1fcaba6520a563f394f", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-25.11", + "repo": "home-manager", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1782847189, + "narHash": "sha256-twXPFqFsrrY5r28Zh7Homgcp2gUMBgQ6WDS98Q/3xFI=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "b6018f87da91d19d0ab4cf979885689b469cdd41", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "home-manager": "home-manager", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..56bdff5 --- /dev/null +++ b/flake.nix @@ -0,0 +1,57 @@ +{ + description = "My multi-device NixOS configuration."; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; + + home-manager = { + url = "github:nix-community/home-manager/release-25.11"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, home-manager, ... }: { + nixosConfigurations = { + thinkpad = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + + modules = [ + ./hosts/thinkpad/default.nix + + home-manager.nixosModules.home-manager { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.users.jashton = import ./home/jashton.nix; + } + ]; + }; + + desktop = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + + modules = [ + ./hosts/desktop/default.nix + + home-manager.nixosModules.home-manager { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.users.jashton = import ./home/jashton.nix; + } + ]; + }; + + framework = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + + modules = [ + ./hosts/framework/default.nix + + home-manager.nixosModules.home-manager { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.users.jashton = import ./home/jashton.nix; + } + ]; + }; + }; + }; +} diff --git a/home/desktop/assets/blurred-samuraii.jpg b/home/desktop/assets/blurred-samuraii.jpg new file mode 100644 index 0000000..8574048 Binary files /dev/null and b/home/desktop/assets/blurred-samuraii.jpg differ diff --git a/home/desktop/assets/samuraii.jpg b/home/desktop/assets/samuraii.jpg new file mode 100644 index 0000000..cc84d9f Binary files /dev/null and b/home/desktop/assets/samuraii.jpg differ diff --git a/home/desktop/default.nix b/home/desktop/default.nix new file mode 100644 index 0000000..9fe99b6 --- /dev/null +++ b/home/desktop/default.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./dunst.nix + ./i3.nix + ./polybar.nix + ./rofi.nix + ]; +} diff --git a/home/desktop/dunst.nix b/home/desktop/dunst.nix new file mode 100644 index 0000000..96c8bfc --- /dev/null +++ b/home/desktop/dunst.nix @@ -0,0 +1,43 @@ +{ config, lib, pkgs, ... }: + +{ + services.dunst = { + enable = true; + settings = { + global = { + width = 300; + height = 300; + offset = "14x50"; + origin = "top-right"; + transparency = 10; + font = "Hack Nerd Font Mono 12"; + + # Geometry and base borders + frame_width = 2; + separator_color = "#2c2137"; # Midnight Violet + }; + + urgency_low = { + background = "#1e1f21"; # Carbon Black + foreground = "#7e6790"; # Vintage Lavender 2 (Subtle text for low priority) + frame_color = "#2c2137"; # Midnight Violet (Darkest accent) + timeout = 5; + }; + + urgency_normal = { + background = "#1e1f21"; # Carbon Black + foreground = "#8d739c"; # Vintage Lavender 1 (Primary readable text) + frame_color = "#4f3963"; # Vintage Grape (Your primary accent) + timeout = 10; + }; + + urgency_critical = { + # Flipping the background to Midnight Violet to make it pop slightly + background = "#2c2137"; + foreground = "#8d739c"; # Vintage Lavender 1 + frame_color = "#847397"; # Vintage Lavender 3 (Brightest accent for critical) + timeout = 0; # Stays on screen until explicitly dismissed + }; + }; + }; +} diff --git a/home/desktop/i3.nix b/home/desktop/i3.nix new file mode 100644 index 0000000..31cf976 --- /dev/null +++ b/home/desktop/i3.nix @@ -0,0 +1,11 @@ +{ config, pkgs, ... }: + +{ + xsession.windowManager.i3 = { + enable = true; + config = null; + extraConfig = (builtins.readFile ./i3/config) + '' + exec --no-startup-id ${pkgs.feh}/bin/feh --bg-fill ${./assets/samuraii.jpg} + ''; + }; +} diff --git a/home/desktop/i3/config b/home/desktop/i3/config new file mode 100644 index 0000000..b972571 --- /dev/null +++ b/home/desktop/i3/config @@ -0,0 +1,295 @@ +# Set modifier key as Alt +set $mod Mod4 + +# Set purple theming & fonts +set $base #08090B +set $accent #8D739C +set $hover #4F3963 + +font pango: Lato 15 + +# Start i3 +exec --no-startup-id dex --autostart --environment i3 +exec --no-startup-id bash -c "pkill -x polybar; sleep 0.5; polybar main &" +exec --no-startup-id nm-applet + +exec alacritty + +# Lock screen with i3lock-color +bindsym $mod+q exec ~/.config/i3scripts/lock + +# Default gaps between windows +gaps outer 10 +gaps inner 5 + +# Adjust floating windows +floating_modifier $mod +tiling_drag modifier titlebar + +bindsym $mod+Return exec alacritty +bindsym $mod+x kill +bindsym $mod+d exec "rofi -show drun -show-icons" + +# Restart i3 in place +bindsym $mod+Shift+c restart + +# Adapt i3 to external monitors. +bindsym $mod+Shift+r exec --no-startup-id autorandr --change + +# Exit i3 & logout +bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'" + +# --------------------- WORKSPACES ------------------------- # +# Define workspaces +set $ws1 "1:%{T3}%{T-}" +set $ws2 "2:%{T3}󰏬%{T-}" +set $ws3 "3:%{T3}%{T-}" +set $ws4 "4:%{T3}%{T-}" +set $ws5 "5:%{T3}󰈙%{T-}" +set $ws6 "6:%{T3}%{T-}" +set $ws7 "7:%{T3}󰇮%{T-}" +set $ws8 "8:%{T3}󰎆%{T-}" +set $ws9 "9:%{T3}󰭹%{T-}" +set $ws10 "10:%{T3}󰈹%{T-}" + +# switch to workspace +bindsym $mod+1 workspace number $ws1 +bindsym $mod+2 workspace number $ws2 +bindsym $mod+3 workspace number $ws3 +bindsym $mod+4 workspace number $ws4 +bindsym $mod+5 workspace number $ws5 +bindsym $mod+6 workspace number $ws6 +bindsym $mod+7 workspace number $ws7 +bindsym $mod+8 workspace number $ws8 +bindsym $mod+9 workspace number $ws9 +bindsym $mod+0 workspace number $ws10 + +# move focused container to workspace +bindsym $mod+Shift+1 move container to workspace number $ws1 +bindsym $mod+Shift+2 move container to workspace number $ws2 +bindsym $mod+Shift+3 move container to workspace number $ws3 +bindsym $mod+Shift+4 move container to workspace number $ws4 +bindsym $mod+Shift+5 move container to workspace number $ws5 +bindsym $mod+Shift+6 move container to workspace number $ws6 +bindsym $mod+Shift+7 move container to workspace number $ws7 +bindsym $mod+Shift+8 move container to workspace number $ws8 +bindsym $mod+Shift+9 move container to workspace number $ws9 +bindsym $mod+Shift+0 move container to workspace number $ws10 + +# ------------------------ STARTUP APPS ---------------------- # + +# ------------------------ WINDOWS --------------------------- # +# change focus +bindsym $mod+h focus left +bindsym $mod+j focus down +bindsym $mod+k focus up +bindsym $mod+l focus right + +# move focused window +bindsym $mod+Shift+h move left +bindsym $mod+Shift+j move down +bindsym $mod+Shift+k move up +bindsym $mod+Shift+l move right + +# enter fullscreen mode for the focused container +bindsym $mod+f fullscreen toggle + +# change container layout (stacked, tabbed, toggle split) +bindsym $mod+s layout stacking +bindsym $mod+w layout tabbed +bindsym $mod+e layout toggle split + +bindsym $mod+v layout splitv +bindsym $mod+b layout splith + +# toggle tiling / floating +bindsym $mod+Shift+space floating toggle + +# change focus between tiling / floating windows +bindsym $mod+space focus mode_toggle + +# Window color customization: +# class border backgr. text indicator child_border +client.focused $base $base $base $base $accent +client.focused_inactive $base $base $hover $base $accent +client.unfocused $accent $accent $base $base $accent +client.urgent #2f343a #900000 $hover $base #900000 +client.placeholder #000000 #0c0c0c $hover $base #0c0c0c +client.background #635380 + +default_border pixel 4 + +# ------------------------- FUNCTION KEY BINDING ---------------------------- # +# Volume control +# ------------------------- FUNCTION KEY BINDING ---------------------------- # +# Volume control (using native PulseAudio commands) +bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +5% +bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -5% +bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle + +# Brightness control (using brightnessctl) +bindsym XF86MonBrightnessUp exec --no-startup-id brightnessctl set 5%+ +bindsym XF86MonBrightnessDown exec --no-startup-id brightnessctl set 5%- + +# Screenshot +bindsym XF86AudioRecord exec flameshot gui +#bindsym XF86Search workspace number $ws10 + +# Audio control +#bindsym XF86AudioPlay exec playerctl play +bindsym XF86AudioPause exec playerctl pause +bindsym XF86AudioNext exec playerctl next +bindsym XF86AudioPrev exec playerctl previous + +# --------------------- MODES ----------------------# +set $mode_gaps Gaps: (o)uter, (i)nner, (h)orizontal, (v)ertical, (t)op, (r)ight, (b)ottom, (l)eft +set $mode_gaps_outer Outer Gaps: +|-|0 (local), Shift + +|-|0 (global) +set $mode_gaps_inner Inner Gaps: +|-|0 (local), Shift + +|-|0 (global) +set $mode_gaps_horiz Horizontal Gaps: +|-|0 (local), Shift + +|-|0 (global) +set $mode_gaps_verti Vertical Gaps: +|-|0 (local), Shift + +|-|0 (global) +set $mode_gaps_top Top Gaps: +|-|0 (local), Shift + +|-|0 (global) +set $mode_gaps_right Right Gaps: +|-|0 (local), Shift + +|-|0 (global) +set $mode_gaps_bottom Bottom Gaps: +|-|0 (local), Shift + +|-|0 (global) +set $mode_gaps_left Left Gaps: +|-|0 (local), Shift + +|-|0 (global) +bindsym $mod+Shift+g mode "$mode_gaps" + +mode "$mode_gaps" { + bindsym o mode "$mode_gaps_outer" + bindsym i mode "$mode_gaps_inner" + bindsym h mode "$mode_gaps_horiz" + bindsym v mode "$mode_gaps_verti" + bindsym t mode "$mode_gaps_top" + bindsym r mode "$mode_gaps_right" + bindsym b mode "$mode_gaps_bottom" + bindsym l mode "$mode_gaps_left" + bindsym Return mode "$mode_gaps" + bindsym Escape mode "default" +} + +mode "$mode_gaps_outer" { + bindsym plus gaps outer current plus 5 + bindsym minus gaps outer current minus 5 + bindsym 0 gaps outer current set 0 + + bindsym Shift+plus gaps outer all plus 5 + bindsym Shift+minus gaps outer all minus 5 + bindsym Shift+0 gaps outer all set 0 + + bindsym Return mode "$mode_gaps" + bindsym Escape mode "default" +} +mode "$mode_gaps_inner" { + bindsym plus gaps inner current plus 5 + bindsym minus gaps inner current minus 5 + bindsym 0 gaps inner current set 0 + + bindsym Shift+plus gaps inner all plus 5 + bindsym Shift+minus gaps inner all minus 5 + bindsym Shift+0 gaps inner all set 0 + + bindsym Return mode "$mode_gaps" + bindsym Escape mode "default" +} +mode "$mode_gaps_horiz" { + bindsym plus gaps horizontal current plus 5 + bindsym minus gaps horizontal current minus 5 + bindsym 0 gaps horizontal current set 0 + + bindsym Shift+plus gaps horizontal all plus 5 + bindsym Shift+minus gaps horizontal all minus 5 + bindsym Shift+0 gaps horizontal all set 0 + + bindsym Return mode "$mode_gaps" + bindsym Escape mode "default" +} +mode "$mode_gaps_verti" { + bindsym plus gaps vertical current plus 5 + bindsym minus gaps vertical current minus 5 + bindsym 0 gaps vertical current set 0 + + bindsym Shift+plus gaps vertical all plus 5 + bindsym Shift+minus gaps vertical all minus 5 + bindsym Shift+0 gaps vertical all set 0 + + bindsym Return mode "$mode_gaps" + bindsym Escape mode "default" +} +mode "$mode_gaps_top" { + bindsym plus gaps top current plus 5 + bindsym minus gaps top current minus 5 + bindsym 0 gaps top current set 0 + + bindsym Shift+plus gaps top all plus 5 + bindsym Shift+minus gaps top all minus 5 + bindsym Shift+0 gaps top all set 0 + + bindsym Return mode "$mode_gaps" + bindsym Escape mode "default" +} +mode "$mode_gaps_right" { + bindsym plus gaps right current plus 5 + bindsym minus gaps right current minus 5 + bindsym 0 gaps right current set 0 + + bindsym Shift+plus gaps right all plus 5 + bindsym Shift+minus gaps right all minus 5 + bindsym Shift+0 gaps right all set 0 + + bindsym Return mode "$mode_gaps" + bindsym Escape mode "default" +} +mode "$mode_gaps_bottom" { + bindsym plus gaps bottom current plus 5 + bindsym minus gaps bottom current minus 5 + bindsym 0 gaps bottom current set 0 + + bindsym Shift+plus gaps bottom all plus 5 + bindsym Shift+minus gaps bottom all minus 5 + bindsym Shift+0 gaps bottom all set 0 + + bindsym Return mode "$mode_gaps" + bindsym Escape mode "default" +} +mode "$mode_gaps_left" { + bindsym plus gaps left current plus 5 + bindsym minus gaps left current minus 5 + bindsym 0 gaps left current set 0 + + bindsym Shift+plus gaps left all plus 5 + bindsym Shift+minus gaps left all minus 5 + bindsym Shift+0 gaps left all set 0 + + bindsym Return mode "$mode_gaps" + bindsym Escape mode "default" +} + +# Resize mode +mode "resize" { + bindsym h resize shrink width 10 px or 10 ppt + bindsym k resize grow height 10 px or 10 ppt + bindsym j resize shrink height 10 px or 10 ppt + bindsym l resize grow width 10 px or 10 ppt + + # back to normal: Enter or Escape or $mod+r + bindsym Return mode "default" + bindsym Escape mode "default" + bindsym $mod+r mode "default" +} + +bindsym $mod+r mode "resize" + +# Creating ability to lock, logout, suspend, hibernate, reboot, and shutdown. +set $mode_system System (e) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown +mode "$mode_system" { + bindsym l exec --no-startup-id lock-screen, mode "default" + bindsym e exec --no-startup-id i3exit logout, mode "default" + bindsym s exec --no-startup-id i3exit suspend, mode "default" + bindsym h exec --no-startup-id i3exit hibernate, mode "default" + bindsym r exec --no-startup-id i3exit reboot, mode "default" + bindsym Shift+s exec --no-startup-id i3exit shutdown, mode "default" + + # back to normal: Enter or Escape + bindsym Return mode "default" + bindsym Escape mode "default" +} +bindsym $mod+Shift+Escape mode "$mode_system" diff --git a/home/desktop/polybar.nix b/home/desktop/polybar.nix new file mode 100644 index 0000000..26842fa --- /dev/null +++ b/home/desktop/polybar.nix @@ -0,0 +1,138 @@ +{ config, pkgs, ... }: + +{ + services.polybar = { + enable = true; + script = "polybar main &"; + + package = pkgs.polybar.override { + i3Support = true; + pulseSupport = true; + }; + + config = { + "colors" = { + background = "#08090b"; + foreground = "#8d739c"; + bg-alt1 = "#1e1f21"; + bg-alt2 = "#2c2137"; + accent = "#4f3963"; + text-light = "#847397"; + }; + + "bar/main" = { + width = "100%"; + height = "24pt"; + background = "\${colors.background}"; + foreground = "\${colors.foreground}"; + + # This gives you the gap between the screen edge and your blocks + padding-left = 0; + padding-right = 0; + + # The physical empty space between each pill + module-margin = 1; + + # True Center Alignment! + modules-left = "i3 weather"; + modules-center = "date"; + modules-right = "spotify pulseaudio wlan battery"; + + font-0 = "Hack Nerd Font Mono:size=12;3"; + font-1 = "Noto Color Emoji:scale=12;3"; + font-2 = "Hack Nerd Font Mono:size=16;3"; + }; + + # --- NATIVE INTERNAL MODULES --- # + + "module/i3" = { + type = "internal/i3"; + format = ""; + strip-wsnumbers = true; + + # Adding padding creates the "pill" width + label-focused = "%name%"; + label-focused-background = "\${colors.bg-alt2}"; + label-focused-foreground = "\${colors.text-light}"; + label-focused-padding = 1; + + label-unfocused = "%name%"; + label-unfocused-background = "\${colors.background}"; + label-unfocused-padding = 1; + }; + + "module/date" = { + type = "internal/date"; + interval = 1; + date = "%a, %b %d"; + time = "%I:%M %p"; + label = " %date% %time% "; + label-background = "\${colors.accent}"; + label-foreground = "#08090b"; + }; + + "module/pulseaudio" = { + type = "internal/pulseaudio"; + format-volume = ""; + label-volume = "  %percentage%% "; + label-volume-background = "\${colors.bg-alt2}"; + label-volume-foreground = "\${colors.text-light}"; + + label-muted = "  Muted "; + label-muted-background = "\${colors.bg-alt2}"; + label-muted-foreground = "#4f3963"; + }; + + "module/wlan" = { + type = "internal/network"; + # Polybar automatically detects your wireless interface + interface-type = "wireless"; + interval = 3; + + # Action Tag: Left-click launches Alacritty with NetworkManager TUI + format-connected = ""; + label-connected = "%{A1:alacritty -e nmtui:} %{T3}%{T-} %essid% %{A}"; + label-connected-background = "\${colors.bg-alt1}"; + label-connected-padding = 1; + + format-disconnected = ""; + label-disconnected = "%{A1:alacritty -e nmtui:} %{T3}󰖪%{T-} Offline %{A}"; + label-disconnected-background = "\${colors.bg-alt1}"; + label-disconnected-foreground = "#900000"; # Red alert when down + label-disconnected-padding = 1; + }; + + "module/battery" = { + type = "internal/battery"; + full-at = 99; + low-at = 10; + battery = "BAT0"; + adapter = "AC"; + + format-charging = ""; + label-charging = "%{A1:power-menu:} ⚡ %percentage%% %{A1}"; + label-charging-background = "\${colors.bg-alt1}"; + + format-notcharging = ""; + label-notcharging = "%{A1:power-menu:} ⏸️ %percentage%% %{A}"; + label-notcharging-background = "\${colors.bg-alt1}"; + + format-discharging = ""; + label-discharging = "%{A1:power-menu:}  %percentage%% %{A1}"; + label-discharging-background = "\${colors.bg-alt1}"; + }; + + # --- CUSTOM SCRIPT MODULES --- # + + "module/weather" = { + type = "custom/script"; + # Call the script we just built in home.packages + exec = "weather-cache"; + interval = 3600; + label = " %output% "; + format-background = "\${colors.bg-alt1}"; + }; + + }; + }; +} diff --git a/home/desktop/rofi.nix b/home/desktop/rofi.nix new file mode 100644 index 0000000..7907a1f --- /dev/null +++ b/home/desktop/rofi.nix @@ -0,0 +1,83 @@ +{ config, pkgs, ... }: + +{ + programs.rofi = { + enable = true; + + # Optional: ensure it uses your configured terminal + terminal = "${pkgs.alacritty}/bin/alacritty"; + font = "Hack Nerd Font Mono 12"; + + theme = let + # Pulls in the mkLiteral function specifically for Rofi + inherit (config.lib.formats.rasi) mkLiteral; + in { + "*" = { + # Your Vintage Lavender Palette + bg0 = mkLiteral "#08090b"; # Black + bg1 = mkLiteral "#1e1f21"; # Carbon Black + bg2 = mkLiteral "#2c2137"; # Midnight Violet + fg0 = mkLiteral "#8d739c"; # Vintage Lavender 1 + fg1 = mkLiteral "#847397"; # Vintage Lavender 3 + accent = mkLiteral "#4f3963"; # Vintage Grape + + background-color = mkLiteral "transparent"; + text-color = mkLiteral "@fg0"; + margin = mkLiteral "0px"; + padding = mkLiteral "0px"; + spacing = mkLiteral "0px"; + }; + + "window" = { + background-color = mkLiteral "@bg0"; + border = mkLiteral "2px"; + border-color = mkLiteral "@accent"; + border-radius = mkLiteral "6px"; + width = mkLiteral "600px"; + }; + + "inputbar" = { + padding = mkLiteral "12px"; + background-color = mkLiteral "@bg1"; + border = mkLiteral "0px 0px 2px 0px"; + border-color = mkLiteral "@accent"; + }; + + "entry" = { + padding = mkLiteral "0px 12px"; + vertical-align = mkLiteral "0.5"; + }; + + "prompt" = { + vertical-align = mkLiteral "0.5"; + text-color = mkLiteral "@accent"; + }; + + "listview" = { + padding = mkLiteral "8px"; + lines = 8; + columns = 1; + fixed-height = mkLiteral "false"; + }; + + "element" = { + padding = mkLiteral "8px"; + spacing = mkLiteral "8px"; + border-radius = mkLiteral "4px"; + }; + + "element-text, element-icon" = { + vertical-align = mkLiteral "0.5"; + background-color = mkLiteral "inherit"; + text-color = mkLiteral "inherit"; + }; + + "element selected" = { + background-color = mkLiteral "@bg2"; + text-color = mkLiteral "@fg0"; + border = mkLiteral "1px"; + border-color = mkLiteral "@accent"; + }; + }; + }; +} diff --git a/home/jashton.nix b/home/jashton.nix new file mode 100644 index 0000000..e902d93 --- /dev/null +++ b/home/jashton.nix @@ -0,0 +1,139 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./programs + ./desktop + ]; + + home.username = "jashton"; + home.homeDirectory = "/home/jashton"; + home.file.".zshrc".text = '' + # Zsh is configured globally at the NixOS system level. + # This file exists solely to prevent the zsh-newuser-install prompt. + ''; + + home.sessionVariables = { + WINIT_X11_SCALE_FACTOR = "1.0"; + }; + + home.packages = with pkgs; [ + spotify + claude-code + mc + discord + asciinema + intelli-shell + aider-chat + animdl + jrnl + freetube + + (pkgs.writeShellScriptBin "lock-screen" '' + # Color palette mapped to i3lock-color format (RRGGBBAA) + BLANK="00000000" # Fully transparent + BLACK="1e1f21ff" # Carbon Black + GRAPE="4f3963ff" # Vintage Grape (Main Ring) + VIOLET="2c2137ff" # Midnight Violet (Verifying Ring) + LAVENDER1="8d739cff" # Vintage Lavender 1 (Text) + LAVENDER2="7e6790ff" # Vintage Lavender 2 (Backspace Highlight) + LAVENDER3="847397ff" # Vintage Lavender 3 (Keypress Highlight) + + ${pkgs.i3lock-color}/bin/i3lock-color \ + --image="${./desktop/assets/blurred-samuraii.jpg}" \ + --fill \ + -c "1E1F21" \ + \ + --insidever-color=$BLANK \ + --ringver-color=$VIOLET \ + \ + --insidewrong-color=$BLANK \ + --ringwrong-color=$GRAPE \ + \ + --inside-color=$BLANK \ + --ring-color=$GRAPE \ + --line-color=$BLANK \ + --separator-color=$BLANK \ + \ + --verif-color=$LAVENDER1 \ + --wrong-color=$LAVENDER1 \ + --time-color=$LAVENDER1 \ + --date-color=$LAVENDER1 \ + --layout-color=$LAVENDER1 \ + --keyhl-color=$LAVENDER3 \ + --bshl-color=$LAVENDER2 \ + \ + --clock \ + --indicator \ + --time-str="%I:%M %p" \ + --date-str="%a, %b %d" \ + --radius=120 \ + --ring-width=8 + '') + + (pkgs.writeShellScriptBin "power-menu" '' + # Define the menu options + OPTIONS="1. ☕ Toggle Caffeine (Disable Auto-Sleep)\n2. 🔋 Force 100% Charge\n3. ♻️ Reset TLP Defaults" + + # Pipe options into Rofi + CHOICE=$(echo -e "$OPTIONS" | ${pkgs.rofi}/bin/rofi -dmenu -i -p "Power:") + + # Execute commands based on the selection + case "$CHOICE" in + *"Caffeine"*) + # Assuming you use xset for screen blanking. Adjust if using xautolock or swayidle. + if xset q | grep -q "DPMS is Enabled"; then + xset -dpms s off + ${pkgs.libnotify}/bin/notify-send "Power" "Caffeine ON (Sleep Disabled)" + else + xset +dpms s on + ${pkgs.libnotify}/bin/notify-send "Power" "Caffeine OFF (Normal Sleep)" + fi + ;; + *"100% Charge"*) + sudo tlp fullcharge BAT0 + ${pkgs.libnotify}/bin/notify-send "TLP" "Charging to 100% temporarily" + ;; + *"Reset TLP Defaults"*) + sudo tlp start + ${pkgs.libnotify}/bin/notify-send "TLP" "Default power profiles restored" + ;; + esac + '') + + (pkgs.writeShellScriptBin "weather-cache" '' + CACHE_FILE="$HOME/.cache/weather-cache.txt" + # Create cache dir if it doesn't exist + mkdir -p "$HOME/.cache" + + # Try to fetch weather with a 3-second timeout + if ${pkgs.curl}/bin/curl -s --connect-timeout 3 'https://wttr.in/Salt+Lake+City?format=1' > /tmp/weather.tmp; then + # If successful, update the cache and print + cat /tmp/weather.tmp > "$CACHE_FILE" + cat "$CACHE_FILE" + else + # If network is down, read from cache and append an offline indicator + if [ -f "$CACHE_FILE" ]; then + echo "[$(cat "$CACHE_FILE")]" + else + echo "No Network" + fi + fi + '') + ]; + + home.activation = { + # 1. Create the persistent directories + createWorkspaceDirs = lib.hm.dag.entryAfter ["writeBoundary"] '' + $DRY_RUN_CMD mkdir -p $HOME/dev + $DRY_RUN_CMD mkdir -p $HOME/downloads + $DRY_RUN_CMD mkdir -p $HOME/life + $DRY_RUN_CMD mkdir -p $HOME/media/pics + $DRY_RUN_CMD mkdir -p $HOME/media/videos + $DRY_RUN_CMD mkdir -p $HOME/school + ''; + }; + + home.stateVersion = "25.11"; # DO NOT CHANGE +} + diff --git a/home/programs/alacritty.nix b/home/programs/alacritty.nix new file mode 100644 index 0000000..5d8e8de --- /dev/null +++ b/home/programs/alacritty.nix @@ -0,0 +1,55 @@ +{ config, pkgs, ... }: + +{ + programs.alacritty = { + enable = true; + theme = "hyper"; + + settings = { + window = { + padding = { x = 10; y = 10; }; + opacity = .9; + }; + + font = { + normal = { + family = "Hack Nerd Font"; + style = "Mono"; + }; + size = 8.0; + }; + + colors = { + primary = { + background = "#08090b"; # Black + foreground = "#8d739c"; # Vintage Lavender 1 + }; + + normal = { + black = "#1e1f21"; # Carbon Black + red = "#4f3963"; # Vintage Grape + green = "#7e6790"; # Vintage Lavender 2 + yellow = "#847397"; # Vintage Lavender 3 + blue = "#2c2137"; # Midnight Violet + magenta = "#8d739c"; # Vintage Lavender 1 + cyan = "#7e6790"; # Vintage Lavender 2 + white = "#323335"; # Graphite + }; + + # Bright colors map to the same palette for a consistent, flat aesthetic + bright = { + black = "#323335"; # Graphite + red = "#4f3963"; # Vintage Grape + green = "#7e6790"; # Vintage Lavender 2 + yellow = "#847397"; # Vintage Lavender 3 + blue = "#2c2137"; # Midnight Violet + magenta = "#8d739c"; # Vintage Lavender 1 + cyan = "#7e6790"; # Vintage Lavender 2 + white = "#8d739c"; # Vintage Lavender 1 + }; + }; + + scrolling.multiplier = 3; + }; + }; +} diff --git a/home/programs/default.nix b/home/programs/default.nix new file mode 100644 index 0000000..60c698e --- /dev/null +++ b/home/programs/default.nix @@ -0,0 +1,9 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./alacritty.nix + ./git.nix + ./nvim.nix + ]; +} diff --git a/home/programs/git.nix b/home/programs/git.nix new file mode 100644 index 0000000..3f3a0f0 --- /dev/null +++ b/home/programs/git.nix @@ -0,0 +1,24 @@ +{ config, pkgs, ... }: + +{ + programs.git = { + enable = true; + settings = { + user = { + name = "joshashtondev"; + email = "me@joshashton.dev"; + }; + + init.defaultBranch = "main"; + pull.rebase = true; + push.autoSetupRemote = true; + }; + + ignores = [ + ".env" + "*.log" + "*.swp" + ".DS_STORE" + ]; + }; +} diff --git a/home/programs/nvim.nix b/home/programs/nvim.nix new file mode 100644 index 0000000..72957f4 --- /dev/null +++ b/home/programs/nvim.nix @@ -0,0 +1,100 @@ +{ config, pkgs, ... }: + +{ + programs.neovim = { + enable = true; + viAlias = true; + vimAlias = true; + defaultEditor = true; + + extraLuaConfig = '' + vim.opt.number = true + vim.opt.relativenumber = true + vim.opt.tabstop = 2 + vim.opt.softtabstop = 2 + vim.opt.expandtab = true + vim.opt.shiftwidth = 2 + vim.opt.smartindent = true + vim.opt.wrap = false + vim.opt.swapfile = false + vim.opt.backup = false + vim.opt.undofile = false + vim.opt.hlsearch = false + vim.opt.incsearch = true + vim.opt.termguicolors = true + vim.opt.clipboard = "unnamedplus" + vim.opt.scrolloff = 999 + vim.opt.updatetime = 50 + vim.opt.foldmethod = "indent" + vim.opt.foldlevel = 99 + + vim.g.mapleader = " " + vim.keymap.set("n", "", ":") + vim.keymap.set("n", "w", "w", { silent = true }) + vim.keymap.set("n", "q", "q", { silent = true }) + vim.keymap.set("n", "wq", "wq", { silent = true }) + vim.keymap.set("n", "x", "!chmod +x %", { silent = true }) + vim.keymap.set("n", "Q", "") + vim.keymap.set("n", "o", "o") + vim.keymap.set("n", "O", "O") + vim.keymap.set("i", "jj", "") + + local is_dark = vim.o.background ~= "light" + require("cyberdream").setup({ + transparent = is_dark, + variant = is_dark and "dark" or "light", + terminal_colors = true, + }) + vim.cmd.colorscheme("cyberdream") + + require("nvim-tree").setup({ + view = { width = 30 }, + renderer = { group_empty = true }, + filters = { dotfiles = false }, + }) + + require("bufferline").setup({ + options = { + offsets = { + { + filetype = "NvimTree", + text = "Files", + highlight = "Directory", + separator = true, + }, + }, + }, + }) + + require("lualine").setup({ + ons = { theme = "auto" }, + }) + + require("neocord").setup({ + logo = "auto", + logo_tooltip = "Neovim", + main_image = "language", + show_time = true, + global_timer = true, + }) + + require("gitsigns").setup({ + signs = { + add = { text = "+" }, + change = { text = "~" }, + delete = { text = "_" }, + }, + }) + ''; + + plugins = with pkgs.vimPlugins; [ + { plugin = cyberdream-nvim; } + { plugin = nvim-web-devicons; } + { plugin = nvim-tree-lua; } + { plugin = bufferline-nvim; } + { plugin = lualine-nvim; } + { plugin = neocord; } + { plugin = gitsigns-nvim; } + ]; + }; +} diff --git a/hosts/thinkpad/default.nix b/hosts/thinkpad/default.nix new file mode 100644 index 0000000..489ffb1 --- /dev/null +++ b/hosts/thinkpad/default.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./hardware.nix + ../../system + ../../system/security/thinkpad.nix + ]; + + networking.hostName = "nix-pad"; + + system.stateVersion = "25.11"; +} diff --git a/hosts/thinkpad/hardware.nix b/hosts/thinkpad/hardware.nix new file mode 100644 index 0000000..b39e66f --- /dev/null +++ b/hosts/thinkpad/hardware.nix @@ -0,0 +1,36 @@ +# 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, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usb_storage" "usbhid" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/64e7369e-c74b-4345-977e-8277f3d16f95"; + fsType = "ext4"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/DBD9-24B0"; + fsType = "vfat"; + options = [ "fmask=0022" "dmask=0022" ]; + }; + + swapDevices = + [ { device = "/dev/disk/by-uuid/332e7db3-3f68-4fd7-be2a-0d091ac936ae"; } + ]; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware = { + cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + bluetooth.enable = true; + }; +} diff --git a/system/core/boot.nix b/system/core/boot.nix new file mode 100644 index 0000000..a050c63 --- /dev/null +++ b/system/core/boot.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + boot.kernelPackages = pkgs.linuxPackages; + environment.pathsToLink = [ "/libexec" ]; +} diff --git a/system/core/default.nix b/system/core/default.nix new file mode 100644 index 0000000..e77f7ff --- /dev/null +++ b/system/core/default.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./boot.nix + ./env.nix + ./locale.nix + ./power.nix + ]; +} diff --git a/system/core/env.nix b/system/core/env.nix new file mode 100644 index 0000000..b71ff26 --- /dev/null +++ b/system/core/env.nix @@ -0,0 +1,42 @@ +{ config, pkgs, ... }: + +{ + environment.shells = with pkgs; [ zsh ]; + users.defaultUserShell = pkgs.zsh; + + fonts.packages = with pkgs; [ + nerd-fonts.hack + ]; + + nix.settings = { + experimental-features = [ "nix-command" "flakes" ]; + }; + + programs.zsh = { + enable = true; + enableCompletion = true; + autosuggestions.enable = true; + syntaxHighlighting.enable = true; + + histSize = 1000000; + + setOptions = [ + "HIST_IGNORE_ALL_DUPS" + ]; + + shellAliases = { + enix = "nvim $HOME/.dotfiles/flake.nix"; + unix = "sudo nixos-rebuild switch --flake $HOME/.dotfiles#thinkpad"; + ehome = "nvim $HOME/.dotfiles/home/jashton.nix"; + l = "ls -la"; + }; + + ohMyZsh = { + enable = true; + theme = "aussiegeek"; + plugins = [ + "git" + ]; + }; + }; +} diff --git a/system/core/locale.nix b/system/core/locale.nix new file mode 100644 index 0000000..53997b1 --- /dev/null +++ b/system/core/locale.nix @@ -0,0 +1,20 @@ +{ config, pkgs, ... }: + +{ + time.timeZone = "America/Denver"; + i18n = { + defaultLocale = "en_US.UTF-8"; + extraLocaleSettings = { + LC_ADDRESS = "en_US.UTF-8"; + LC_IDENTIFICATION = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_NAME = "en_US.UTF-8"; + LC_NUMERIC = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_TELEPHONE = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + LC_CTYPE = "en_US.UTF-8"; + }; + }; +} diff --git a/system/core/power.nix b/system/core/power.nix new file mode 100644 index 0000000..a73989b --- /dev/null +++ b/system/core/power.nix @@ -0,0 +1,32 @@ +{ config, pkgs, ... }: + +{ + boot.kernelParams = [ "mem_sleep_default=deep" ]; + + services.power-profiles-daemon.enable = false; + + services.tlp = { + enable = true; + settings = { + USB_AUTOSUSPEND = 0; + + # AC + CPU_SCALING_GOVERNOR_ON_AC = "performance"; + CPU_ENERGY_PERF_POLICY_ON_AC = "performance"; + SOUND_POWER_SAVE_ON_AC = 0; + PCIE_ASPM_ON_AC = "default"; + CPU_BOOST_ON_BAT = 0; + + # Battery + CPU_SCALING_GOVERNOR_ON_BAT = "powersave"; + CPU_ENERGY_PERF_POLICY_ON_BAT = "power"; + SOUND_POWER_SAVE_ON_BAT = 1; + PCIE_ASPM_ON_BAT = "powersupersave"; + CPU_BOOST_ON_AC = 1; + + # Battery Thresholds + START_CHARGE_THRESH_BAT0 = 40; + STOP_CHARGE_THRESH_BAT0 = 80; + }; + }; +} diff --git a/system/default.nix b/system/default.nix new file mode 100644 index 0000000..03838c9 --- /dev/null +++ b/system/default.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./packages.nix + ./core + ./network + ./security + ./services + ./virtualisation + ]; +} diff --git a/system/network/default.nix b/system/network/default.nix new file mode 100644 index 0000000..53418d1 --- /dev/null +++ b/system/network/default.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + networking = { + networkmanager.enable = true; + + firewall = { + enable = true; + allowedTCPPorts = []; + allowedUDPPorts = []; + }; + }; +} diff --git a/system/packages.nix b/system/packages.nix new file mode 100644 index 0000000..7c8625c --- /dev/null +++ b/system/packages.nix @@ -0,0 +1,37 @@ +{ config, pkgs, ... }: + +{ + nixpkgs.config.allowUnfree = true; + + environment.systemPackages = with pkgs; [ + acpi + alacritty + btop + dconf + dunst + fastfetch + firefox + git + github-cli + gnome-keyring + google-chrome + libnotify + mypy + networkmanagerapplet + nitrogen + pasystray + picom + polkit_gnome + pulseaudioFull + tldr + tmux + unrar + unzip + vim + wget + xclip + ]; + + programs.firefox.enable = true; + programs.thunar.enable = true; +} diff --git a/system/security/default.nix b/system/security/default.nix new file mode 100644 index 0000000..fb10b70 --- /dev/null +++ b/system/security/default.nix @@ -0,0 +1,14 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./sudo.nix + ./systemd.nix + ./users.nix + ]; + + security = { + polkit.enable = true; + rtkit.enable = true; + }; +} diff --git a/system/security/sudo.nix b/system/security/sudo.nix new file mode 100644 index 0000000..f90815b --- /dev/null +++ b/system/security/sudo.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + security.sudo.extraRules = [ + { + users = [ "jashton" ]; + + commands = [ + { + command = "/run/current-system/sw/bin/tlp"; + options = [ "NOPASSWD" ]; + } + ]; + } + ]; +} diff --git a/system/security/systemd.nix b/system/security/systemd.nix new file mode 100644 index 0000000..767a223 --- /dev/null +++ b/system/security/systemd.nix @@ -0,0 +1,19 @@ +{ config, pkgs, ... }: + +{ + systemd = { + user.services.polkit-gnome-authentication-agent-1 = { + description = "polkit-gnome-authentication-agent-1"; + wantedBy = [ "graphical-session.target" ]; + wants = [ "graphics-session.target" ]; + after = [ "graphics-session.target" ]; + serviceConfig = { + Type = "simple"; + ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1"; + Restart = "on-failure"; + RestartSec = 1; + TimeoutStopSec = 10; + }; + }; + }; +} diff --git a/system/security/thinkpad.nix b/system/security/thinkpad.nix new file mode 100644 index 0000000..e55de60 --- /dev/null +++ b/system/security/thinkpad.nix @@ -0,0 +1,9 @@ +{ config, lib, pkgs, ... }: + +{ + services.fprintd = { + enable = true; + #tod.enable = true; + #tod.driver = pkgs.libfprint-2-tod1-goodix; + }; +} diff --git a/system/security/users.nix b/system/security/users.nix new file mode 100644 index 0000000..7696ac7 --- /dev/null +++ b/system/security/users.nix @@ -0,0 +1,17 @@ +{ config, pkgs, ... }: + +{ + users.groups.jashton = {}; + users.users.jashton = { + isNormalUser = true; + description = "Josh Ashton"; + group = "jashton"; + extraGroups = [ "networkmanager" "wheel" ]; + + shell = pkgs.zsh; + }; + + users.users.root = { + shell = pkgs.zsh; + }; +} diff --git a/system/services/default.nix b/system/services/default.nix new file mode 100644 index 0000000..6cc037c --- /dev/null +++ b/system/services/default.nix @@ -0,0 +1,58 @@ +{ config, pkgs, ... }: + +{ + services = { + displayManager = { + ly.enable = true; + }; + + xserver = { + enable = true; + + xkb = { + variant = ""; + layout = "us"; + }; + + windowManager.i3 = { + enable = true; + extraPackages = with pkgs; [ + brightnessctl + dmenu + i3lock-color + playerctl + rofi + xautolock + ]; + }; + }; + + picom = { + enable = true; + backend = "glx"; + vSync = true; + }; + + + libinput = { + enable = true; + }; + + openssh = { + enable = false; + }; + + printing.enable = true; + gvfs.enable = true; + gnome.gnome-keyring.enable = true; + blueman.enable = true; + pipewire = { + enable = true; + alsa = { + enable = true; + support32Bit = true; + }; + pulse.enable = true; + }; + }; +} diff --git a/system/virtualisation/default.nix b/system/virtualisation/default.nix new file mode 100644 index 0000000..36aab12 --- /dev/null +++ b/system/virtualisation/default.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + virtualisation = { + podman = { + enable = true; + dockerCompat = true; + }; + + virtualbox.host.enable = true; + libvirtd.enable = true; + }; +} diff --git a/todo.md b/todo.md new file mode 100644 index 0000000..183d6bb --- /dev/null +++ b/todo.md @@ -0,0 +1,11 @@ +# TODO + +- [x] `tlp` power management +- [x] `tlp` power management widget in polybar +- [ ] notification management and styling +- [ ] login & lockscreen manager +- [ ] lsp in neovim +- [ ] gemini in terminal +- [ ] adaptive workspace icon indicators based on open application (rather than hard coded icons) +- [ ] calendar/clock/timer/alarm/pomodoro widget +- [ ] handwritten note taking application with on-device (or personal cloud) text conversion