From 899a1aa1ab29c3f33c76cff728947799345e527f Mon Sep 17 00:00:00 2001 From: Jeremy McClure Date: Sat, 1 Aug 2026 07:19:37 -0400 Subject: [PATCH] Add 16 files (16+ files changed) --- .dotstate-profiles.toml | 24 ++ default/.config/ghostty/config | 69 ++++ default/.config/ghostty/cursor_warp.glsl | 308 ++++++++++++++++++ .../ghostty/ripple_rectangle_cursor.glsl | 138 ++++++++ default/.config/starship.toml | 101 ++++++ default/.config/tmux/tmux.conf | 139 ++++++++ default/.config/zsh/.zlogin | 10 + default/.config/zsh/.zlogout | 2 + default/.config/zsh/.zprofile | 8 + default/.config/zsh/.zsh_plugins.txt | 27 ++ default/.config/zsh/.zshenv | 0 default/.config/zsh/.zshrc | 9 + default/.config/zsh/aliases.zsh | 27 ++ default/.config/zsh/bootstrap.sh | 138 ++++++++ default/.config/zsh/functions.zsh | 7 + default/.config/zsh/init.zsh | 54 +++ default/.zshenv | 12 + 17 files changed, 1073 insertions(+) create mode 100644 .dotstate-profiles.toml create mode 100644 default/.config/ghostty/config create mode 100644 default/.config/ghostty/cursor_warp.glsl create mode 100644 default/.config/ghostty/ripple_rectangle_cursor.glsl create mode 100644 default/.config/starship.toml create mode 100644 default/.config/tmux/tmux.conf create mode 100644 default/.config/zsh/.zlogin create mode 100644 default/.config/zsh/.zlogout create mode 100644 default/.config/zsh/.zprofile create mode 100644 default/.config/zsh/.zsh_plugins.txt create mode 100644 default/.config/zsh/.zshenv create mode 100644 default/.config/zsh/.zshrc create mode 100644 default/.config/zsh/aliases.zsh create mode 100755 default/.config/zsh/bootstrap.sh create mode 100644 default/.config/zsh/functions.zsh create mode 100644 default/.config/zsh/init.zsh create mode 100644 default/.zshenv diff --git a/.dotstate-profiles.toml b/.dotstate-profiles.toml new file mode 100644 index 0000000..e62bfb2 --- /dev/null +++ b/.dotstate-profiles.toml @@ -0,0 +1,24 @@ +version = 2 + +[common] +synced_files = [] + +[[profiles]] +name = "default" +synced_files = [ + ".config/ghostty", + ".config/starship.toml", + ".config/tmux/tmux.conf", + ".config/zsh/.zlogin", + ".config/zsh/.zlogout", + ".config/zsh/.zprofile", + ".config/zsh/.zsh_plugins.txt", + ".config/zsh/.zshenv", + ".config/zsh/.zshrc", + ".config/zsh/aliases.zsh", + ".config/zsh/bootstrap.sh", + ".config/zsh/functions.zsh", + ".config/zsh/init.zsh", + ".zshenv", +] +packages = [] diff --git a/default/.config/ghostty/config b/default/.config/ghostty/config new file mode 100644 index 0000000..715749c --- /dev/null +++ b/default/.config/ghostty/config @@ -0,0 +1,69 @@ +# GitHub Dark Default theme (matching Alacritty) +background = #0d1117 +foreground = #b3b1ad +palette = 0=#484f58 +palette = 1=#ff7b72 +palette = 2=#3fb950 +palette = 3=#d29922 +palette = 4=#58a6ff +palette = 5=#bc8cff +palette = 6=#39c5cf +palette = 7=#b1bac4 +palette = 8=#6e7681 +palette = 9=#ffa198 +palette = 10=#56d364 +palette = 11=#e3b341 +palette = 12=#79c0ff +palette = 13=#d2a8ff +palette = 14=#56d4dd +palette = 15=#f0f6fc +palette = 16=#d18616 +palette = 17=#ffa198 + +# Font +font-family = SFMono Nerd Font +font-family-bold = SFMono Nerd Font SemiBold +font-family-italic = SFMono Nerd Font Italic +font-family-bold-italic = SFMono Nerd Font Bold Italic +font-size = 11.25 + +# Window +background-opacity = 0.95 +window-padding-x = 5 +window-padding-y = 5 + +# Cursor +cursor-style = block +cursor-style-blink = false + +# Mouse +mouse-hide-while-typing = true + +confirm-close-surface = false +window-save-state = always +bold-is-bright = true +resize-overlay-duration = 0 +selection-foreground = #0d1117 +selection-background = #b3b1ad + +# Selection - auto-copy to clipboard on select +copy-on-select = clipboard + +# Scrolling +scrollback-limit = 10000 + +# Shell +command = /bin/zsh --login + +# Terminal env +term = xterm-256color + +# Cursor shaders — warp trail + ripple pulse +custom-shader-animation = always +custom-shader = cursor_warp.glsl +custom-shader = ripple_rectangle_cursor.glsl + +# Keybindings (matching Alacritty) +keybind = ctrl+shift+c=copy_to_clipboard +keybind = ctrl+shift+v=paste_from_clipboard +keybind = ctrl+shift+n=new_window diff --git a/default/.config/ghostty/cursor_warp.glsl b/default/.config/ghostty/cursor_warp.glsl new file mode 100644 index 0000000..1860c50 --- /dev/null +++ b/default/.config/ghostty/cursor_warp.glsl @@ -0,0 +1,308 @@ +// sRGB -> Linear conversion (needed because Ghostty passes sRGB values but the shader pipeline operates in linear color space) +vec3 sRGBToLinear(vec3 c) { + return mix(c / 12.92, pow((c + 0.055) / 1.055, vec3(2.4)), step(vec3(0.04045), c)); +} + +// --- CONFIGURATION --- +vec4 TRAIL_COLOR = vec4(sRGBToLinear(iCurrentCursorColor.rgb), iCurrentCursorColor.a); // for custom color: vec4(0.2, 0.6, 1.0, 0.5); (wrap in sRGBToLinear for correct brightness) +const float DURATION = 0.2; // total animation time +const float TRAIL_SIZE = 0.8; // 0.0 = all corners move together. 1.0 = max smear (leading corners jump instantly) +const float THRESHOLD_MIN_DISTANCE = 1.5; // min distance to show trail (units of cursor height) +const float BLUR = 1.0; // blur size in pixels (for antialiasing) +const float TRAIL_THICKNESS = 1.0; // 1.0 = full cursor height, 0.0 = zero height, >1.0 = funky aah +const float TRAIL_THICKNESS_X = 0.9; + +const float FADE_ENABLED = 0.0; // 1.0 to enable fade gradient along the trail, 0.0 to disable +const float FADE_EXPONENT = 5.0; // exponent for fade gradient along the trail + +// --- CONSTANTS for easing functions --- +const float PI = 3.14159265359; +const float C1_BACK = 1.70158; +const float C2_BACK = C1_BACK * 1.525; +const float C3_BACK = C1_BACK + 1.0; +const float C4_ELASTIC = (2.0 * PI) / 3.0; +const float C5_ELASTIC = (2.0 * PI) / 4.5; +const float SPRING_STIFFNESS = 9.0; +const float SPRING_DAMPING = 0.9; + +// --- EASING FUNCTIONS --- + +// // Linear +// float ease(float x) { +// return x; +// } + +// // EaseOutQuad +// float ease(float x) { +// return 1.0 - (1.0 - x) * (1.0 - x); +// } + +// // EaseOutCubic +// float ease(float x) { +// return 1.0 - pow(1.0 - x, 3.0); +// } + +// // EaseOutQuart +// float ease(float x) { +// return 1.0 - pow(1.0 - x, 4.0); +// } + +// // EaseOutQuint +// float ease(float x) { +// return 1.0 - pow(1.0 - x, 5.0); +// } + +// // EaseOutSine +// float ease(float x) { +// return sin((x * PI) / 2.0); +// } + +// // EaseOutExpo +// float ease(float x) { +// return x == 1.0 ? 1.0 : 1.0 - pow(2.0, -10.0 * x); +// } + +// EaseOutCirc +float ease(float x) { + return sqrt(1.0 - pow(x - 1.0, 2.0)); +} + +// // EaseOutBack +// float ease(float x) { +// return 1.0 + C3_BACK * pow(x - 1.0, 3.0) + C1_BACK * pow(x - 1.0, 2.0); +// } + +// // EaseOutElastic +// float ease(float x) { +// return x == 0.0 ? 0.0 +// : x == 1.0 ? 1.0 +// : pow(2.0, -10.0 * x) * sin((x * 10.0 - 0.75) * C4_ELASTIC) + 1.0; +// } + +// // Parametric Spring +// float ease(float x) { +// x = clamp(x, 0.0, 1.0); +// float decay = exp(-SPRING_DAMPING * SPRING_STIFFNESS * x); +// float freq = sqrt(SPRING_STIFFNESS * (1.0 - SPRING_DAMPING * SPRING_DAMPING)); +// float osc = cos(freq * 6.283185 * x) + (SPRING_DAMPING * sqrt(SPRING_STIFFNESS) / freq) * sin(freq * 6.283185 * x); +// return 1.0 - decay * osc; +// } + +float getSdfRectangle(in vec2 p, in vec2 xy, in vec2 b) +{ + vec2 d = abs(p - xy) - b; + return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); +} + +// Based on Inigo Quilez's 2D distance functions article: https://iquilezles.org/articles/distfunctions2d/ +// Potencially optimized by eliminating conditionals and loops to enhance performance and reduce branching +float seg(in vec2 p, in vec2 a, in vec2 b, inout float s, float d) { + vec2 e = b - a; + vec2 w = p - a; + vec2 proj = a + e * clamp(dot(w, e) / dot(e, e), 0.0, 1.0); + float segd = dot(p - proj, p - proj); + d = min(d, segd); + + float c0 = step(0.0, p.y - a.y); + float c1 = 1.0 - step(0.0, p.y - b.y); + float c2 = 1.0 - step(0.0, e.x * w.y - e.y * w.x); + float allCond = c0 * c1 * c2; + float noneCond = (1.0 - c0) * (1.0 - c1) * (1.0 - c2); + float flip = mix(1.0, -1.0, step(0.5, allCond + noneCond)); + s *= flip; + return d; +} + +float getSdfConvexQuad(in vec2 p, in vec2 v1, in vec2 v2, in vec2 v3, in vec2 v4) { + float s = 1.0; + float d = dot(p - v1, p - v1); + + d = seg(p, v1, v2, s, d); + d = seg(p, v2, v3, s, d); + d = seg(p, v3, v4, s, d); + d = seg(p, v4, v1, s, d); + + return s * sqrt(d); +} + +vec2 normalize(vec2 value, float isPosition) { + return (value * 2.0 - (iResolution.xy * isPosition)) / iResolution.y; +} + +float antialising(float distance, float blurAmount) { + return 1. - smoothstep(0., normalize(vec2(blurAmount, blurAmount), 0.).x, distance); +} + +// Determines animation duration based on a corner's alignment with the move direction(dot product) +// dot_val will be in [-2, 2] +// > 0.5 (1 or 2) = Leading +// > -0.5 (0) = Side +// <= -0.5 (-1 or -2) = Trailing +float getDurationFromDot(float dot_val, float DURATION_LEAD, float DURATION_SIDE, float DURATION_TRAIL) { + float isLead = step(0.5, dot_val); + float isSide = step(-0.5, dot_val) * (1.0 - isLead); + + // Start with trailing duration + float duration = mix(DURATION_TRAIL, DURATION_SIDE, isSide); + // Mix in leading duration + duration = mix(duration, DURATION_LEAD, isLead); + return duration; +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord){ + #if !defined(WEB) + fragColor = texture(iChannel0, fragCoord.xy / iResolution.xy); + #endif + + // normalization & setup(-1, 1 coords) + vec2 vu = normalize(fragCoord, 1.); + vec2 offsetFactor = vec2(-.5, 0.5); + + vec4 currentCursor = vec4(normalize(iCurrentCursor.xy, 1.), normalize(iCurrentCursor.zw, 0.)); + vec4 previousCursor = vec4(normalize(iPreviousCursor.xy, 1.), normalize(iPreviousCursor.zw, 0.)); + + vec2 centerCC = currentCursor.xy - (currentCursor.zw * offsetFactor); + vec2 halfSizeCC = currentCursor.zw * 0.5; + vec2 centerCP = previousCursor.xy - (previousCursor.zw * offsetFactor); + vec2 halfSizeCP = previousCursor.zw * 0.5; + + float sdfCurrentCursor = getSdfRectangle(vu, centerCC, halfSizeCC); + + float lineLength = distance(centerCC, centerCP); + float minDist = currentCursor.w * THRESHOLD_MIN_DISTANCE; + + vec4 newColor = vec4(fragColor); + + float baseProgress = iTime - iTimeCursorChange; + + if (lineLength > minDist && baseProgress < DURATION - 0.001) { + // defining corners of cursors + + // Y (Height) with TRAIL_THICKNESS + float cc_half_height = currentCursor.w * 0.5; + float cc_center_y = currentCursor.y - cc_half_height; + float cc_new_half_height = cc_half_height * TRAIL_THICKNESS; + float cc_new_top_y = cc_center_y + cc_new_half_height; + float cc_new_bottom_y = cc_center_y - cc_new_half_height; + + // X (Width) with TRAIL_THICKNESS + float cc_half_width = currentCursor.z * 0.5; + float cc_center_x = currentCursor.x + cc_half_width; + float cc_new_half_width = cc_half_width * TRAIL_THICKNESS_X; + float cc_new_left_x = cc_center_x - cc_new_half_width; + float cc_new_right_x = cc_center_x + cc_new_half_width; + + vec2 cc_tl = vec2(cc_new_left_x, cc_new_top_y); + vec2 cc_tr = vec2(cc_new_right_x, cc_new_top_y); + vec2 cc_bl = vec2(cc_new_left_x, cc_new_bottom_y); + vec2 cc_br = vec2(cc_new_right_x, cc_new_bottom_y); + + // same thing for previous cursor + float cp_half_height = previousCursor.w * 0.5; + float cp_center_y = previousCursor.y - cp_half_height; + float cp_new_half_height = cp_half_height * TRAIL_THICKNESS; + float cp_new_top_y = cp_center_y + cp_new_half_height; + float cp_new_bottom_y = cp_center_y - cp_new_half_height; + + float cp_half_width = previousCursor.z * 0.5; + float cp_center_x = previousCursor.x + cp_half_width; + float cp_new_half_width = cp_half_width * TRAIL_THICKNESS_X; + float cp_new_left_x = cp_center_x - cp_new_half_width; + float cp_new_right_x = cp_center_x + cp_new_half_width; + + vec2 cp_tl = vec2(cp_new_left_x, cp_new_top_y); + vec2 cp_tr = vec2(cp_new_right_x, cp_new_top_y); + vec2 cp_bl = vec2(cp_new_left_x, cp_new_bottom_y); + vec2 cp_br = vec2(cp_new_right_x, cp_new_bottom_y); + + // calculating durations for every corner + const float DURATION_TRAIL = DURATION; + const float DURATION_LEAD = DURATION * (1.0 - TRAIL_SIZE); + const float DURATION_SIDE = (DURATION_LEAD + DURATION_TRAIL) / 2.0; + + vec2 moveVec = centerCC - centerCP; + vec2 s = sign(moveVec); + + // dot products for each corner, determining alignment with movement direction + float dot_tl = dot(vec2(-1., 1.), s); + float dot_tr = dot(vec2( 1., 1.), s); + float dot_bl = dot(vec2(-1.,-1.), s); + float dot_br = dot(vec2( 1.,-1.), s); + + // assign durations based on dot products + float dur_tl = getDurationFromDot(dot_tl, DURATION_LEAD, DURATION_SIDE, DURATION_TRAIL); + float dur_tr = getDurationFromDot(dot_tr, DURATION_LEAD, DURATION_SIDE, DURATION_TRAIL); + float dur_bl = getDurationFromDot(dot_bl, DURATION_LEAD, DURATION_SIDE, DURATION_TRAIL); + float dur_br = getDurationFromDot(dot_br, DURATION_LEAD, DURATION_SIDE, DURATION_TRAIL); + + // check direction of horizontal movement + float isMovingRight = step(0.5, s.x); + float isMovingLeft = step(0.5, -s.x); + + // calculate vertical-rail durations + float dot_right_edge = (dot_tr + dot_br) * 0.5; + float dur_right_rail = getDurationFromDot(dot_right_edge, DURATION_LEAD, DURATION_SIDE, DURATION_TRAIL); + + float dot_left_edge = (dot_tl + dot_bl) * 0.5; + float dur_left_rail = getDurationFromDot(dot_left_edge, DURATION_LEAD, DURATION_SIDE, DURATION_TRAIL); + + float final_dur_tl = mix(dur_tl, dur_left_rail, isMovingLeft); + float final_dur_bl = mix(dur_bl, dur_left_rail, isMovingLeft); + + float final_dur_tr = mix(dur_tr, dur_right_rail, isMovingRight); + float final_dur_br = mix(dur_br, dur_right_rail, isMovingRight); + + // calculate progress for each corner based on the duration and time since cursor change + float prog_tl = ease(clamp(baseProgress / final_dur_tl, 0.0, 1.0)); + float prog_tr = ease(clamp(baseProgress / final_dur_tr, 0.0, 1.0)); + float prog_bl = ease(clamp(baseProgress / final_dur_bl, 0.0, 1.0)); + float prog_br = ease(clamp(baseProgress / final_dur_br, 0.0, 1.0)); + + // get the trial corner positions based on progress + vec2 v_tl = mix(cp_tl, cc_tl, prog_tl); + vec2 v_tr = mix(cp_tr, cc_tr, prog_tr); + vec2 v_br = mix(cp_br, cc_br, prog_br); + vec2 v_bl = mix(cp_bl, cc_bl, prog_bl); + + // DRAWING THE TRAIL + float sdfTrail = getSdfConvexQuad(vu, v_tl, v_tr, v_br, v_bl); + + // --- FADE GRADIENT CALCULATION --- + vec2 fragVec = vu - centerCP; + + // project fragment onto movement vector, normalize to [0, 1] + // 0.0 at tail, 1.0 at head + // tiny epsilon to avoid division by zero if moveVec is (0,0) + float fadeProgress = clamp(dot(fragVec, moveVec) / (dot(moveVec, moveVec) + 1e-6), 0.0, 1.0); + + vec4 trail = TRAIL_COLOR; + + float effectiveBlur = BLUR; + if (BLUR < 2.5) { + // no antialising on horizontal/vertical movement, fixes 'pulse' like thing on end cursor + float isDiagonal = abs(s.x) * abs(s.y); // 1.0 if diagonal, 0.0 if H/V + float effectiveBlur = mix(0.0, BLUR, isDiagonal); + } + float shapeAlpha = antialising(sdfTrail, effectiveBlur); // shape mask + + if (FADE_ENABLED > 0.5) { + // apply fade gradient along the trail + // float fadeStart = 0.2; + // float easedProgress = smoothstep(fadeStart, 1.0, fadeProgress); + // easedProgress = pow(2.0, 10.0 * (fadeProgress - 1.0)); + float easedProgress = pow(fadeProgress, FADE_EXPONENT); + trail.a *= easedProgress; + } + + float finalAlpha = trail.a * shapeAlpha; + + // newColor.a to preserve the background alpha. + newColor = mix(newColor, vec4(trail.rgb, newColor.a), finalAlpha); + + // punch hole on the trail, so current cursor is drawn on top + newColor = mix(newColor, fragColor, step(sdfCurrentCursor, 0.)); + + } + + fragColor = newColor; +} diff --git a/default/.config/ghostty/ripple_rectangle_cursor.glsl b/default/.config/ghostty/ripple_rectangle_cursor.glsl new file mode 100644 index 0000000..7b1aa34 --- /dev/null +++ b/default/.config/ghostty/ripple_rectangle_cursor.glsl @@ -0,0 +1,138 @@ +// CONFIGURATION +const float DURATION = 0.15; // How long the ripple animates (seconds) +const float MAX_SIZE = 0.05; // Max radius in normalized coords (0.5 = 1/4 screen height) +const float RING_THICKNESS = 0.02; // Ring width in normalized coords +const float CURSOR_WIDTH_CHANGE_THRESHOLD = 0.5; // Triggers ripple if cursor width changes by this fraction +vec4 COLOR = vec4(0.35, 0.36, 0.44, 1.0); // change to iCurrentCursorColor for your cursor's color +const float BLUR = 1.0; // Blur level in pixels +const float ANIMATION_START_OFFSET = 0.0; // Start the ripple slightly progressed (0.0 - 1.0) + + +// Easing functions +float easeOutQuad(float t) { + return 1.0 - (1.0 - t) * (1.0 - t); +} +float easeInOutQuad(float t) { + return t < 0.5 ? 2.0 * t * t : 1.0 - pow(-2.0 * t + 2.0, 2.0) / 2.0; +} +float easeOutCubic(float t) { + return 1.0 - pow(1.0 - t, 3.0); +} +float easeOutQuart(float t) { + return 1.0 - pow(1.0 - t, 4.0); +} +float easeOutQuint(float t) { + return 1.0 - pow(1.0 - t, 5.0); +} +float easeOutExpo(float t) { + return t == 1.0 ? 1.0 : 1.0 - pow(2.0, -10.0 * t); +} +float easeOutCirc(float t) { + return sqrt(1.0 - pow(t - 1.0, 2.0)); +} +float easeOutSine(float t) { + return sin((t * 3.1415916) / 2.0); +} +float easeOutElastic(float t) { + const float c4 = (2.0 * 3.1415916) / 3.0; + return t == 0.0 ? 0.0 : t == 1.0 ? 1.0 : pow(2.0, -10.0 * t) * sin((t * 10.0 - 0.75) * c4) + 1.0; +} +float easeOutBounce(float t) { + const float n1 = 7.5625; + const float d1 = 2.75; + if (t < 1.0 / d1) { + return n1 * t * t; + } else if (t < 2.0 / d1) { + return n1 * (t -= 1.5 / d1) * t + 0.75; + } else if (t < 2.5 / d1) { + return n1 * (t -= 2.25 / d1) * t + 0.9375; + } else { + return n1 * (t -= 2.625 / d1) * t + 0.984375; + } +} +float easeOutBack(float t) { + const float c1 = 1.70158; + const float c3 = c1 + 1.0; + return 1.0 + c3 * pow(t - 1.0, 3.0) + c1 * pow(t - 1.0, 2.0); +} + +// Pulse fade functions +float easeOutPulse(float t) { + return t * (2.0 - t); +} +float exponentialDecayPulse(float t) { + return exp(-3.0 * t) * sin(t * 3.1415916); +} + +vec2 normalize(vec2 value, float isPosition) { + return (value * 2.0 - (iResolution.xy * isPosition)) / iResolution.y; +} + +float getSdfRectangle(in vec2 p, in vec2 xy, in vec2 b){ + vec2 d = abs(p - xy) - b; + return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord){ + #if !defined(WEB) + fragColor = texture(iChannel0, fragCoord.xy / iResolution.xy); + #endif + + // Normalization & setup (-1 to 1 coords) + vec2 vu = normalize(fragCoord, 1.); + vec2 offsetFactor = vec2(-.5, 0.5); + + vec4 currentCursor = vec4(normalize(iCurrentCursor.xy, 1.), normalize(iCurrentCursor.zw, 0.)); + vec4 previousCursor = vec4(normalize(iPreviousCursor.xy, 1.), normalize(iPreviousCursor.zw, 0.)); + + vec2 centerCC = currentCursor.xy - (currentCursor.zw * offsetFactor); + + float cellWidth = max(currentCursor.z, previousCursor.z); // width of the 'block' cursor + + // check for significant width change + float widthChange = abs(currentCursor.z - previousCursor.z); + float widthThresholdNorm = cellWidth * CURSOR_WIDTH_CHANGE_THRESHOLD; + float isModeChange = step(widthThresholdNorm, widthChange); + + + // ANIMATION + float rippleProgress = (iTime - iTimeCursorChange) / DURATION + ANIMATION_START_OFFSET; + // don't clamp yet; we need to know if it's > 1.0 (finished) + float isAnimating = 1.0 - step(1.0, rippleProgress); // progress < 1.0 ? 1.0: 0.0 + + if (isModeChange > 0.0 && isAnimating > 0.0) { + // Apply easing to progress + // float easedProgress = rippleProgress; + // float easedProgress = easeOutQuad(rippleProgress); + // float easedProgress = easeInOutQuad(rippleProgress); + // float easedProgress = easeOutCubic(rippleProgress); + // float easedProgress = easeOutQuart(rippleProgress); + // float easedProgress = easeOutQuint(rippleProgress); + // float easedProgress = easeOutExpo(rippleProgress); + float easedProgress = easeOutCirc(rippleProgress); + // float easedProgress = easeOutSine(rippleProgress); + // float easedProgress = easeOutBack(rippleProgress); + + // RIPPLE CALCULATION + float rippleExpansion = easedProgress * MAX_SIZE; + + // float fade = 1.0; // no fade + // float fade = 1.0 - easedProgress; // linear fade + float fade = 1.0 - easeOutPulse(rippleProgress); + // float fade = 1.0 - exponentialDecayPulse(rippleProgress); + + // Calculate distance from frag to cursor center + // float dist = distance(vu, centerCC); + + // float sdfRing = abs(dist - rippleExpansion) - RING_THICKNESS * 0.5; + vec2 halfSizeCC = vec2(currentCursor.z, currentCursor.w) * 0.5 + vec2(rippleExpansion); + float sdfRectRing = abs(getSdfRectangle(vu, centerCC, halfSizeCC)) - RING_THICKNESS * 0.5; + // Antialias (1-pixel width in normalized coords) + float antiAliasSize = normalize(vec2(BLUR, BLUR), 0.0).x; + float ripple = (1.0 - smoothstep(-antiAliasSize, antiAliasSize, sdfRectRing)) * fade; + + // Apply ripple effect + fragColor = mix(fragColor, COLOR, ripple * COLOR.a); + } + // else: do nothing, keep original fragColor +} diff --git a/default/.config/starship.toml b/default/.config/starship.toml new file mode 100644 index 0000000..6a1d1f6 --- /dev/null +++ b/default/.config/starship.toml @@ -0,0 +1,101 @@ +# Starship prompt configuration - managed by the zshrc repo. +# Local edits to ~/.config/starship.toml are overwritten on the next interactive +# shell start (reproducible/self-configuring design). Uses Nerd Font symbols +# (JetBrainsMono Nerd Font is installed by the tmux config). + +command_timeout = 1000 +add_newline = true + +# Two-line prompt: +# line 1: directory + git status + command duration +# line 2: the input arrow (red on error) +format = """ +$directory\ +$git_branch\ +$git_status\ +$cmd_duration\ +$line_break\ +$character\ +""" + +[character] +success_symbol = "[➜](bold green)" +error_symbol = "[✗](bold red)" +vimcmd_symbol = "[V](bold green)" + +[directory] +truncation_length = 3 +truncate_to_repo = true +style = "bold blue" +read_only = " 󰌾" +read_only_style = "red" +repo_root_style = "bold cyan" + +[git_branch] +symbol = " " +style = "bold purple" +format = "[$symbol$branch]($style) " + +[git_status] +style = "bold red" +conflicted = "=${count}" +ahead = "⇡${count}" +behind = "⇣${count}" +diverged = "⇕↑${ahead_count}↓${behind_count}" +untracked = "?${count}" +stashed = " *${count}" +modified = " !${count}" +staged = " +${count}" +renamed = " »${count}" +deleted = " ✘${count}" +format = '([$all_status$ahead_behind]($style) )' + +[cmd_duration] +min_time = 2000 +format = "took [$duration](bold yellow) " + +[status] +disabled = false +format = '[$symbol]($style)' +symbol = "✗ " +success_symbol = "" +style = "bold red" + +[username] +show_always = false +style_user = "bold yellow" +style_root = "bold red" +format = "[$user]($style)@" + +[hostname] +ssh_only = true +style = "bold green" +format = "[$hostname]($style) " + +[python] +symbol = " " +format = '[${symbol}${pyenv_prefix}(${version})(\($virtualenv\))]($style) ' + +[nodejs] +symbol = " " +format = "[$symbol($version)]($style) " + +[rust] +symbol = " " +format = "[$symbol($version)]($style) " + +[golang] +symbol = " " +format = "[$symbol($version)]($style) " + +[java] +symbol = " " +format = "[$symbol($version)]($style) " + +[docker_context] +symbol = " " +format = "[$symbol$context]($style) " + +[shell] +disabled = true +style = "bold cyan" \ No newline at end of file diff --git a/default/.config/tmux/tmux.conf b/default/.config/tmux/tmux.conf new file mode 100644 index 0000000..1754e07 --- /dev/null +++ b/default/.config/tmux/tmux.conf @@ -0,0 +1,139 @@ +# set prefix key to Ctrl-a +set -g prefix C-a + +# enable mouse mode +set -g mouse on + +# set default terminal to xterm-256color +set -g default-terminal "tmux-256color" + +# bind keys for pane navigation +bind h select-pane -L +bind j select-pane -D +bind k select-pane -U +bind l select-pane -R + +# bind key for closing panes +bind x kill-pane +bind q confirm-before kill-session +# bind key for switching between windows +bind n next-window +bind p previous-window + +# cheatsheet & reload +bind ? display-popup -h 27 -w 46 -E "echo -e '╔══════════════════════════════════════════╗\n║  Tmux Cheatsheet ║\n╠══════════════════════════════════════════╣\n║ Press Ctrl+A (prefix) then: ║\n╠══════════════════════════════════════════╣\n║ PANES ║\n║ h/j/k/l Navigate pane ║\n║ | Split horizontally ║\n║ - Split vertically ║\n║ x Kill pane ║\n║ Ctrl+S Swap pane layout ║\n╠══════════════════════════════════════════╣\n║ WINDOWS ║\n║ n Next window ║\n║ p Previous window ║\n║ q Kill session ║\n║ c New window ║\n║ , Rename window ║\n╠══════════════════════════════════════════╣\n║ GENERAL ║\n║ r Reload config ║\n║ ? This cheatsheet ║\n╚══════════════════════════════════════════╝\nPress any key to close.' && read -n 1 -s" +bind r source-file ~/.config/tmux/tmux.conf + +# disable terminal flow control (so C-s doesn't freeze) +# set -g flow-control off # option not available in this tmux build + +# bind key for toggling between horizontal and vertical split +bind C-s swap-pane -s .-1 + +# split panes using | and - +bind | split-window -h +bind - split-window -v +unbind '"' +unbind % + +set -g @plugin 'tmux-plugins/tpm' +set -g @plugin 'tmux-plugins/tmux-online-status' +set -g @plugin 'tmux-plugins/tmux-battery' +set -g @plugin 'tmux-plugins/tmux-cpu' +# GitHub Dark color palette +set -g @thm_bg "#0d1117" +set -g @thm_surface_0 "#161b22" +set -g @thm_overlay_0 "#30363d" +set -g @thm_red "#f85149" +set -g @thm_green "#3fb950" +set -g @thm_yellow "#d29922" +set -g @thm_blue "#58a6ff" +set -g @thm_mauve "#bc8cff" +set -g @thm_pink "#f778ba" +set -g @thm_peach "#f0883e" +set -g @thm_maroon "#ff7b72" +set -g @thm_rosewater "#c9d1d9" + +# Configure Online +set -g @online_icon "ok" +set -g @offline_icon "nok" + +# status left look and feel +set -g status-left-length 100 +set -g status-left "" +set -ga status-left "#{?client_prefix,#{#[bg=#{@thm_red},fg=#{@thm_bg},bold]  #S },#{#[bg=#{@thm_bg},fg=#{@thm_green}]  #S }}" +set -ga status-left "#[bg=#{@thm_bg},fg=#{@thm_overlay_0},none]│" +set -ga status-left "#[bg=#{@thm_bg},fg=#{@thm_maroon}]  #{pane_current_command} " +set -ga status-left "#[bg=#{@thm_bg},fg=#{@thm_overlay_0},none]│" +set -ga status-left "#[bg=#{@thm_bg},fg=#{@thm_blue}]  #{=/-32/...:#{s|$USER|~|:#{b:pane_current_path}}} " +set -ga status-left "#[bg=#{@thm_bg},fg=#{@thm_overlay_0},none]#{?window_zoomed_flag,│,}" +set -ga status-left "#[bg=#{@thm_bg},fg=#{@thm_yellow}]#{?window_zoomed_flag,  zoom ,}" + +# status right look and feel +set -g status-right-length 100 +set -g status-right "" +set -ga status-right "#{?#{e|>=:10,#{battery_percentage}},#{#[bg=#{@thm_red},fg=#{@thm_bg}]},#{#[bg=#{@thm_bg},fg=#{@thm_pink}]}} #{battery_icon} #{battery_percentage} " +set -ga status-right "#[bg=#{@thm_bg},fg=#{@thm_overlay_0}, none]│" +set -ga status-right "#[bg=#{@thm_bg}]#{?#{==:#{online_status},ok},#[fg=#{@thm_mauve}] 󰖩 on ,#[fg=#{@thm_red},bold]#[reverse] 󰖪 off }" +set -ga status-right "#[bg=#{@thm_bg},fg=#{@thm_overlay_0}, none]│" +set -ga status-right "#[bg=#{@thm_bg},fg=#{@thm_blue}] 󰭦 %a, %m-%d-%Y 󰅐 %I:%M %p " + +# start indexing at 1 (not 0) +set -g base-index 1 +setw -g pane-base-index 1 + +# misc quality-of-life +set -sg escape-time 0 +set -g status-interval 5 +set -g renumber-windows on +set -g focus-events on +setw -g aggressive-resize on +set -g set-clipboard on + +# bootstrap tpm +if "test ! -d ~/.config/tmux/plugins/tpm" \ + "run 'git clone https://github.com/tmux-plugins/tpm ~/.config/tmux/plugins/tpm && ~/.config/tmux/plugins/tpm/bin/install_plugins'" + +# auto-install a Nerd Font if missing (for icons) +run 'if ! fc-list :lang=en 2>/dev/null | grep -qi "nerd\\|jetbrainsmono\\|firacode\\|hack\\|iosevka\\|meslo"; then + mkdir -p ~/.local/share/fonts + if command -v curl >/dev/null 2>&1; then + curl -sL "https://github.com/ryanoasis/nerd-fonts/releases/download/v3.3.0/JetBrainsMono.zip" -o /tmp/jetbrains-nerd.zip + elif command -v wget >/dev/null 2>&1; then + wget -q "https://github.com/ryanoasis/nerd-fonts/releases/download/v3.3.0/JetBrainsMono.zip" -O /tmp/jetbrains-nerd.zip + fi + if [ -f /tmp/jetbrains-nerd.zip ]; then + unzip -qo /tmp/jetbrains-nerd.zip -d ~/.local/share/fonts/ 2>/dev/null + rm -f /tmp/jetbrains-nerd.zip + fc-cache -f ~/.local/share/fonts/ 2>/dev/null + fi +fi' + +# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) +run '~/.config/tmux/plugins/tpm/tpm' + +# Configure Tmux +set -g status-position bottom +set -g status-style "bg=#{@thm_bg}" +set -g status-justify "absolute-centre" + +# pane border look and feel +setw -g pane-border-status bottom +setw -g pane-border-format "" +setw -g pane-active-border-style "bg=#{@thm_bg},fg=#{@thm_overlay_0}" +setw -g pane-border-style "bg=#{@thm_bg},fg=#{@thm_surface_0}" +setw -g pane-border-lines single + +# window look and feel +set -wg automatic-rename on +set -g automatic-rename-format "#{pane_current_command}" + +set -g window-status-format " #I#{?#{!=:#{window_name},Window},: #W,} " +set -g window-status-style "bg=#{@thm_bg},fg=#{@thm_rosewater}" +set -g window-status-last-style "bg=#{@thm_bg},fg=#{@thm_peach}" +set -g window-status-activity-style "bg=#{@thm_red},fg=#{@thm_bg}" +set -g window-status-bell-style "bg=#{@thm_red},fg=#{@thm_bg},bold" +set -gF window-status-separator "#[bg=#{@thm_bg},fg=#{@thm_overlay_0}]│" + +set -g window-status-current-format " #I#{?#{!=:#{window_name},Window},: #W,} " +set -g window-status-current-style "bg=#{@thm_peach},fg=#{@thm_bg},bold" diff --git a/default/.config/zsh/.zlogin b/default/.config/zsh/.zlogin new file mode 100644 index 0000000..fc917d8 --- /dev/null +++ b/default/.config/zsh/.zlogin @@ -0,0 +1,10 @@ +# ~/.zlogin: Executed for LOGIN shells, AFTER .zshrc has loaded. +# Use for final tasks that require the full environment to be ready (e.g., welcome messages, mail checks). +# Rarely needed for standard configuration. + +[[ -f $HOME/.zshrc.local ]] || touch $HOME/.zshrc.local +source $HOME/.zshrc.local + +if [[ $FFENABLED != "false" ]] && command -v fastfetch >/dev/null; then + fastfetch --config examples/13 +fi \ No newline at end of file diff --git a/default/.config/zsh/.zlogout b/default/.config/zsh/.zlogout new file mode 100644 index 0000000..54b0160 --- /dev/null +++ b/default/.config/zsh/.zlogout @@ -0,0 +1,2 @@ +# ~/.zlogout: Executed when a LOGIN shell exits. +# Use for cleanup tasks: resetting terminal titles, stopping agents, or clearing temp files. diff --git a/default/.config/zsh/.zprofile b/default/.config/zsh/.zprofile new file mode 100644 index 0000000..d006b70 --- /dev/null +++ b/default/.config/zsh/.zprofile @@ -0,0 +1,8 @@ +# ~/.zprofile: Executed once for LOGIN shells (initial terminal/SSH). +# Use for one-time setup: PATH modifications, starting agents, or environment exports. +# Runs BEFORE .zshrc. Ideal for variables that shouldn't be re-evaluated in every sub-shell. + +[[ -d "$HOME/Scripts" ]] && path+=("$HOME/Scripts") +[[ -d "$HOME/.local/bin" ]] && path+=("$HOME/.local/bin") +[[ -d "$HOME/AppImages" ]] && path+=("$HOME/AppImages") +[[ -d "$HOME/.opencode/bin" ]] && path+=("$HOME/.opencode/bin") diff --git a/default/.config/zsh/.zsh_plugins.txt b/default/.config/zsh/.zsh_plugins.txt new file mode 100644 index 0000000..86fbf1d --- /dev/null +++ b/default/.config/zsh/.zsh_plugins.txt @@ -0,0 +1,27 @@ + +# frameworks like oh-my-zsh are supported +getantidote/use-omz # handle OMZ dependencies +ohmyzsh/ohmyzsh path:lib # load OMZ's library + +using:ohmyzsh/ohmyzsh path:plugins +git +sudo +extract +eza +history +kitty +docker +docker-compose +archlinux +encode64 +universalarchive +fzf +systemd +vscode +rsync + +# popular fish-like plugins +zsh-users/zsh-autosuggestions +zdharma-continuum/fast-syntax-highlighting kind:defer +zsh-users/zsh-history-substring-search +Aloxaf/fzf-tab diff --git a/default/.config/zsh/.zshenv b/default/.config/zsh/.zshenv new file mode 100644 index 0000000..e69de29 diff --git a/default/.config/zsh/.zshrc b/default/.config/zsh/.zshrc new file mode 100644 index 0000000..407ee13 --- /dev/null +++ b/default/.config/zsh/.zshrc @@ -0,0 +1,9 @@ +# ~/.zshrc: Executed for EVERY INTERACTIVE shell (terminal tabs/windows). +# Use for aliases, functions, prompt themes, key bindings, and shell options (setopt). +# This is where 90% of your customization belongs. + +source ${ZDOTDIR}/init.zsh +source ${ZDOTDIR}/aliases.zsh +source ${ZDOTDIR}/functions.zsh + +eval "$(starship init zsh)" \ No newline at end of file diff --git a/default/.config/zsh/aliases.zsh b/default/.config/zsh/aliases.zsh new file mode 100644 index 0000000..117015e --- /dev/null +++ b/default/.config/zsh/aliases.zsh @@ -0,0 +1,27 @@ +_hl_flag="--hyperlink" +if command -v eza >/dev/null && eza --help 2>&1 | grep -q -- '--hyperlink.*'; then + _hl_flag="--hyperlink=always" +fi +for _ea in la ldot lD lDD ll ls lsd lsdl lS lT; do + (( $+aliases[$_ea] )) && alias "$_ea"="${aliases[$_ea]} $_hl_flag" +done +unset _ea _hl_flag + +# bat: colored `cat` and colored man pages. bat/batcat handled by bootstrap. +if command -v bat >/dev/null; then + alias cat='bat' + export BAT_THEME="${BAT_THEME:-Monokai Extended}" + export MANPAGER="sh -c 'col -bx | bat -l man -p'" + export MANROFFOPT='-c' +fi + +# delta: prettier git diffs as git's pager (git respects GIT_PAGER). Auto-installed +# by the bootstrap. Not aliased to `diff` since delta reads diff input on stdin, +# not two file arguments — GIT_PAGER is the correct integration. +command -v delta >/dev/null && export GIT_PAGER='delta' + +alias c='clear' +alias q="exit" +alias nbstat=$'netbird status --json | jq -r \'.peers.details[]? | [(.hostname // .fqdn), .netbirdIp, .status] | @tsv\' | column -t -s $\'\\t\'' +alias open-ports="ss -tulpn | grep LISTEN" +alias yeet='yay -Rcs' \ No newline at end of file diff --git a/default/.config/zsh/bootstrap.sh b/default/.config/zsh/bootstrap.sh new file mode 100755 index 0000000..1bf76a3 --- /dev/null +++ b/default/.config/zsh/bootstrap.sh @@ -0,0 +1,138 @@ +#!/bin/bash +set -e + +# --- Helpers --- + +info() { printf "\033[1;34m%s\033[0m\n" "$*"; } +warn() { printf "\033[1;33m%s\033[0m\n" "$*"; } +error() { printf "\033[1;31m%s\033[0m\n" "$*"; } + +arch() { + case "$(uname -m)" in + x86_64) echo "x86_64" ;; + aarch64) echo "aarch64" ;; + armv7l) echo "armhf" ;; + *) echo "unknown" ;; + esac +} + +# --- Check existing --- + +check_all() { + local missing=() + for cmd in git curl jq fzf starship eza bat delta fastfetch dotstate; do + command -v "$cmd" &>/dev/null || missing+=("$cmd") + done + if [[ ${#missing[@]} -eq 0 ]]; then + info "all tools present" >&2 + exit 0 + fi + echo "${missing[@]}" +} + +MISSING=($(check_all)) +[[ ${#MISSING[@]} -eq 0 ]] && exit 0 + +# --- Detect package manager --- + +install_pkgs() { + if command -v pacman &>/dev/null; then + sudo pacman -S --noconfirm "$@" + elif command -v dnf &>/dev/null; then + sudo dnf install -y "$@" + elif command -v apt &>/dev/null; then + sudo apt update -qq && sudo apt install -y "$@" + elif command -v zypper &>/dev/null; then + sudo zypper install -y "$@" + elif command -v apk &>/dev/null; then + sudo apk add "$@" + else + return 1 + fi +} + +# --- Install from system repos --- + +SYS_pkgs=() +BIN_pkgs=() + +# Map tool names to distro package names where they differ +declare -A PKG_NAMES=( + [git]="git" + [curl]="curl" + [jq]="jq" + [fzf]="fzf" + [eza]="eza" + [bat]="bat" + [delta]="git-delta" + [fastfetch]="fastfetch" +) + +# starship and dotstate have no distro package, always binary +for tool in "${MISSING[@]}"; do + if [[ "$tool" == "starship" || "$tool" == "dotstate" ]]; then + BIN_pkgs+=("$tool") + continue + fi + pkg="${PKG_NAMES[$tool]:-$tool}" + SYS_pkgs+=("$pkg") +done + +if [[ ${#SYS_pkgs[@]} -gt 0 ]]; then + info "installing from system repos: ${SYS_pkgs[*]}" + install_pkgs "${SYS_pkgs[@]}" || { + warn "system install failed, falling back to binaries" + BIN_pkgs+=("${SYS_pkgs[@]}") + } +fi + +# --- Install pre-built binaries --- + +install_binary() { + local name="$1" + local arch + arch=$(arch) + + case "$name" in + starship) + info "installing starship" + curl -sS https://starship.rs/install.sh | sh -s -- -y + ;; + eza) + info "installing eza" + local url="https://github.com/eza-community/eza/releases/latest/download/eza-${arch}-unknown-linux-musl.tar.gz" + curl -sSfL "$url" | sudo tar xz -C /usr/local/bin + ;; + bat) + info "installing bat" + local url="https://github.com/sharkdp/bat/releases/latest/download/bat-${arch}-unknown-linux-musl.tar.gz" + curl -sSfL "$url" | sudo tar xz --strip-components=1 -C /usr/local/bin "bat-${arch}-unknown-linux-musl/bat" + ;; + delta) + info "installing delta" + local url="https://github.com/dandavison/delta/releases/latest/download/delta-${arch}-unknown-linux-musl.tar.gz" + curl -sSfL "$url" | sudo tar xz --strip-components=1 -C /usr/local/bin "delta-${arch}-unknown-linux-musl/delta" + ;; + fastfetch) + info "installing fastfetch" + local url="https://github.com/fastfetch-cli/fastfetch/releases/latest/download/fastfetch-linux-${arch}.tar.gz" + curl -sSfL "$url" | sudo tar xz --strip-components=2 -C /usr/local/bin + ;; + jq) + info "installing jq" + local url="https://github.com/jqlang/jq/releases/latest/download/jq-linux-${arch}" + curl -sSfL "$url" -o /usr/local/bin/jq + sudo chmod +x /usr/local/bin/jq + ;; + dotstate) + info "installing dotstate" + curl -fsSL https://dotstate.serkan.dev/install.sh | bash + ;; + esac +} + +for tool in "${BIN_pkgs[@]}"; do + install_binary "$tool" +done + +info "done" diff --git a/default/.config/zsh/functions.zsh b/default/.config/zsh/functions.zsh new file mode 100644 index 0000000..4a0a6ec --- /dev/null +++ b/default/.config/zsh/functions.zsh @@ -0,0 +1,7 @@ +fix_btopbg(){ + sed -i 's/theme_background = true/theme_background = false/' ~/.config/btop/btop.conf +} + +install_opencode(){ + curl -fsSL https://opencode.ai/install | bash +} diff --git a/default/.config/zsh/init.zsh b/default/.config/zsh/init.zsh new file mode 100644 index 0000000..242e7c2 --- /dev/null +++ b/default/.config/zsh/init.zsh @@ -0,0 +1,54 @@ +# first, run this from an interactive zsh terminal session: +if [[ -e "${ZDOTDIR}/.antidote" && ! -d "${ZDOTDIR}/.antidote" ]]; then + mkdir -p "${ZDOTDIR}/.antidote" && chmod 700 "${ZDOTDIR}/.antidote" + git clone --depth=1 https://github.com/mattmc3/antidote.git ${ZDOTDIR}/.antidote +fi + +zsh_plugins=${ZDOTDIR}/.zsh_plugins +[[ -f ${zsh_plugins}.txt ]] || touch ${zsh_plugins}.txt + +# source antidote +source ${ZDOTDIR}/.antidote/antidote.zsh + +# Eza plugin options +zstyle ':omz:plugins:eza' dirs-first yes +zstyle ':omz:plugins:eza' git-status yes +zstyle ':omz:plugins:eza' header yes +zstyle ':omz:plugins:eza' show-group yes +zstyle ':omz:plugins:eza' icons yes +zstyle ':omz:plugins:eza' color-scale all +zstyle ':omz:plugins:eza' color-scale-mode fixed +zstyle ':omz:plugins:eza' size-prefix si +# Note: 'hyperlink' is omitted as per your comment + +# Completion settings +zstyle ':completion:*' menu select +zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}' +zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" +zstyle ':completion:*' special-dirs true + + +export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}" +# Ensure directories exist +mkdir -p "$XDG_CACHE_HOME/zsh" + +export HISTFILE="$XDG_CACHE_HOME/zsh/history" +export ZSH_COMPDUMP="$XDG_CACHE_HOME/zsh/zcompdump-${HOST}-${ZSH_VERSION}" +export HISTSIZE=10000 +export SAVEHIST=10000 + +setopt SHARE_HISTORY +setopt HIST_IGNORE_ALL_DUPS +setopt HIST_REDUCE_BLANKS +setopt HIST_FCNTL_LOCK +setopt AUTO_CD +setopt AUTO_LIST +setopt INTERACTIVE_COMMENTS +setopt HIST_VERIFY +setopt EXTENDED_HISTORY +setopt AUTO_PUSHD +setopt PUSHD_IGNORE_DUPS +setopt PUSHD_SILENT + +# initialize plugins statically with ${ZDOTDIR:-$HOME}/.zsh_plugins.txt +antidote load diff --git a/default/.zshenv b/default/.zshenv new file mode 100644 index 0000000..222fd46 --- /dev/null +++ b/default/.zshenv @@ -0,0 +1,12 @@ +# ~/.zshenv: Executed for EVERY shell instance (interactive, scripts, cron). +# Use ONLY for critical environment variables needed by child processes. +# WARNING: Keep this file minimal and fast. Do NOT put aliases or heavy logic here. + +# Interactive +# /etc/zshenv → ~/.zshenv → /etc/zprofile → ~/.zprofile → /etc/zshrc → ~/.zshrc → /etc/zlogin → ~/.zlogin + +# Non Interactive +# /etc/zshenv → ~/.zshenv +export ZDOTDIR="$HOME/.config/zsh" + +source "$ZDOTDIR/.zshenv" \ No newline at end of file