theme: add apex-neon configs

This commit is contained in:
s0wlz (Matthias Puchstein)
2025-12-30 04:05:31 +01:00
parent 1c491bbef2
commit 5523871e71
8 changed files with 775 additions and 2256 deletions

View File

@@ -0,0 +1,164 @@
-- Apex Neon: Standalone Theme Engine
-- Philosophy: State over Decoration. Red is Presence. Cyan is Data.
local M = {}
M.palette = {
-- The Void
void = "#050505", -- Background
panel = "#141414", -- Dark Surface (Statusline/Gutter)
border = "#262626", -- Muted Border
stealth = "#404040", -- Comments / Ignored
-- The Signal
text = "#ededed", -- Stark White
dim = "#737373", -- Muted Text
-- The Hunter (Presence)
razor = "#ff0044", -- PRIMARY: Cursor, Current Match, Active Border
alert = "#ff8899", -- ERROR: Readable text on Red
-- The HUD (Data)
tech = "#00eaff", -- INFO: Selection, Search Match, Constants
toxic = "#00ff99", -- SUCCESS: Strings
amber = "#ffb700", -- WARNING: Types, Search
azure = "#0088cc", -- STRUCT: Functions (Deep Blue)
sacred = "#9d00ff", -- SPECIAL: Keywords, Root
}
function M.load()
vim.cmd "hi clear"
if vim.fn.exists "syntax_on" then vim.cmd "syntax reset" end
vim.o.background = "dark"
vim.g.colors_name = "apex-neon"
local p = M.palette
local groups = {
-- CANVAS & UI -----------------------------------------------------------
Normal = { fg = p.text, bg = p.void },
NormalNC = { fg = p.dim, bg = p.void }, -- Non-focused windows
SignColumn = { bg = p.void },
FoldColumn = { fg = p.stealth, bg = p.void },
VertSplit = { fg = p.razor }, -- Deprecated in nvim 0.10, but good fallback
WinSeparator = { fg = p.razor }, -- The Cage (Red Borders)
EndOfBuffer = { fg = p.void }, -- Hide tildes
-- CURSOR & NAVIGATION ("The Hunter") ------------------------------------
Cursor = { fg = p.void, bg = p.razor }, -- Red Beam
TermCursor = { fg = p.void, bg = p.razor },
CursorLine = { bg = p.panel },
CursorLineNr = { fg = p.razor, bold = true }, -- Red Line Number (You are here)
LineNr = { fg = p.stealth }, -- Other lines fade out
-- SELECTION & SEARCH ("Terminator Vision") ------------------------------
Visual = { fg = p.void, bg = p.tech, bold = true }, -- Cyan (Data Lock)
VisualNOS = { fg = p.void, bg = p.border },
Search = { fg = p.void, bg = p.tech }, -- Cyan (Potential Targets)
IncSearch = { fg = p.void, bg = p.razor }, -- Red (Acquiring...)
CurSearch = { fg = p.void, bg = p.razor, bold = true }, -- Red (Target Locked)
-- STATUS & MESSAGES -----------------------------------------------------
StatusLine = { fg = p.text, bg = p.panel },
StatusLineNC = { fg = p.dim, bg = p.void },
WildMenu = { fg = p.void, bg = p.tech },
Pmenu = { fg = p.text, bg = p.panel },
PmenuSel = { fg = p.void, bg = p.razor, bold = true }, -- Red Menu Selection
PmenuSbar = { bg = p.panel },
PmenuThumb = { bg = p.stealth },
-- SYNTAX HIGHLIGHTING ---------------------------------------------------
Comment = { fg = p.stealth, italic = true },
Constant = { fg = p.tech }, -- Cyan (Digital values)
String = { fg = p.toxic }, -- Green (Organic strings)
Character = { fg = p.toxic },
Number = { fg = p.tech },
Boolean = { fg = p.tech },
Float = { fg = p.tech },
Identifier = { fg = p.text }, -- Variables (White)
Function = { fg = p.azure }, -- Deep Blue (Structure)
Statement = { fg = p.sacred }, -- Purple (Keywords)
Conditional = { fg = p.sacred },
Repeat = { fg = p.sacred },
Label = { fg = p.sacred },
Operator = { fg = p.tech }, -- Cyan (Tech)
Keyword = { fg = p.sacred },
Exception = { fg = p.razor }, -- Red (Errors)
PreProc = { fg = p.sacred },
Include = { fg = p.sacred },
Define = { fg = p.sacred },
Macro = { fg = p.sacred },
PreCondit = { fg = p.sacred },
Type = { fg = p.amber }, -- Yellow (Types/Classes)
StorageClass = { fg = p.amber },
Structure = { fg = p.amber },
Typedef = { fg = p.amber },
Special = { fg = p.tech },
SpecialChar = { fg = p.tech },
Tag = { fg = p.tech },
Delimiter = { fg = p.dim }, -- Subtle delimiters
Debug = { fg = p.razor },
Underlined = { underline = true },
Ignore = { fg = p.stealth },
Error = { fg = p.razor },
Todo = { fg = p.void, bg = p.amber, bold = true },
-- DIAGNOSTICS -----------------------------------------------------------
DiagnosticError = { fg = p.razor },
DiagnosticWarn = { fg = p.amber },
DiagnosticInfo = { fg = p.tech },
DiagnosticHint = { fg = p.dim },
DiagnosticUnderlineError = { sp = p.razor, underline = true },
DiagnosticUnderlineWarn = { sp = p.amber, underline = true },
-- PLUGINS: TELESCOPE ("The HUD") ----------------------------------------
TelescopeNormal = { bg = p.void },
TelescopeBorder = { fg = p.razor, bg = p.void }, -- Red Border
TelescopePromptNormal = { fg = p.text, bg = p.void },
TelescopePromptBorder = { fg = p.tech, bg = p.void }, -- Cyan Input Border
TelescopePromptTitle = { fg = p.void, bg = p.tech }, -- Cyan Label
TelescopePreviewTitle = { fg = p.void, bg = p.razor }, -- Red Label
TelescopeResultsTitle = { fg = p.void, bg = p.panel },
TelescopeSelection = { fg = p.void, bg = p.razor }, -- Red Selection
-- PLUGINS: NEO-TREE ("Stealth") -----------------------------------------
NeoTreeNormal = { bg = p.void },
NeoTreeNormalNC = { bg = p.void },
NeoTreeVertSplit = { fg = p.panel, bg = p.void },
NeoTreeWinSeparator = { fg = p.panel, bg = p.void }, -- Fade out tree border
NeoTreeRootName = { fg = p.razor, bold = true }, -- Root is Red
NeoTreeGitAdded = { fg = p.toxic },
NeoTreeGitConflict = { fg = p.amber },
NeoTreeGitDeleted = { fg = p.razor },
NeoTreeGitModified = { fg = p.tech },
-- PLUGINS: GITSIGNS -----------------------------------------------------
GitSignsAdd = { fg = p.toxic, bg = p.void },
GitSignsChange = { fg = p.tech, bg = p.void },
GitSignsDelete = { fg = p.razor, bg = p.void },
-- PLUGINS: CMP (Completion) ---------------------------------------------
CmpItemAbbrDeprecated = { fg = p.dim, strikethrough = true },
CmpItemAbbrMatch = { fg = p.tech, bold = true },
CmpItemAbbrMatchFuzzy = { fg = p.tech, bold = true },
CmpItemKindFunction = { fg = p.azure },
CmpItemKindMethod = { fg = p.azure },
CmpItemKindKeyword = { fg = p.sacred },
CmpItemKindVariable = { fg = p.text },
}
for group, highlight in pairs(groups) do
vim.api.nvim_set_hl(0, group, highlight)
end
end
M.load()
return M

View File

@@ -1,68 +0,0 @@
return {
-- 1. Keep the palette definition (for syntax highlighting)
{
"AstroNvim/astrotheme",
opts = {
palette = {
astrodark = {
bg = "#050505",
fg = "#ededed",
ui = {
base = "#050505",
bg_gutter = "#050505",
bg_p1 = "#141414",
bg_p2 = "#262626",
border = "#ff0044",
},
syntax = {
red = "#ff0044",
orange = "#ffb700",
yellow = "#ffb700",
green = "#00ff99",
cyan = "#00eaff",
blue = "#00eaff",
purple = "#9d00ff",
magenta = "#ff80bf",
comment = "#404040",
},
},
},
},
},
-- 2. THE IMPORTANT PART: Brute force the UI background
{
"AstroNvim/astroui",
opts = {
colorscheme = "astrodark",
highlights = {
-- This 'init' table runs on startup and overwrites everything
init = {
-- FORCE THE MAIN EDITOR BACKGROUND BLACK
Normal = { bg = "#050505", fg = "#ededed" },
NormalNC = { bg = "#050505" }, -- Non-current windows
-- VISUAL SELECTION: TARGET ACQUIRED
Visual = { bg = "#00eaff", fg = "#050505", bold = true },
VisualNOS = { bg = "#00eaff", fg = "#050505" },
-- Force the gutters (line numbers) to blend in
SignColumn = { bg = "#050505" },
FoldColumn = { bg = "#050505" },
-- Aggressive UI Tweaks
WinSeparator = { fg = "#ff0044" },
NeoTreeNormal = { bg = "#050505" },
NeoTreeNormalNC = { bg = "#050505" },
-- Hide the "~" characters at the end of the buffer
EndOfBuffer = { fg = "#050505" },
-- Line numbers
LineNr = { fg = "#404040" },
CursorLineNr = { fg = "#00eaff", bold = true },
},
},
},
},
}

View File

@@ -5,33 +5,33 @@
---@type LazySpec
return {
"AstroNvim/astroui",
---@type AstroUIOpts
opts = {
-- change colorscheme
colorscheme = "astrodark",
-- AstroUI allows you to easily modify highlight groups easily for any and all colorschemes
highlights = {
init = { -- this table overrides highlights in all themes
-- Normal = { bg = "#000000" },
},
astrodark = { -- a table of overrides/changes when applying the astrotheme theme
-- Normal = { bg = "#000000" },
},
},
-- Icons can be configured throughout the interface
icons = {
-- configure the loading of the lsp in the status line
LSPLoading1 = "",
LSPLoading2 = "",
LSPLoading3 = "",
LSPLoading4 = "",
LSPLoading5 = "",
LSPLoading6 = "",
LSPLoading7 = "",
LSPLoading8 = "",
LSPLoading9 = "",
LSPLoading10 = "",
},
},
"AstroNvim/astroui",
---@type AstroUIOpts
opts = {
-- change colorscheme
colorscheme = "apex-neon",
-- AstroUI allows you to easily modify highlight groups easily for any and all colorschemes
highlights = {
init = { -- this table overrides highlights in all themes
-- Normal = { bg = "#000000" },
},
astrodark = { -- a table of overrides/changes when applying the astrotheme theme
-- Normal = { bg = "#000000" },
},
},
-- Icons can be configured throughout the interface
icons = {
-- configure the loading of the lsp in the status line
LSPLoading1 = "",
LSPLoading2 = "",
LSPLoading3 = "",
LSPLoading4 = "",
LSPLoading5 = "",
LSPLoading6 = "",
LSPLoading7 = "",
LSPLoading8 = "",
LSPLoading9 = "",
LSPLoading10 = "",
},
},
}

View File

@@ -1,21 +1,22 @@
@define-color base #050505;
@define-color surface #141414;
@define-color overlay #262626;
@define-color text #ededed;
@define-color muted #404040;
@define-color subtle #404040;
@define-color love #ff0044;
@define-color gold #ffb700;
@define-color rose #ff80bf;
@define-color pine #00ff99;
@define-color foam #00eaff;
@define-color iris #9d00ff;
@define-color base #050505; /* Void Black */
@define-color surface #141414; /* Dark Surface */
@define-color overlay #262626; /* Light Surface */
@define-color text #ededed; /* Stark White */
@define-color muted #737373; /* Muted Text (spec) */
@define-color love #ff0044; /* Razor Red */
@define-color foam #00eaff; /* Electric Cyan */
@define-color pine #00ff99; /* Toxic Green */
@define-color gold #ffb700; /* Warning Gold */
@define-color iris #9d00ff; /* Void Purple */
@define-color hl_low #141414;
@define-color hl_med #262626;
@define-color hl_high #404040;
@define-color hl_high #262626; /* keep borders “light surface”, not random gray */
@define-color bar_alpha rgba(5, 5, 5, 0.65);
@define-color surface_alpha rgba(20, 20, 20, 0.82);
@define-color overlay_alpha rgba(38, 38, 38, 0.9);
@define-color overlay_alpha rgba(38, 38, 38, 0.92);
/* Bar */
window#waybar {
@@ -27,20 +28,15 @@ window#waybar {
/* Extra breathing room for the first/last pill in each section */
#left > :first-child,
#center > :first-child,
#right > :first-child {
margin-top: 8px;
}
#right > :first-child { margin-top: 8px; }
#left > :last-child,
#center > :last-child,
#right > :last-child {
margin-bottom: 8px;
}
#right > :last-child { margin-bottom: 8px; }
/* Typography */
* {
font-family:
"InconsolataGo Nerd Font Mono", "InconsolataGo Nerd Font", monospace;
font-family: "InconsolataGo Nerd Font Mono", "InconsolataGo Nerd Font", monospace;
font-size: 11px;
}
@@ -52,31 +48,38 @@ window#waybar {
font-size: 10px;
}
/* Default workspace = neutral surface */
#workspaces button {
background: @surface_alpha;
color: @text;
border: 1px solid @hl_low;
color: @muted; /* inactive should look “off” */
border: 1px solid @overlay; /* light surface border */
border-radius: 6px;
margin: 2px;
padding: 3px 6px;
}
/* Hover = cyan tech highlight */
#workspaces button:hover {
background: @overlay_alpha;
}
#workspaces button.active {
background: @hl_med;
border-color: @hl_high;
border-color: @foam;
color: @text;
}
/* Active = razor red "target locked" */
#workspaces button.active {
background: @love;
color: @base; /* spec: black text on red */
border-color: @love;
}
/* Urgent = still red, but let it glow harder */
#workspaces button.urgent {
background: @love;
color: @base;
box-shadow: 0 0 6px rgba(255, 0, 68, 0.55);
}
/* Shared pill look for ALL modules - FIXED */
/* Shared pill look for ALL modules */
#window,
#cpu,
#memory,
@@ -98,13 +101,13 @@ window#waybar {
#custom-alhp {
background: @surface_alpha;
color: @text;
border: 1px solid @hl_low;
border: 1px solid @overlay;
border-radius: 8px;
padding: 3px 6px;
margin: 2px 3px;
}
/* Universal hover effects - FIXED */
/* Universal hover = cyan border "scanline" effect */
#window:hover,
#cpu:hover,
#memory:hover,
@@ -125,162 +128,82 @@ window#waybar {
#custom-hyprsunset:hover,
#custom-alhp:hover {
background: @overlay_alpha;
border-color: @foam;
}
/* Window title */
#window {
border-left: 3px solid @iris;
}
/* Focus/primary module accents (Apex-Neon logic) */
#window { border-left: 3px solid @love; } /* focus = Razor Red */
/* Accents for metrics */
#cpu {
border-left: 3px solid @pine;
}
/* Metrics: make them "dashboard semantics" */
#cpu { border-left: 3px solid @pine; } /* success/ok */
#memory { border-left: 3px solid @iris; } /* special */
#disk { border-left: 3px solid @foam; } /* info/tech */
#network{ border-left: 3px solid @foam; } /* network = cyan (tech accent) */
#memory {
border-left: 3px solid @iris;
}
#disk {
border-left: 3px solid @foam;
}
#network {
border-left: 3px solid @gold;
}
/* Temperature modules - individual styling for standalone use */
#temperature.cpu {
border-left: 3px solid @pine;
}
#temperature.gpu_hotspot {
border-left: 3px solid @rose;
}
#temperature.nvme {
border-left: 3px solid @gold;
}
/* Temperature modules */
#temperature.cpu { border-left: 3px solid @pine; }
#temperature.gpu_hotspot { border-left: 3px solid @love; } /* hot = red, not pink */
#temperature.nvme { border-left: 3px solid @gold; }
#temperature.critical {
background: @hl_med;
color: @love;
background: @love;
color: @base; /* black on red */
border-left-color: @love;
border-color: @love;
}
/* WirePlumber / audio */
#wireplumber {
border-left: 3px solid @gold;
}
#wireplumber { border-left: 3px solid @gold; }
#wireplumber.muted {
color: @muted;
border-left-color: @hl_high;
}
#wireplumber.microphone {
border-left-color: @gold;
}
#wireplumber.microphone.muted {
border-left-color: @hl_high;
color: @muted;
border-left-color: @overlay;
}
/* Privacy states */
#privacy.screencast {
border-left: 3px solid @rose;
}
#privacy.microphone {
border-left: 3px solid @gold;
}
#privacy.camera {
border-left: 3px solid @iris;
}
#privacy.screencast { border-left: 3px solid @foam; } /* "active tech" */
#privacy.microphone { border-left: 3px solid @gold; }
#privacy.camera { border-left: 3px solid @iris; }
/* Idle inhibitor */
#idle_inhibitor.activated {
border-left: 3px solid @foam;
}
#idle_inhibitor.deactivated {
border-left: 3px solid @hl_high;
}
#idle_inhibitor.activated { border-left: 3px solid @foam; }
#idle_inhibitor.deactivated { border-left: 3px solid @overlay; color: @muted; }
/* Gamemode */
#gamemode {
border-left: 3px solid @gold;
}
#gamemode { border-left: 3px solid @gold; }
/* Clock */
#clock {
border-left: 3px solid @foam;
}
#clock { border-left: 3px solid @foam; }
/* Battery */
#battery {
border-left: 3px solid @foam;
}
#battery.warning {
border-left-color: @gold;
}
#battery.critical {
border-left-color: @love;
color: @love;
}
#battery { border-left: 3px solid @foam; }
#battery.warning { border-left-color: @gold; }
#battery.critical { border-left-color: @love; color: @love; }
/* Power profiles */
#power-profiles-daemon {
border-left: 3px solid @gold;
}
#power-profiles-daemon.performance {
border-left-color: @love;
}
#power-profiles-daemon.balanced {
border-left-color: @foam;
}
#power-profiles-daemon.power-saver {
border-left-color: @pine;
}
#power-profiles-daemon { border-left: 3px solid @gold; }
#power-profiles-daemon.performance { border-left-color: @love; }
#power-profiles-daemon.balanced { border-left-color: @foam; }
#power-profiles-daemon.power-saver { border-left-color: @pine; }
/* Bluetooth */
#bluetooth {
border-left: 3px solid @iris;
}
#bluetooth { border-left: 3px solid @iris; }
#bluetooth.off,
#bluetooth.disabled {
color: @muted;
border-left-color: @hl_high;
border-left-color: @overlay;
}
/* Notifications */
#custom-swaync {
border-left: 3px solid @iris;
}
#custom-swaync.dnd {
border-left-color: @gold;
}
#custom-swaync { border-left: 3px solid @iris; }
#custom-swaync.dnd { border-left-color: @gold; }
/* Night shift */
#custom-hyprsunset {
border-left: 3px solid @rose;
}
#custom-hyprsunset { border-left: 3px solid @foam; } /* tech accent instead of rose */
/* ALHP custom module - FIXED */
#custom-alhp {
border-left: 3px solid @pine;
}
/* ALHP custom module */
#custom-alhp { border-left: 3px solid @pine; }
/* Group wrappers (no extra padding to avoid width growth) */
/* Group wrappers */
#group-temps,
#group-volume {
background: transparent;
@@ -289,68 +212,43 @@ window#waybar {
padding: 0;
}
#custom-temps-cycle {
border-left: 3px solid @rose;
}
#custom-temps-cycle { border-left: 3px solid @foam; }
#group-temps #temperature {
margin: 2px 0;
}
#group-temps #temperature { margin: 2px 0; }
#group-temps #temperature:hover { background: @overlay_alpha; border-color: @foam; }
#group-temps #temperature:hover {
background: @overlay_alpha;
}
/* Temperature modules within group - maintain specific colors */
#group-temps #temperature.cpu {
border-left: 3px solid @pine;
}
#group-temps #temperature.gpu_edge {
border-left: 3px solid @iris;
}
#group-temps #temperature.gpu_hotspot {
border-left: 3px solid @rose;
}
#group-temps #temperature.nvme {
border-left: 3px solid @gold;
}
/* Preserve semantics within group */
#group-temps #temperature.cpu { border-left: 3px solid @pine; }
#group-temps #temperature.gpu_edge { border-left: 3px solid @iris; }
#group-temps #temperature.gpu_hotspot { border-left: 3px solid @love; }
#group-temps #temperature.nvme { border-left: 3px solid @gold; }
#group-temps #temperature.critical {
background: @hl_med;
color: @text;
background: @love;
color: @base;
}
/* Tray */
#tray {
border-left: 3px solid @iris;
}
#tray > .passive {
opacity: 0.7;
}
#tray { border-left: 3px solid @iris; }
#tray > .passive { opacity: 0.7; }
#tray > .needs-attention {
border-left: 3px solid @love;
box-shadow: 0 0 6px rgba(255, 0, 68, 0.55);
}
/* Volume group sizing */
#group-volume #wireplumber {
margin: 1px 0;
padding: 2px 4px;
}
#group-volume #wireplumber:hover {
background: @overlay_alpha;
}
#group-volume #wireplumber:hover { background: @overlay_alpha; border-color: @foam; }
/* Tooltips */
tooltip,
window#waybar tooltip {
background: @surface;
color: @text;
border: 1px solid @hl_low;
border: 1px solid @overlay;
border-radius: 8px;
padding: 6px 8px;
}
@@ -362,7 +260,7 @@ popover,
.popover {
background: @surface;
color: @text;
border: 1px solid @hl_low;
border: 1px solid @overlay;
border-radius: 8px;
padding: 6px 8px;
}
@@ -378,16 +276,16 @@ menuitem,
menuitem:hover,
.menuitem:hover {
background: @overlay_alpha;
border: 1px solid @foam;
}
menuitem:disabled,
.menuitem:disabled {
color: @muted;
}
.menuitem:disabled { color: @muted; }
menu separator,
.menu separator {
background: @hl_low;
background: @overlay;
min-height: 1px;
margin: 6px 0;
}

View File

@@ -0,0 +1,485 @@
# Apex Neon — Predator Cockpit (Zsh) — v1
# Two-bus design:
# [precmd radar] -> after-action + context bursts (event-driven)
# [promptline] -> LEFT: identity + territory
# RIGHT: intel + vcs + friction (stable)
setopt prompt_subst
setopt no_beep
zmodload zsh/datetime 2>/dev/null
# -----------------------------------------------------------------------------
# 1) PALETTE (Apex Neon DNA)
# -----------------------------------------------------------------------------
typeset -gA C
C[VOID]="#050505"
C[WHITE]="#ededed"
C[MUTED]="#737373"
C[RAZOR]="#ff0044"
C[CYAN]="#00eaff"
C[GOLD]="#ffb700"
C[OK]="#00ff99"
C[PURPLE]="#9d00ff"
C[ALERT]="#ff8899"
# -----------------------------------------------------------------------------
# 2) ICONS / GLYPHS (Nerd Font optional)
# -----------------------------------------------------------------------------
typeset -gA I
I[OS]=""
I[SSH]=""
I[ROOT]=""
I[GIT]=""
I[JOBS]=""
I[RADAR]="⌁"
I[RET]="↩"
typeset -gA S
S[PL_L]=""
S[PL_R]=""
S[DOT]="·"
# -----------------------------------------------------------------------------
# 3) CONFIG
# -----------------------------------------------------------------------------
typeset -gA APEX
APEX[SLOW_SOFT_MS]=750
APEX[SLOW_HARD_MS]=2000
APEX[STARTUP_BURST]=1
APEX[SHOW_AAR]=1
APEX[SHOW_CONTEXT_BURST]=1
APEX[SHOW_VCS]=1
APEX[SHOW_INTEL]=1
APEX[SHOW_JOBS]=1
APEX[SHOW_RO]=1
APEX[GIT_AHEAD_BEHIND]=0
# Ops commands (also match wrappers like sudo/doas/command)
APEX[OPS_RE]='^((sudo|doas|command)[[:space:]]+)*((pacman|yay|paru|apt|dnf|brew|systemctl|docker|kubectl|helm|git))([[:space:]]|$)'
# Session-ish commands (spawn a subshell; exit codes are often “not a failure”)
APEX[SESSION_RE]='^((sudo|doas|command)[[:space:]]+)*chezmoi[[:space:]]+cd([[:space:]]|$)'
# -----------------------------------------------------------------------------
# 4) STATE
# -----------------------------------------------------------------------------
typeset -gF apex_cmd_start=0.0
typeset -g apex_last_cmd=""
typeset -g apex_has_run_cmd=0
typeset -g apex_startup_done=0
typeset -g apex_pwd_changed=1
# Sticky intel
typeset -g apex_venv_name=""
typeset -g apex_target_sig=""
typeset -g apex_mode_sig=""
# Git state
typeset -g apex_in_git=0
typeset -g apex_git_branch=""
typeset -g apex_git_dirty_wt=0
typeset -g apex_git_dirty_ix=0
typeset -g apex_git_op=""
typeset -g apex_git_up_ok=0
typeset -g apex_git_ahead=0
typeset -g apex_git_behind=0
# Radar previous snapshots (transition detection)
typeset -g apex_prev_in_git=-1
typeset -g apex_prev_git_branch=""
typeset -g apex_prev_git_op=""
typeset -g apex_prev_venv_name=""
typeset -g apex_prev_target_sig=""
typeset -g apex_prev_proj_sig=""
# -----------------------------------------------------------------------------
# 5) UTILITIES
# -----------------------------------------------------------------------------
apex__short_cmd() {
local s="$1"
s="${s//$'\n'/ }"
s="${s#"${s%%[![:space:]]*}"}" # ltrim
s="${s%"${s##*[![:space:]]}"}" # rtrim
print -r -- "${s[1,90]}"
}
apex__project_sig() {
local s=""
[[ -f package.json ]] && s+="node"
[[ -f pnpm-lock.yaml ]] && s+="+pnpm"
[[ -f bun.lockb ]] && s+="+bun"
[[ -f yarn.lock ]] && s+="+yarn"
[[ -f pyproject.toml || -f requirements.txt ]] && s+="${s:+ }py"
[[ -f uv.lock ]] && s+="+uv"
[[ -f Cargo.toml ]] && s+="${s:+ }rust"
[[ -f go.mod ]] && s+="${s:+ }go"
[[ -n "$s" ]] && print -r -- "$s"
}
# -----------------------------------------------------------------------------
# 6) INTEL (sticky; updated each prompt)
# -----------------------------------------------------------------------------
apex_update_intel() {
# Target (cheap env-based; no kubectl calls)
if [[ -n "$AWS_PROFILE" ]]; then
apex_target_sig="aws:${AWS_PROFILE}"
elif [[ -n "$GOOGLE_CLOUD_PROJECT" ]]; then
apex_target_sig="gcp:${GOOGLE_CLOUD_PROJECT}"
elif [[ -n "$KUBE_CONTEXT" ]]; then
apex_target_sig="kube:${KUBE_CONTEXT}"
else
apex_target_sig=""
fi
# Mode
if [[ -n "$IN_NIX_SHELL" ]]; then
apex_mode_sig="nix"
elif [[ -n "$DIRENV_DIR" ]]; then
apex_mode_sig="direnv"
else
apex_mode_sig=""
fi
# Venv
apex_venv_name=""
if [[ -n "$VIRTUAL_ENV" ]]; then
apex_venv_name="$(basename "$VIRTUAL_ENV")"
elif [[ -n "$CONDA_DEFAULT_ENV" ]]; then
apex_venv_name="$CONDA_DEFAULT_ENV"
fi
}
# -----------------------------------------------------------------------------
# 7) GIT
# -----------------------------------------------------------------------------
apex_git_update() {
apex_in_git=0
apex_git_branch=""
apex_git_dirty_wt=0
apex_git_dirty_ix=0
apex_git_op=""
apex_git_up_ok=0
apex_git_ahead=0
apex_git_behind=0
command git rev-parse --is-inside-work-tree &>/dev/null || return
apex_in_git=1
apex_git_branch="$(
command git symbolic-ref --quiet --short HEAD 2>/dev/null \
|| command git rev-parse --short HEAD 2>/dev/null
)"
local gd; gd="$(command git rev-parse --git-dir 2>/dev/null)" || return
[[ -d "$gd/rebase-apply" || -d "$gd/rebase-merge" ]] && apex_git_op="rebase"
[[ -f "$gd/MERGE_HEAD" ]] && apex_git_op="merge"
[[ -f "$gd/CHERRY_PICK_HEAD" ]] && apex_git_op="cherry-pick"
[[ -f "$gd/BISECT_LOG" ]] && apex_git_op="bisect"
# Dirty markers
command git diff --quiet --ignore-submodules -- 2>/dev/null || apex_git_dirty_wt=1
command git diff --cached --quiet --ignore-submodules -- 2>/dev/null || apex_git_dirty_ix=1
# Upstream (earned ✓)
if command git rev-parse --abbrev-ref --symbolic-full-name @{u} &>/dev/null; then
local counts
counts="$(command git rev-list --left-right --count @{u}...HEAD 2>/dev/null)" || return
apex_git_behind="${counts%% *}"
apex_git_ahead="${counts##* }"
if (( apex_git_dirty_wt == 0 && apex_git_dirty_ix == 0 )) && [[ -z "$apex_git_op" ]]; then
[[ "$apex_git_behind" == "0" && "$apex_git_ahead" == "0" ]] && apex_git_up_ok=1
fi
fi
}
# -----------------------------------------------------------------------------
# 8) LEFT PROMPTLINE: IDENTITY + TERRITORY
# -----------------------------------------------------------------------------
apex_identity() {
local is_root=0 is_ssh=0 color label
(( EUID == 0 )) && is_root=1
[[ -n "$SSH_CONNECTION$SSH_TTY" ]] && is_ssh=1
if (( is_root )); then
color="${C[PURPLE]}"
if (( is_ssh )); then
label="${I[ROOT]} @%m"
else
label="${I[ROOT]} root"
fi
elif (( is_ssh )); then
color="${C[CYAN]}"
label="${I[SSH]} %n@%m"
else
return 0
fi
print -n "%F{${color}}${S[PL_L]}%f%K{${color}}%F{${C[VOID]}}%B ${label} %b%f%k%F{${color}}${S[PL_R]}%f "
}
apex_territory() {
print -n "%F{${C[RAZOR]}}${S[PL_L]}%f%K{${C[RAZOR]}}%F{${C[VOID]}}%B ${I[OS]}%b %F{${C[WHITE]}}%B%~%b %f%k%F{${C[RAZOR]}}${S[PL_R]}%f"
}
# -----------------------------------------------------------------------------
# 9) RIGHT PROMPT (RPROMPT): INTEL + VCS + FRICTION
# -----------------------------------------------------------------------------
apex_intel_r() {
(( APEX[SHOW_INTEL] )) || return 0
if [[ -n "$apex_target_sig" ]]; then
print -n "%F{${C[CYAN]}}(${apex_target_sig})%f"
elif [[ -n "$apex_mode_sig" ]]; then
print -n "%F{${C[CYAN]}}(${apex_mode_sig})%f"
elif [[ -n "$apex_venv_name" ]]; then
print -n "%F{${C[CYAN]}}(${apex_venv_name})%f"
fi
}
apex_vcs_r() {
(( APEX[SHOW_VCS] )) || return 0
(( apex_in_git )) || return 0
if [[ -n "$apex_git_op" ]]; then
print -n "%F{${C[ALERT]}}${I[GIT]} ${apex_git_branch} ${apex_git_op}%f"
return 0
fi
print -n "%F{${C[CYAN]}}${I[GIT]} ${apex_git_branch}%f"
local mark=""
(( apex_git_dirty_ix )) && mark+="+"
(( apex_git_dirty_wt )) && mark+="!"
[[ -n "$mark" ]] && print -n "%F{${C[GOLD]}} ${mark}%f"
(( apex_git_up_ok )) && print -n "%F{${C[OK]}} ✓%f"
if (( APEX[GIT_AHEAD_BEHIND] )); then
(( apex_git_ahead > 0 )) && print -n "%F{${C[MUTED]}} ⇡${apex_git_ahead}%f"
(( apex_git_behind > 0 )) && print -n "%F{${C[MUTED]}} ⇣${apex_git_behind}%f"
fi
}
apex_friction_r() {
if (( APEX[SHOW_RO] )) && [[ ! -w . ]]; then
print -n "%F{${C[GOLD]}}${I[ROOT]} ro%f"
return 0
fi
if (( APEX[SHOW_JOBS] )); then
local jc
jc=$(jobs -p 2>/dev/null | wc -l | tr -d ' ')
if [[ -n "$jc" && "$jc" != "0" ]]; then
print -n "%F{${C[MUTED]}}${I[JOBS]} ${jc}%f"
return 0
fi
fi
}
build_rprompt() {
local s out=""
local sep="%F{${C[MUTED]}} ${S[DOT]} %f"
s="$(apex_intel_r)"; [[ -n "$s" ]] && out+="$s"
s="$(apex_vcs_r)"; [[ -n "$s" ]] && out+="${out:+$sep}$s"
s="$(apex_friction_r)"; [[ -n "$s" ]] && out+="${out:+$sep}$s"
[[ -n "$out" ]] && out="%F{${C[MUTED]}}[%f${out}%F{${C[MUTED]}}]%f"
print -n "$out"
}
# -----------------------------------------------------------------------------
# 10) RADAR (precmd)
# -----------------------------------------------------------------------------
apex_radar_aar() {
(( APEX[SHOW_AAR] )) || return 0
local ec=$1 cmd="$2" dur="$3"
local -i ms=${4:-0}
local show=0
(( ec != 0 )) && show=1
[[ -n "$dur" ]] && show=1
[[ "$cmd" =~ ${APEX[OPS_RE]} ]] && show=1
(( show )) || return 0
local short; short="$(apex__short_cmd "$cmd")"
local dur_color="${C[MUTED]}"
(( ms >= ${APEX[SLOW_HARD_MS]} )) && dur_color="${C[GOLD]}"
local dur_chunk=""
if [[ -n "$dur" ]]; then
if (( ms >= ${APEX[SLOW_HARD_MS]} )); then
dur_chunk=" %F{${dur_color}}%B${dur}%b%f"
else
dur_chunk=" %F{${dur_color}}${dur}%f"
fi
fi
# Session commands: don't scream in red for “rc:1”
if [[ "$cmd" =~ ${APEX[SESSION_RE]} ]]; then
if (( ec == 0 )); then
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[OK]}}${I[RET]}%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
else
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[GOLD]}}${I[RET]}%f %F{${C[WHITE]}}${short}%f %F{${C[MUTED]}}rc:${ec}%f${dur_chunk}"
fi
return 0
fi
if (( ec == 0 )); then
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[OK]}}✓%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
return 0
fi
# Signals: 128 + signal number
case $ec in
130) # SIGINT (Ctrl+C)
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[CYAN]}}^C%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
141) # SIGPIPE
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[MUTED]}}PIPE%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
143) # SIGTERM
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[GOLD]}}TERM%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
*)
print -P "%F{${C[MUTED]}}${I[RADAR]}%f %F{${C[ALERT]}}✘ ${ec}%f %F{${C[WHITE]}}${short}%f${dur_chunk}"
;;
esac
}
apex_radar_context_burst() {
(( APEX[SHOW_CONTEXT_BURST] )) || return 0
local proj_sig; proj_sig="$(apex__project_sig 2>/dev/null || print -r -- "")"
local emit=0
if (( apex_startup_done == 0 )); then
(( APEX[STARTUP_BURST] )) && emit=1
fi
(( apex_pwd_changed )) && emit=1
[[ "$apex_venv_name" != "$apex_prev_venv_name" ]] && emit=1
[[ "$apex_target_sig" != "$apex_prev_target_sig" ]] && emit=1
(( apex_in_git != apex_prev_in_git )) && emit=1
[[ "$apex_git_branch" != "$apex_prev_git_branch" ]] && emit=1
[[ "$apex_git_op" != "$apex_prev_git_op" ]] && emit=1
[[ "$proj_sig" != "$apex_prev_proj_sig" ]] && emit=1
(( emit )) || return 0
# If nothing to say, say nothing.
if [[ -z "$proj_sig" && -z "$apex_venv_name" && -z "$apex_target_sig" ]] && (( apex_in_git == 0 )); then
apex_pwd_changed=0
apex_startup_done=1
return 0
fi
local out="%F{${C[MUTED]}}${I[RADAR]}%f "
# Git first
if (( apex_in_git )); then
if [[ -n "$apex_git_op" ]]; then
out+="%F{${C[ALERT]}}${I[GIT]} ${apex_git_branch} ${apex_git_op}%f"
else
out+="%F{${C[CYAN]}}${I[GIT]} ${apex_git_branch}%f"
fi
fi
[[ -n "$proj_sig" ]] && out+="${out:+ %F{${C[MUTED]}}·%f }%F{${C[MUTED]}}${proj_sig}%f"
[[ -n "$apex_venv_name" ]] && out+="${out:+ %F{${C[MUTED]}}·%f }%F{${C[CYAN]}}(${apex_venv_name})%f"
[[ -n "$apex_target_sig" ]] && out+="${out:+ %F{${C[MUTED]}}·%f }%F{${C[CYAN]}}(${apex_target_sig})%f"
print -P "$out"
apex_prev_venv_name="$apex_venv_name"
apex_prev_target_sig="$apex_target_sig"
apex_prev_in_git="$apex_in_git"
apex_prev_git_branch="$apex_git_branch"
apex_prev_git_op="$apex_git_op"
apex_prev_proj_sig="$proj_sig"
apex_pwd_changed=0
apex_startup_done=1
}
# -----------------------------------------------------------------------------
# 11) HOOKS
# -----------------------------------------------------------------------------
apex_preexec_hook() {
apex_has_run_cmd=1
apex_cmd_start=${EPOCHREALTIME:-$EPOCHSECONDS}
apex_last_cmd="$1"
}
apex_chpwd_hook() {
apex_pwd_changed=1
}
apex_precmd_hook() {
local ec=$?
apex_update_intel
apex_git_update
# Did a command actually run since the last prompt?
local ran=0
(( apex_has_run_cmd )) && ran=1
if (( ran )); then
local now=${EPOCHREALTIME:-$EPOCHSECONDS}
local -i ms
ms=$(( (now - apex_cmd_start) * 1000 ))
# Show time if: slow OR ops OR failed.
local dur=""
if (( ms >= ${APEX[SLOW_SOFT_MS]} )) || [[ "$apex_last_cmd" =~ ${APEX[OPS_RE]} ]] || (( ec != 0 )); then
dur="$(printf "%.2fs" $(( ms / 1000.0 )))"
fi
apex_radar_aar $ec "$apex_last_cmd" "$dur" $ms
apex_has_run_cmd=0
# Spacer between AAR and context burst / prompt.
print -r -- ""
fi
apex_radar_context_burst
}
autoload -Uz add-zsh-hook
add-zsh-hook preexec apex_preexec_hook
add-zsh-hook precmd apex_precmd_hook
add-zsh-hook chpwd apex_chpwd_hook
# -----------------------------------------------------------------------------
# 12) PROMPT BUILD
# -----------------------------------------------------------------------------
build_prompt() {
local ec=$?
# Line 1: identity + territory (left)
print -n "$(apex_identity)"
print -n "$(apex_territory)"
print -n $'\n'
# Line 2: trigger posture
if (( EUID == 0 )); then
print -n "%F{${C[PURPLE]}}%f "
elif (( ec != 0 )); then
print -n "%F{${C[ALERT]}}%f "
else
print -n "%F{${C[CYAN]}}%f "
fi
}
PROMPT='$(build_prompt)'
RPROMPT='$(build_rprompt)'

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,6 @@ zmodule utility
zmodule fzf
zmodule ssh
zmodule git
zmodule romkatv/powerlevel10k --use degit
zmodule joke/zim-yq
zmodule joke/zim-kubectl
zmodule https://github.com/fdellwing/zsh-bat.git

View File

@@ -1,10 +1,3 @@
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.config/zsh/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# Load personal aliases
if [[ -f "${HOME}/.config/zsh/aliases.zsh" ]]; then
source "${HOME}/.config/zsh/aliases.zsh"
@@ -34,5 +27,5 @@ bindkey "^[OB" history-substring-search-down
bindkey -M vicmd 'k' history-substring-search-up
bindkey -M vicmd 'j' history-substring-search-down
# To customize prompt, run `p10k configure` or edit ~/.config/zsh/.p10k.zsh.
[[ ! -f ~/.config/zsh/.p10k.zsh ]] || source ~/.config/zsh/.p10k.zsh
# Initialize Apex Neon Theme
source ~/.config/zsh/apex-neon.zsh