mirror of
https://github.com/mr0xb/dotfiles_chezmoi.git
synced 2026-08-27 19:34:57 -04:00
initial commit
This commit is contained in:
commit
f1374f54c4
46 changed files with 4121 additions and 0 deletions
37
dot_config/ghostty/config.ghostty
Normal file
37
dot_config/ghostty/config.ghostty
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
custom-shader = ./shaders/starfield-colors.glsl
|
||||
#custom-shader = ./shaders/bloom.glsl
|
||||
#custom-shader = ./shaders/custom/bling99_compat.glsl
|
||||
#custom-shader = ./shaders/iamond_teeth_cursor.glsl
|
||||
#custom-shader = ./shaders/custom/cash_money_badge.glsl
|
||||
|
||||
background-blur-radius = 15
|
||||
background-opacity = 0.9
|
||||
#theme = dark:cyberdream, light:cyberdream-light
|
||||
#theme = challengerdeep
|
||||
#theme = "Challenger Deep"
|
||||
|
||||
#window-theme = system
|
||||
|
||||
shell-integration = zsh
|
||||
shell-integration-features = ssh-env,ssh-terminfo
|
||||
|
||||
#font-family = "MesloLGS Nerd Font Mono"
|
||||
font-family = "IBM Plex Mono"
|
||||
font-size = 12
|
||||
|
||||
window-padding-x = 2
|
||||
window-padding-y = 2
|
||||
window-decoration = true
|
||||
cursor-style = block
|
||||
adjust-cell-height = 35%
|
||||
mouse-scroll-multiplier = 2
|
||||
copy-on-select = clipboard
|
||||
window-padding-balance = true
|
||||
window-save-state = always
|
||||
background-opacity = 0.8
|
||||
window-colorspace = "display-p3"
|
||||
background-blur = 30
|
||||
|
||||
macos-option-as-alt = true
|
||||
macos-titlebar-style = transparent
|
||||
macos-titlebar-proxy-icon = hidden
|
||||
96
dot_config/ghostty/shaders/bling99_gold.glsl
Normal file
96
dot_config/ghostty/shaders/bling99_gold.glsl
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
#define PI 3.141592653589793
|
||||
|
||||
float hash12(vec2 p) {
|
||||
vec3 p3 = fract(vec3(p.xyx) * 0.1031);
|
||||
p3 += dot(p3, p3.yzx + 33.33);
|
||||
return fract((p3.x + p3.y) * p3.z);
|
||||
}
|
||||
|
||||
float diamondSparkle(vec2 uv, float density, float threshold, float speed) {
|
||||
vec2 g = uv * vec2(density, density * 0.55);
|
||||
vec2 id = floor(g);
|
||||
vec2 f = fract(g) - 0.5;
|
||||
|
||||
float n = hash12(id);
|
||||
float gate = step(threshold, n);
|
||||
float twinkle = pow(max(0.0, sin(iTime * speed + n * 6.2831853)), 36.0);
|
||||
|
||||
float diaD = abs(f.x) + abs(f.y);
|
||||
float diamond = 1.0 - smoothstep(0.00, 0.10, diaD);
|
||||
|
||||
float vertical = (1.0 - smoothstep(0.00, 0.012, abs(f.x))) *
|
||||
(1.0 - smoothstep(0.00, 0.38, abs(f.y)));
|
||||
float horizontal = (1.0 - smoothstep(0.00, 0.012, abs(f.y))) *
|
||||
(1.0 - smoothstep(0.00, 0.38, abs(f.x)));
|
||||
|
||||
return gate * twinkle * (diamond + 0.40 * (vertical + horizontal));
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
vec2 px = 1.0 / iResolution.xy;
|
||||
|
||||
// Tiny VHS-ish horizontal wobble.
|
||||
float wobble = sin(uv.y * 82.0 + iTime * 2.1) * 0.0008
|
||||
+ sin(uv.y * 11.0 - iTime * 0.35) * 0.0012;
|
||||
|
||||
vec2 uvR = clamp(uv + vec2(wobble + px.x * 1.25, 0.0), vec2(0.001), vec2(0.999));
|
||||
vec2 uvG = clamp(uv + vec2(wobble, 0.0), vec2(0.001), vec2(0.999));
|
||||
vec2 uvB = clamp(uv + vec2(wobble - px.x * 1.25, 0.0), vec2(0.001), vec2(0.999));
|
||||
|
||||
vec4 base = texture(iChannel0, uvG);
|
||||
vec3 src = vec3(
|
||||
texture(iChannel0, uvR).r,
|
||||
base.g,
|
||||
texture(iChannel0, uvB).b
|
||||
);
|
||||
|
||||
float lum = dot(src, vec3(0.299, 0.587, 0.114));
|
||||
float ink = smoothstep(0.03, 0.22, lum);
|
||||
float text = smoothstep(0.20, 0.78, lum);
|
||||
|
||||
// Cash-money palette: velvet black, dark leather brown, hot gold, pale diamond gold.
|
||||
vec3 velvet = vec3(0.014, 0.008, 0.003);
|
||||
vec3 brown = vec3(0.085, 0.044, 0.012);
|
||||
vec3 gold = vec3(1.00, 0.66, 0.13);
|
||||
vec3 paleGold = vec3(1.00, 0.90, 0.55);
|
||||
|
||||
vec3 bg = mix(
|
||||
velvet,
|
||||
brown,
|
||||
uv.y + 0.20 * sin(uv.x * 3.0 + iTime * 0.10)
|
||||
);
|
||||
|
||||
vec3 goldText = mix(gold * 0.75, paleGold, pow(lum, 0.75));
|
||||
vec3 col = mix(bg, mix(src, goldText + src * 0.50, 0.48), ink);
|
||||
|
||||
// Jewelry-store light sweep / chrome-grille reflection.
|
||||
float sweepA = pow(max(0.0, sin((uv.x * 1.8 + uv.y * 0.75) * PI * 2.0 - iTime * 0.60)), 22.0);
|
||||
float sweepB = pow(max(0.0, sin((uv.x * -1.1 + uv.y * 1.25) * PI * 2.0 + iTime * 0.42)), 30.0);
|
||||
col += (sweepA * 0.16 + sweepB * 0.11) * vec3(1.0, 0.83, 0.42) * (0.35 + text);
|
||||
|
||||
// Thin old-video scan shimmer, subtle enough to keep text readable.
|
||||
float scan = 0.965 + 0.035 * sin(fragCoord.y * PI);
|
||||
float vhs = 0.98 + 0.02 * hash12(vec2(floor(uv.y * 360.0), floor(iTime * 24.0)));
|
||||
col *= scan * vhs;
|
||||
|
||||
// Random diamond/star hits.
|
||||
float spark = diamondSparkle(uv, 74.0, 0.978, 4.5);
|
||||
spark += 0.55 * diamondSparkle(uv + vec2(0.17, -0.11), 43.0, 0.970, 3.2);
|
||||
col += spark * vec3(1.0, 0.88, 0.48) * (0.85 + 0.65 * text);
|
||||
|
||||
// Camera-flash blobs in the corners.
|
||||
vec2 aspect = vec2(iResolution.x / iResolution.y, 1.0);
|
||||
float flashL = 1.0 - smoothstep(0.00, 0.28, length((uv - vec2(0.14, 0.82)) * aspect));
|
||||
float flashR = 1.0 - smoothstep(0.00, 0.34, length((uv - vec2(0.88, 0.18)) * aspect));
|
||||
col += (flashL * 0.10 + flashR * 0.07) * vec3(1.0, 0.72, 0.22);
|
||||
|
||||
// Music-video edge falloff.
|
||||
float vig = 1.0 - smoothstep(0.20, 0.82, distance(uv, vec2(0.5)));
|
||||
col *= 0.80 + 0.20 * vig;
|
||||
|
||||
// Legibility save: blend some original terminal text back in.
|
||||
col = mix(col, src, 0.18 * text);
|
||||
|
||||
fragColor = vec4(clamp(col, 0.0, 1.0), base.a);
|
||||
}
|
||||
52
dot_config/ghostty/shaders/bloom.glsl
Normal file
52
dot_config/ghostty/shaders/bloom.glsl
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// source: https://gist.github.com/qwerasd205/c3da6c610c8ffe17d6d2d3cc7068f17f
|
||||
// credits: https://github.com/qwerasd205
|
||||
// Golden spiral samples, [x, y, weight] weight is inverse of distance.
|
||||
const vec3[24] samples = {
|
||||
vec3(0.1693761725038636, 0.9855514761735895, 1),
|
||||
vec3(-1.333070830962943, 0.4721463328627773, 0.7071067811865475),
|
||||
vec3(-0.8464394909806497, -1.51113870578065, 0.5773502691896258),
|
||||
vec3(1.554155680728463, -1.2588090085709776, 0.5),
|
||||
vec3(1.681364377589461, 1.4741145918052656, 0.4472135954999579),
|
||||
vec3(-1.2795157692199817, 2.088741103228784, 0.4082482904638631),
|
||||
vec3(-2.4575847530631187, -0.9799373355024756, 0.3779644730092272),
|
||||
vec3(0.5874641440200847, -2.7667464429345077, 0.35355339059327373),
|
||||
vec3(2.997715703369726, 0.11704939884745152, 0.3333333333333333),
|
||||
vec3(0.41360842451688395, 3.1351121305574803, 0.31622776601683794),
|
||||
vec3(-3.167149933769243, 0.9844599011770256, 0.30151134457776363),
|
||||
vec3(-1.5736713846521535, -3.0860263079123245, 0.2886751345948129),
|
||||
vec3(2.888202648340422, -2.1583061557896213, 0.2773500981126146),
|
||||
vec3(2.7150778983300325, 2.5745586041105715, 0.2672612419124244),
|
||||
vec3(-2.1504069972377464, 3.2211410627650165, 0.2581988897471611),
|
||||
vec3(-3.6548858794907493, -1.6253643308191343, 0.25),
|
||||
vec3(1.0130775986052671, -3.9967078676335834, 0.24253562503633297),
|
||||
vec3(4.229723673607257, 0.33081361055181563, 0.23570226039551587),
|
||||
vec3(0.40107790291173834, 4.340407413572593, 0.22941573387056174),
|
||||
vec3(-4.319124570236028, 1.159811599693438, 0.22360679774997896),
|
||||
vec3(-1.9209044802827355, -4.160543952132907, 0.2182178902359924),
|
||||
vec3(3.8639122286635708, -2.6589814382925123, 0.21320071635561041),
|
||||
vec3(3.3486228404946234, 3.4331800232609, 0.20851441405707477),
|
||||
vec3(-2.8769733643574344, 3.9652268864187157, 0.20412414523193154)
|
||||
};
|
||||
|
||||
float lum(vec4 c) {
|
||||
return 0.299 * c.r + 0.587 * c.g + 0.114 * c.b;
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
|
||||
vec4 color = texture(iChannel0, uv);
|
||||
|
||||
vec2 step = vec2(1.414) / iResolution.xy;
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
vec3 s = samples[i];
|
||||
vec4 c = texture(iChannel0, uv + s.xy * step);
|
||||
float l = lum(c);
|
||||
if (l > 0.2) {
|
||||
color += l * s.z * c * 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
fragColor = color;
|
||||
}
|
||||
43
dot_config/ghostty/shaders/cash_money_frame.glsl
Normal file
43
dot_config/ghostty/shaders/cash_money_frame.glsl
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#define PI 3.141592653589793
|
||||
|
||||
float diamondAt(vec2 uv, vec2 c, float r) {
|
||||
vec2 q = (uv - c) * vec2(iResolution.x / iResolution.y, 1.0);
|
||||
return 1.0 - smoothstep(r * 0.20, r, abs(q.x) + abs(q.y));
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
vec4 base = texture(iChannel0, uv);
|
||||
vec3 col = base.rgb;
|
||||
|
||||
float edgeD = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));
|
||||
float frame = 1.0 - smoothstep(0.0, 0.055, edgeD);
|
||||
|
||||
float chrome = pow(
|
||||
0.5 + 0.5 * sin((uv.x * 5.0 + uv.y * 3.0) * PI * 2.0 - iTime * 2.0),
|
||||
3.0
|
||||
);
|
||||
|
||||
float bead = pow(
|
||||
0.5 + 0.5 * sin((uv.x + uv.y) * 120.0 + iTime * 1.7),
|
||||
14.0
|
||||
);
|
||||
|
||||
vec3 darkGold = vec3(0.23, 0.11, 0.02);
|
||||
vec3 hotGold = vec3(1.00, 0.82, 0.30);
|
||||
vec3 frameColor = mix(darkGold, hotGold, chrome);
|
||||
|
||||
col = mix(col, col + frameColor * (0.20 + 0.35 * bead), frame * 0.55);
|
||||
|
||||
// Big fake diamonds in the corners.
|
||||
float corners = 0.0;
|
||||
corners += diamondAt(uv, vec2(0.035, 0.045), 0.040);
|
||||
corners += diamondAt(uv, vec2(0.965, 0.045), 0.040);
|
||||
corners += diamondAt(uv, vec2(0.035, 0.955), 0.040);
|
||||
corners += diamondAt(uv, vec2(0.965, 0.955), 0.040);
|
||||
|
||||
float twinkle = 0.75 + 0.25 * sin(iTime * 5.0);
|
||||
col += corners * vec3(1.0, 0.90, 0.55) * twinkle * 0.80;
|
||||
|
||||
fragColor = vec4(clamp(col, 0.0, 1.0), base.a);
|
||||
}
|
||||
114
dot_config/ghostty/shaders/cubes.glsl
Normal file
114
dot_config/ghostty/shaders/cubes.glsl
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
// credits: https://github.com/rymdlego
|
||||
|
||||
const float speed = 0.2;
|
||||
const float cube_size = 1.0;
|
||||
const float cube_brightness = 1.0;
|
||||
const float cube_rotation_speed = 2.8;
|
||||
const float camera_rotation_speed = 0.1;
|
||||
|
||||
|
||||
|
||||
mat3 rotationMatrix(vec3 m,float a) {
|
||||
m = normalize(m);
|
||||
float c = cos(a),s=sin(a);
|
||||
return mat3(c+(1.-c)*m.x*m.x,
|
||||
(1.-c)*m.x*m.y-s*m.z,
|
||||
(1.-c)*m.x*m.z+s*m.y,
|
||||
(1.-c)*m.x*m.y+s*m.z,
|
||||
c+(1.-c)*m.y*m.y,
|
||||
(1.-c)*m.y*m.z-s*m.x,
|
||||
(1.-c)*m.x*m.z-s*m.y,
|
||||
(1.-c)*m.y*m.z+s*m.x,
|
||||
c+(1.-c)*m.z*m.z);
|
||||
}
|
||||
|
||||
float sphere(vec3 pos, float radius)
|
||||
{
|
||||
return length(pos) - radius;
|
||||
}
|
||||
|
||||
float box(vec3 pos, vec3 size)
|
||||
{
|
||||
float t = iTime;
|
||||
pos = pos * 0.9 * rotationMatrix(vec3(sin(t/4.0*speed)*10.,cos(t/4.0*speed)*12.,2.7), t*2.4/4.0*speed*cube_rotation_speed);
|
||||
return length(max(abs(pos) - size, 0.0));
|
||||
}
|
||||
|
||||
|
||||
float distfunc(vec3 pos)
|
||||
{
|
||||
float t = iTime;
|
||||
|
||||
float size = 0.45 + 0.25*abs(16.0*sin(t*speed/4.0));
|
||||
// float size = 2.3 + 1.8*tan((t-5.4)*6.549);
|
||||
size = cube_size * 0.16 * clamp(size, 2.0, 4.0);
|
||||
|
||||
//pos = pos * rotationMatrix(vec3(0.,-3.,0.7), 3.3 * mod(t/30.0, 4.0));
|
||||
vec3 q = mod(pos, 5.0) - 2.5;
|
||||
float obj1 = box(q, vec3(size));
|
||||
return obj1;
|
||||
}
|
||||
|
||||
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||
{
|
||||
float t = iTime;
|
||||
vec2 screenPos = -1.0 + 2.0 * fragCoord.xy / iResolution.xy;
|
||||
screenPos.x *= iResolution.x / iResolution.y;
|
||||
vec3 cameraOrigin = vec3(t*1.0*speed, 0.0, 0.0);
|
||||
// vec3 cameraOrigin = vec3(t*1.8*speed, 3.0+t*0.02*speed, 0.0);
|
||||
vec3 cameraTarget = vec3(t*100., 0.0, 0.0);
|
||||
cameraTarget = vec3(t*20.0,0.0,0.0) * rotationMatrix(vec3(0.0,0.0,1.0), t*speed*camera_rotation_speed);
|
||||
|
||||
vec3 upDirection = vec3(0.5, 1.0, 0.6);
|
||||
|
||||
vec3 cameraDir = normalize(cameraTarget - cameraOrigin);
|
||||
vec3 cameraRight = normalize(cross(upDirection, cameraOrigin));
|
||||
vec3 cameraUp = cross(cameraDir, cameraRight);
|
||||
|
||||
vec3 rayDir = normalize(cameraRight * screenPos.x + cameraUp * screenPos.y + cameraDir);
|
||||
|
||||
const int MAX_ITER = 64;
|
||||
const float MAX_DIST = 48.0;
|
||||
const float EPSILON = 0.001;
|
||||
|
||||
float totalDist = 0.0;
|
||||
vec3 pos = cameraOrigin;
|
||||
float dist = EPSILON;
|
||||
|
||||
for (int i = 0; i < MAX_ITER; i++)
|
||||
{
|
||||
if (dist < EPSILON || totalDist > MAX_DIST)
|
||||
break;
|
||||
dist = distfunc(pos);
|
||||
totalDist += dist;
|
||||
pos += dist*rayDir;
|
||||
}
|
||||
|
||||
vec4 cubes;
|
||||
|
||||
if (dist < EPSILON)
|
||||
{
|
||||
// Lighting Code
|
||||
vec2 eps = vec2(0.0, EPSILON);
|
||||
vec3 normal = normalize(vec3(
|
||||
distfunc(pos + eps.yxx) - distfunc(pos - eps.yxx),
|
||||
distfunc(pos + eps.xyx) - distfunc(pos - eps.xyx),
|
||||
distfunc(pos + eps.xxy) - distfunc(pos - eps.xxy)));
|
||||
float diffuse = max(0., dot(-rayDir, normal));
|
||||
float specular = pow(diffuse, 32.0);
|
||||
vec3 color = vec3(diffuse + specular);
|
||||
vec3 cubeColor = vec3(abs(screenPos),0.5+0.5*sin(t*2.0))*0.8;
|
||||
cubeColor = mix(cubeColor.rgb, vec3(0.0,0.0,0.0), 1.0);
|
||||
color += cubeColor;
|
||||
cubes = vec4(color, 1.0) * vec4(1.0 - (totalDist/MAX_DIST));
|
||||
cubes = vec4(cubes.rgb*0.02*cube_brightness, 0.1);
|
||||
}
|
||||
else {
|
||||
cubes = vec4(0.0);
|
||||
}
|
||||
|
||||
vec2 uv = fragCoord/iResolution.xy;
|
||||
vec4 terminalColor = texture(iChannel0, uv);
|
||||
vec3 blendedColor = terminalColor.rgb + cubes.rgb;
|
||||
fragColor = vec4(blendedColor, terminalColor.a);
|
||||
}
|
||||
221
dot_config/ghostty/shaders/cursor_sweep.glsl
Normal file
221
dot_config/ghostty/shaders/cursor_sweep.glsl
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
// 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; // in seconds
|
||||
const float TRAIL_LENGTH = 0.5;
|
||||
const float BLUR = 2.0; // blur size in pixels (for antialiasing)
|
||||
|
||||
// --- 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 point, in vec2 center, in vec2 halfSize)
|
||||
{
|
||||
vec2 d = abs(point - center) - halfSize;
|
||||
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 getSdfParallelogram(in vec2 p, in vec2 v0, in vec2 v1, in vec2 v2, in vec2 v3) {
|
||||
float s = 1.0;
|
||||
float d = dot(p - v0, p - v0);
|
||||
|
||||
d = seg(p, v0, v3, s, d);
|
||||
d = seg(p, v1, v0, s, d);
|
||||
d = seg(p, v2, v1, s, d);
|
||||
d = seg(p, v3, v2, 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) {
|
||||
return 1. - smoothstep(0., normalize(vec2(BLUR, BLUR), 0.).x, distance);
|
||||
}
|
||||
|
||||
float getTopVertexFlag(vec2 a, vec2 b) {
|
||||
float condition1 = step(b.x, a.x) * step(a.y, b.y); // a.x < b.x && a.y > b.y
|
||||
float condition2 = step(a.x, b.x) * step(b.y, a.y); // a.x > b.x && a.y < b.y
|
||||
|
||||
// if neither condition is met, return 1 (else case)
|
||||
return 1.0 - max(condition1, condition2);
|
||||
}
|
||||
|
||||
vec2 getRectangleCenter(vec4 rectangle) {
|
||||
return vec2(rectangle.x + (rectangle.z / 2.), rectangle.y - (rectangle.w / 2.));
|
||||
}
|
||||
|
||||
|
||||
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 centerCP = previousCursor.xy - (previousCursor.zw * offsetFactor);
|
||||
|
||||
float sdfCurrentCursor = getSdfRectangle(vu, centerCC, currentCursor.zw * 0.5);
|
||||
|
||||
float lineLength = distance(centerCC, centerCP);
|
||||
|
||||
vec4 newColor = vec4(fragColor);
|
||||
|
||||
float minDist = currentCursor.w * 1.5;
|
||||
float progress = clamp((iTime - iTimeCursorChange) / DURATION, 0.0, 1.0);
|
||||
if (lineLength > minDist) {
|
||||
// --- Animation Logic ---
|
||||
float shrinkFactor = ease(progress);
|
||||
|
||||
// detect straight moves
|
||||
vec2 delta = abs(centerCC - centerCP);
|
||||
float threshold = 0.001;
|
||||
float isHorizontal = step(delta.y, threshold);
|
||||
float isVertical = step(delta.x, threshold);
|
||||
float isStraightMove = max(isHorizontal, isVertical);
|
||||
|
||||
// -- Making parallelogram sdf (diagonal moves) ---
|
||||
float topVertexFlag = getTopVertexFlag(currentCursor.xy, previousCursor.xy);
|
||||
float bottomVertexFlag = 1.0 - topVertexFlag;
|
||||
vec2 v0 = vec2(currentCursor.x + currentCursor.z * topVertexFlag, currentCursor.y - currentCursor.w);
|
||||
vec2 v1 = vec2(currentCursor.x + currentCursor.z * bottomVertexFlag, currentCursor.y);
|
||||
vec2 v2_full = vec2(previousCursor.x + currentCursor.z * bottomVertexFlag, previousCursor.y);
|
||||
vec2 v3_full = vec2(previousCursor.x + currentCursor.z * topVertexFlag, previousCursor.y - previousCursor.w);
|
||||
|
||||
vec2 v2_start = mix(v1, v2_full, TRAIL_LENGTH);
|
||||
vec2 v3_start = mix(v0, v3_full, TRAIL_LENGTH);
|
||||
vec2 v2_anim = mix(v2_start, v1, shrinkFactor);
|
||||
vec2 v3_anim = mix(v3_start, v0, shrinkFactor);
|
||||
|
||||
float sdfTrail_diag = getSdfParallelogram(vu, v0, v1, v2_anim, v3_anim);
|
||||
|
||||
// --- Making rectangle sdf (straight moves) ---
|
||||
vec2 min_center = min(centerCP, centerCC);
|
||||
vec2 max_center = max(centerCP, centerCC);
|
||||
|
||||
vec2 bBoxSize_full = (max_center - min_center) + currentCursor.zw;
|
||||
vec2 bBoxCenter_full = (min_center + max_center) * 0.5;
|
||||
|
||||
vec2 bBoxSize_start = mix(currentCursor.zw, bBoxSize_full, TRAIL_LENGTH);
|
||||
vec2 bBoxCenter_start = mix(centerCC, bBoxCenter_full, TRAIL_LENGTH);
|
||||
|
||||
vec2 animSize = mix(bBoxSize_start, currentCursor.zw, shrinkFactor);
|
||||
vec2 animCenter = mix(bBoxCenter_start, centerCC, shrinkFactor);
|
||||
|
||||
float sdfTrail_rect = getSdfRectangle(vu, animCenter, animSize * 0.5);
|
||||
|
||||
// -- Selecting and drawing the trail sdf --
|
||||
float sdfTrail = mix(sdfTrail_diag, sdfTrail_rect, isStraightMove);
|
||||
|
||||
vec4 trail = TRAIL_COLOR;
|
||||
float trailAlpha = antialising(sdfTrail);
|
||||
newColor = mix(newColor, trail, trailAlpha);
|
||||
|
||||
// Punch hole
|
||||
newColor = mix(newColor, fragColor, step(sdfCurrentCursor, 0.));
|
||||
}
|
||||
|
||||
|
||||
fragColor = newColor;
|
||||
}
|
||||
239
dot_config/ghostty/shaders/cursor_tail.glsl
Normal file
239
dot_config/ghostty/shaders/cursor_tail.glsl
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
// 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.09; // in seconds
|
||||
const float MAX_TRAIL_LENGTH = 0.2;
|
||||
const float THRESHOLD_MIN_DISTANCE = 1.5; // min distance to show trail (units of cursor width)
|
||||
const float BLUR = 2.0; // blur size in pixels (for antialiasing)
|
||||
|
||||
// --- 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 getSdfParallelogram(in vec2 p, in vec2 v0, in vec2 v1, in vec2 v2, in vec2 v3) {
|
||||
float s = 1.0;
|
||||
float d = dot(p - v0, p - v0);
|
||||
|
||||
d = seg(p, v0, v3, s, d);
|
||||
d = seg(p, v1, v0, s, d);
|
||||
d = seg(p, v2, v1, s, d);
|
||||
d = seg(p, v3, v2, 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) {
|
||||
return 1. - smoothstep(0., normalize(vec2(BLUR, BLUR), 0.).x, distance);
|
||||
}
|
||||
|
||||
float determineIfTopRightIsLeading(vec2 a, vec2 b) {
|
||||
float condition1 = step(b.x, a.x) * step(a.y, b.y); // a.x < b.x && a.y > b.y
|
||||
float condition2 = step(a.x, b.x) * step(b.y, a.y); // a.x > b.x && a.y < b.y
|
||||
|
||||
// if neither condition is met, return 1 (else case)
|
||||
return 1.0 - max(condition1, condition2);
|
||||
}
|
||||
|
||||
vec2 getRectangleCenter(vec4 rectangle) {
|
||||
return vec2(rectangle.x + (rectangle.z / 2.), rectangle.y - (rectangle.w / 2.));
|
||||
}
|
||||
|
||||
|
||||
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 centerCP = previousCursor.xy - (previousCursor.zw * offsetFactor);
|
||||
|
||||
vec2 delta = centerCP - centerCC;
|
||||
float lineLength = length(delta);
|
||||
|
||||
float sdfCurrentCursor = getSdfRectangle(vu, centerCC, currentCursor.zw * 0.5);
|
||||
|
||||
vec4 newColor = vec4(fragColor);
|
||||
|
||||
float minDist = currentCursor.w * THRESHOLD_MIN_DISTANCE;
|
||||
float progress = clamp((iTime - iTimeCursorChange) / DURATION, 0.0, 1.0);
|
||||
if (lineLength > minDist) {
|
||||
// ANIMATION logic
|
||||
|
||||
float head_eased = 0.0;
|
||||
float tail_eased = 0.0;
|
||||
|
||||
float tail_delay_factor = MAX_TRAIL_LENGTH / lineLength;
|
||||
|
||||
float isLongMove = step(MAX_TRAIL_LENGTH, lineLength);
|
||||
|
||||
float head_eased_short = ease(progress);
|
||||
float tail_eased_short = ease(smoothstep(tail_delay_factor, 1.0, progress));
|
||||
float head_eased_long = 1.0;
|
||||
float tail_eased_long = ease(progress);
|
||||
|
||||
head_eased = mix(head_eased_long, head_eased_short, isLongMove);
|
||||
tail_eased = mix(tail_eased_long, tail_eased_short, isLongMove);
|
||||
|
||||
// detect straight moves
|
||||
vec2 delta_abs = abs(centerCC - centerCP);
|
||||
float threshold = 0.001;
|
||||
float isHorizontal = step(delta_abs.y, threshold);
|
||||
float isVertical = step(delta_abs.x, threshold);
|
||||
float isStraightMove = max(isHorizontal, isVertical);
|
||||
|
||||
// -- Making the parallelogram sdf (diagonal move) --
|
||||
|
||||
// animate the TOP-LEFT corners
|
||||
vec2 head_pos_tl = mix(previousCursor.xy, currentCursor.xy, head_eased);
|
||||
vec2 tail_pos_tl = mix(previousCursor.xy, currentCursor.xy, tail_eased);
|
||||
|
||||
float isTopRightLeading = determineIfTopRightIsLeading(currentCursor.xy, previousCursor.xy);
|
||||
float isBottomLeftLeading = 1.0 - isTopRightLeading;
|
||||
|
||||
// v0, v1 : "front" of the trail (head)
|
||||
vec2 v0 = vec2(head_pos_tl.x + currentCursor.z * isTopRightLeading, head_pos_tl.y - currentCursor.w);
|
||||
vec2 v1 = vec2(head_pos_tl.x + currentCursor.z * isBottomLeftLeading, head_pos_tl.y);
|
||||
|
||||
// v2, v3: "back" of the trail (tail)
|
||||
vec2 v2 = vec2(tail_pos_tl.x + currentCursor.z * isBottomLeftLeading, tail_pos_tl.y);
|
||||
vec2 v3 = vec2(tail_pos_tl.x + currentCursor.z * isTopRightLeading, tail_pos_tl.y - previousCursor.w);
|
||||
|
||||
float sdfTrail_diag = getSdfParallelogram(vu, v0, v1, v2, v3);
|
||||
|
||||
// -- Making the rectangle sdf (straight move) --
|
||||
|
||||
vec2 head_center = mix(centerCP, centerCC, head_eased);
|
||||
vec2 tail_center = mix(centerCP, centerCC, tail_eased);
|
||||
|
||||
vec2 min_center = min(head_center, tail_center);
|
||||
vec2 max_center = max(head_center, tail_center);
|
||||
|
||||
vec2 box_size = (max_center - min_center) + currentCursor.zw;
|
||||
vec2 box_center = (min_center + max_center) * 0.5;
|
||||
|
||||
float sdfTrail_rect = getSdfRectangle(vu, box_center, box_size * 0.5);
|
||||
|
||||
// -- FINAL SELECTING AND DRAWING --
|
||||
float sdfTrail = mix(sdfTrail_diag, sdfTrail_rect, isStraightMove);
|
||||
|
||||
vec4 trail = TRAIL_COLOR;
|
||||
float trailAlpha = antialising(sdfTrail);
|
||||
newColor = mix(newColor, trail, trailAlpha);
|
||||
|
||||
// punch hole
|
||||
newColor = mix(newColor, fragColor, step(sdfCurrentCursor, 0.));
|
||||
}
|
||||
|
||||
fragColor = newColor;
|
||||
}
|
||||
308
dot_config/ghostty/shaders/cursor_warp.glsl
Normal file
308
dot_config/ghostty/shaders/cursor_warp.glsl
Normal file
|
|
@ -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;
|
||||
}
|
||||
170
dot_config/ghostty/shaders/custom/bling99_compat.glsl
Normal file
170
dot_config/ghostty/shaders/custom/bling99_compat.glsl
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
#define PI 3.141592653589793
|
||||
|
||||
float spotlightBeam(vec2 uv, vec2 origin, float angle, float width, float lengthFade) {
|
||||
vec2 p = uv - origin;
|
||||
|
||||
float c = cos(angle);
|
||||
float s = sin(angle);
|
||||
|
||||
// Rotate into beam space
|
||||
vec2 q = vec2(
|
||||
c * p.x + s * p.y,
|
||||
-s * p.x + c * p.y
|
||||
);
|
||||
|
||||
// Beam extends along +Y in local space
|
||||
float across = abs(q.x);
|
||||
float along = q.y;
|
||||
|
||||
float beamCore = exp(-pow(across / width, 2.0));
|
||||
float beamLength = smoothstep(-0.05, 0.10, along) * (1.0 - smoothstep(lengthFade, 1.35, along));
|
||||
|
||||
return beamCore * beamLength;
|
||||
}
|
||||
|
||||
float hash12(vec2 p) {
|
||||
vec3 p3 = fract(vec3(p.xyx) * 0.1031);
|
||||
p3 += dot(p3, p3.yzx + 33.33);
|
||||
return fract((p3.x + p3.y) * p3.z);
|
||||
}
|
||||
|
||||
float sparkleGrid(vec2 uv, float scale, float threshold, float speed) {
|
||||
vec2 g = uv * vec2(scale, scale * 0.56);
|
||||
vec2 id = floor(g);
|
||||
vec2 f = fract(g) - 0.5;
|
||||
|
||||
float n = hash12(id);
|
||||
float gate = step(threshold, n);
|
||||
float twinkle = pow(max(0.0, sin(iTime * speed + n * 6.2831853)), 28.0);
|
||||
|
||||
float diamond = 1.0 - smoothstep(0.02, 0.13, abs(f.x) + abs(f.y));
|
||||
|
||||
float flareX = (1.0 - smoothstep(0.000, 0.016, abs(f.y))) *
|
||||
(1.0 - smoothstep(0.000, 0.42, abs(f.x)));
|
||||
float flareY = (1.0 - smoothstep(0.000, 0.016, abs(f.x))) *
|
||||
(1.0 - smoothstep(0.000, 0.42, abs(f.y)));
|
||||
|
||||
return gate * twinkle * (diamond + 0.35 * flareX + 0.35 * flareY);
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
vec2 px = 1.0 / iResolution.xy;
|
||||
|
||||
// Very light late-90s video wobble.
|
||||
float wobble = sin(uv.y * 90.0 + iTime * 2.0) * 0.0008
|
||||
+ sin(uv.y * 12.0 - iTime * 0.35) * 0.0010;
|
||||
|
||||
vec2 tUv = clamp(uv + vec2(wobble, 0.0), vec2(0.001), vec2(0.999));
|
||||
|
||||
// Tiny chromatic shift.
|
||||
vec3 src;
|
||||
src.r = texture(iChannel0, clamp(tUv + vec2(px.x * 1.1, 0.0), vec2(0.001), vec2(0.999))).r;
|
||||
src.g = texture(iChannel0, tUv).g;
|
||||
src.b = texture(iChannel0, clamp(tUv - vec2(px.x * 1.1, 0.0), vec2(0.001), vec2(0.999))).b;
|
||||
|
||||
float lum = dot(src, vec3(0.299, 0.587, 0.114));
|
||||
float glyph = smoothstep(0.06, 0.30, lum);
|
||||
|
||||
// Velvet / leather background.
|
||||
vec3 velvet = vec3(0.012, 0.007, 0.002);
|
||||
vec3 brown = vec3(0.075, 0.038, 0.010);
|
||||
vec3 bg = mix(velvet, brown, uv.y + 0.15 * sin(uv.x * 4.0 + iTime * 0.12));
|
||||
|
||||
// Cash Money gold.
|
||||
vec3 gold = vec3(1.00, 0.62, 0.10);
|
||||
vec3 paleGold = vec3(1.00, 0.88, 0.45);
|
||||
vec3 hotGold = mix(gold, paleGold, pow(lum, 0.65));
|
||||
|
||||
// Tint glyphs gold while preserving some original terminal color.
|
||||
vec3 col = mix(bg, src, glyph * 0.28);
|
||||
col = mix(col, hotGold + src * 0.28, glyph * 0.82);
|
||||
|
||||
// Chrome sweep, like jewelry-store lights / spinning rims.
|
||||
float sweep1 = pow(max(0.0, sin((uv.x * 1.8 + uv.y * 0.65) * PI * 2.0 - iTime * 0.55)), 22.0);
|
||||
float sweep2 = pow(max(0.0, sin((uv.x * -1.1 + uv.y * 1.20) * PI * 2.0 + iTime * 0.40)), 30.0);
|
||||
col += (sweep1 * 0.15 + sweep2 * 0.10) * vec3(1.0, 0.77, 0.32) * (0.35 + glyph);
|
||||
|
||||
// Independent moving spotlight trails
|
||||
float ray1 = spotlightBeam(
|
||||
uv,
|
||||
vec2(0.10, 1.10),
|
||||
-0.95 + 0.22 * sin(iTime * 0.63 + 0.3),
|
||||
0.045 + 0.008 * sin(iTime * 1.10 + 0.7),
|
||||
1.00
|
||||
);
|
||||
|
||||
float ray2 = spotlightBeam(
|
||||
uv,
|
||||
vec2(0.35, 1.12),
|
||||
-1.20 + 0.18 * sin(iTime * 0.47 + 1.7),
|
||||
0.055 + 0.006 * sin(iTime * 0.90 + 2.1),
|
||||
1.05
|
||||
);
|
||||
|
||||
float ray3 = spotlightBeam(
|
||||
uv,
|
||||
vec2(0.72, 1.08),
|
||||
-1.55 + 0.20 * sin(iTime * 0.71 + 2.8),
|
||||
0.050 + 0.010 * sin(iTime * 1.30 + 0.5),
|
||||
0.95
|
||||
);
|
||||
|
||||
float ray4 = spotlightBeam(
|
||||
uv,
|
||||
vec2(0.92, 1.15),
|
||||
-1.85 + 0.24 * sin(iTime * 0.58 + 4.0),
|
||||
0.060 + 0.007 * sin(iTime * 0.80 + 3.4),
|
||||
1.10
|
||||
);
|
||||
|
||||
// Optional faint upward beam from bottom-left for extra motion
|
||||
float ray5 = spotlightBeam(
|
||||
uv,
|
||||
vec2(-0.05, -0.05),
|
||||
0.70 + 0.15 * sin(iTime * 0.52 + 5.2),
|
||||
0.040 + 0.005 * sin(iTime * 1.00 + 1.3),
|
||||
0.90
|
||||
);
|
||||
|
||||
float rays = 0.0;
|
||||
rays += ray1 * (0.75 + 0.25 * sin(iTime * 0.90 + 0.2));
|
||||
rays += ray2 * (0.65 + 0.35 * sin(iTime * 0.70 + 1.9));
|
||||
rays += ray3 * (0.80 + 0.20 * sin(iTime * 1.10 + 2.6));
|
||||
rays += ray4 * (0.70 + 0.30 * sin(iTime * 0.85 + 4.3));
|
||||
rays += ray5 * (0.45 + 0.25 * sin(iTime * 0.95 + 3.1));
|
||||
|
||||
// Warm gold spotlight tint
|
||||
vec3 rayColorA = vec3(1.00, 0.74, 0.22);
|
||||
vec3 rayColorB = vec3(1.00, 0.86, 0.48);
|
||||
|
||||
// Mix two shades so it feels less flat
|
||||
vec3 spotlightColor = mix(rayColorA, rayColorB, 0.5 + 0.5 * sin(iTime * 0.33));
|
||||
|
||||
// Add trails mostly into background, not too hard on text
|
||||
col += rays * spotlightColor * (0.10 + 0.10 * (1.0 - glyph));
|
||||
|
||||
// Diamond glints.
|
||||
float spark = sparkleGrid(uv, 62.0, 0.978, 4.0);
|
||||
spark += 0.50 * sparkleGrid(uv + vec2(0.13, -0.09), 38.0, 0.965, 3.0);
|
||||
col += spark * vec3(1.0, 0.90, 0.55) * (0.8 + 0.5 * glyph);
|
||||
|
||||
// Gold frame around the terminal.
|
||||
float edgeD = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));
|
||||
float frame = 1.0 - smoothstep(0.000, 0.045, edgeD);
|
||||
float frameWave = pow(0.5 + 0.5 * sin((uv.x + uv.y) * 90.0 - iTime * 1.8), 8.0);
|
||||
col += frame * vec3(1.0, 0.72, 0.20) * (0.10 + 0.22 * frameWave);
|
||||
|
||||
// Scanline shimmer, not too heavy.
|
||||
float scan = 0.965 + 0.035 * sin(fragCoord.y * PI);
|
||||
col *= scan;
|
||||
|
||||
// Music-video vignette.
|
||||
float vig = 1.0 - smoothstep(0.22, 0.82, distance(uv, vec2(0.5)));
|
||||
col *= 0.78 + 0.22 * vig;
|
||||
|
||||
// Keep text readable.
|
||||
col = mix(col, src, glyph * 0.16);
|
||||
|
||||
fragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
|
||||
}
|
||||
267
dot_config/ghostty/shaders/custom/cash_money_badge.glsl
Normal file
267
dot_config/ghostty/shaders/custom/cash_money_badge.glsl
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
#define PI 3.141592653589793
|
||||
|
||||
float smin(float a, float b, float k) {
|
||||
float h = max(k - abs(a - b), 0.0) / k;
|
||||
return min(a, b) - h * h * h * k * (1.0 / 6.0);
|
||||
}
|
||||
|
||||
float rectSDF(vec2 p, vec2 b) {
|
||||
vec2 d = abs(p) - b;
|
||||
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
|
||||
}
|
||||
|
||||
float fill(float d, float aa) {
|
||||
return 1.0 - smoothstep(0.0, aa, d);
|
||||
}
|
||||
|
||||
float stroke(float d, float w, float aa) {
|
||||
return 1.0 - smoothstep(0.0, aa, abs(d) - w);
|
||||
}
|
||||
|
||||
float box01(vec2 uv, vec2 c, vec2 s, float aa) {
|
||||
return fill(rectSDF(uv - c, s), aa);
|
||||
}
|
||||
|
||||
float frame01(vec2 uv, vec2 c, vec2 s, float w, float aa) {
|
||||
return stroke(rectSDF(uv - c, s), w, aa);
|
||||
}
|
||||
|
||||
float in01(vec2 uv) {
|
||||
return step(0.0, uv.x) * step(0.0, uv.y) * step(uv.x, 1.0) * step(uv.y, 1.0);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Very simple block-letter glyphs in a 0..1 local cell.
|
||||
// Not perfect typography, but close enough to read.
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
float glyphC(vec2 uv, float aa) {
|
||||
float m = 0.0;
|
||||
m = max(m, box01(uv, vec2(0.22, 0.50), vec2(0.10, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.52, 0.84), vec2(0.30, 0.08), aa));
|
||||
m = max(m, box01(uv, vec2(0.52, 0.16), vec2(0.30, 0.08), aa));
|
||||
return m * in01(uv);
|
||||
}
|
||||
|
||||
float glyphA(vec2 uv, float aa) {
|
||||
float m = 0.0;
|
||||
m = max(m, box01(uv, vec2(0.22, 0.50), vec2(0.10, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.78, 0.50), vec2(0.10, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.84), vec2(0.30, 0.08), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.50), vec2(0.30, 0.08), aa));
|
||||
return m * in01(uv);
|
||||
}
|
||||
|
||||
float glyphS(vec2 uv, float aa) {
|
||||
float m = 0.0;
|
||||
m = max(m, box01(uv, vec2(0.50, 0.84), vec2(0.30, 0.08), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.50), vec2(0.30, 0.08), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.16), vec2(0.30, 0.08), aa));
|
||||
m = max(m, box01(uv, vec2(0.22, 0.67), vec2(0.10, 0.17), aa));
|
||||
m = max(m, box01(uv, vec2(0.78, 0.33), vec2(0.10, 0.17), aa));
|
||||
return m * in01(uv);
|
||||
}
|
||||
|
||||
float glyphH(vec2 uv, float aa) {
|
||||
float m = 0.0;
|
||||
m = max(m, box01(uv, vec2(0.22, 0.50), vec2(0.10, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.78, 0.50), vec2(0.10, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.50), vec2(0.30, 0.08), aa));
|
||||
return m * in01(uv);
|
||||
}
|
||||
|
||||
float glyphM(vec2 uv, float aa) {
|
||||
float m = 0.0;
|
||||
m = max(m, box01(uv, vec2(0.16, 0.50), vec2(0.09, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.84, 0.50), vec2(0.09, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.38, 0.65), vec2(0.08, 0.27), aa));
|
||||
m = max(m, box01(uv, vec2(0.62, 0.65), vec2(0.08, 0.27), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.84), vec2(0.25, 0.08), aa));
|
||||
return m * in01(uv);
|
||||
}
|
||||
|
||||
float glyphO(vec2 uv, float aa) {
|
||||
float outer = box01(uv, vec2(0.50, 0.50), vec2(0.34, 0.42), aa);
|
||||
float inner = box01(uv, vec2(0.50, 0.50), vec2(0.18, 0.24), aa);
|
||||
return max(0.0, outer - inner) * in01(uv);
|
||||
}
|
||||
|
||||
float glyphN(vec2 uv, float aa) {
|
||||
float m = 0.0;
|
||||
m = max(m, box01(uv, vec2(0.20, 0.50), vec2(0.10, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.80, 0.50), vec2(0.10, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.50), vec2(0.08, 0.42), aa));
|
||||
return m * in01(uv);
|
||||
}
|
||||
|
||||
float glyphE(vec2 uv, float aa) {
|
||||
float m = 0.0;
|
||||
m = max(m, box01(uv, vec2(0.22, 0.50), vec2(0.10, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.52, 0.84), vec2(0.30, 0.08), aa));
|
||||
m = max(m, box01(uv, vec2(0.48, 0.50), vec2(0.26, 0.08), aa));
|
||||
m = max(m, box01(uv, vec2(0.52, 0.16), vec2(0.30, 0.08), aa));
|
||||
return m * in01(uv);
|
||||
}
|
||||
|
||||
float glyphY(vec2 uv, float aa) {
|
||||
float m = 0.0;
|
||||
m = max(m, box01(uv, vec2(0.22, 0.72), vec2(0.10, 0.20), aa));
|
||||
m = max(m, box01(uv, vec2(0.78, 0.72), vec2(0.10, 0.20), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.50), vec2(0.10, 0.12), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.20), vec2(0.10, 0.20), aa));
|
||||
return m * in01(uv);
|
||||
}
|
||||
|
||||
float glyphR(vec2 uv, float aa) {
|
||||
float m = 0.0;
|
||||
m = max(m, box01(uv, vec2(0.22, 0.50), vec2(0.10, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.84), vec2(0.28, 0.08), aa));
|
||||
m = max(m, box01(uv, vec2(0.72, 0.68), vec2(0.10, 0.16), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.50), vec2(0.26, 0.08), aa));
|
||||
m = max(m, box01(uv, vec2(0.68, 0.24), vec2(0.10, 0.20), aa));
|
||||
return m * in01(uv);
|
||||
}
|
||||
|
||||
float glyphD(vec2 uv, float aa) {
|
||||
float m = 0.0;
|
||||
m = max(m, box01(uv, vec2(0.22, 0.50), vec2(0.10, 0.42), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.84), vec2(0.26, 0.08), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.16), vec2(0.26, 0.08), aa));
|
||||
m = max(m, box01(uv, vec2(0.74, 0.50), vec2(0.10, 0.34), aa));
|
||||
return m * in01(uv);
|
||||
}
|
||||
|
||||
float drawGlyph(int g, vec2 uv, float aa) {
|
||||
if (g == 0) return glyphC(uv, aa);
|
||||
if (g == 1) return glyphA(uv, aa);
|
||||
if (g == 2) return glyphS(uv, aa);
|
||||
if (g == 3) return glyphH(uv, aa);
|
||||
if (g == 4) return glyphM(uv, aa);
|
||||
if (g == 5) return glyphO(uv, aa);
|
||||
if (g == 6) return glyphN(uv, aa);
|
||||
if (g == 7) return glyphE(uv, aa);
|
||||
if (g == 8) return glyphY(uv, aa);
|
||||
if (g == 9) return glyphR(uv, aa);
|
||||
if (g == 10) return glyphD(uv, aa);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float placeGlyph(vec2 q, vec4 box, int glyphId, float aa) {
|
||||
vec2 uv = (q - box.xy) / (box.zw - box.xy);
|
||||
return drawGlyph(glyphId, uv, aa);
|
||||
}
|
||||
|
||||
float dollarMark(vec2 uv, float aa) {
|
||||
float m = 0.0;
|
||||
|
||||
// vertical bar
|
||||
m = max(m, box01(uv, vec2(0.50, 0.50), vec2(0.05, 0.42), aa));
|
||||
|
||||
// top/bottom heavy bars to make a chunky $
|
||||
m = max(m, box01(uv, vec2(0.50, 0.82), vec2(0.22, 0.10), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.50), vec2(0.22, 0.10), aa));
|
||||
m = max(m, box01(uv, vec2(0.50, 0.18), vec2(0.22, 0.10), aa));
|
||||
|
||||
// left upper / right lower chunks
|
||||
m = max(m, box01(uv, vec2(0.30, 0.66), vec2(0.10, 0.18), aa));
|
||||
m = max(m, box01(uv, vec2(0.70, 0.34), vec2(0.10, 0.18), aa));
|
||||
|
||||
return m * in01(uv);
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
vec4 base = texture(iChannel0, uv);
|
||||
vec3 col = base.rgb;
|
||||
|
||||
float aa = 1.6 / iResolution.y;
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Bouncing rectangular badge, DVD-logo style
|
||||
// ----------------------------------------------------------
|
||||
vec2 badgeSize = vec2(0.18, 0.44);
|
||||
vec2 minP = badgeSize * 0.5 + vec2(0.02, 0.03);
|
||||
vec2 maxP = vec2(1.0) - minP;
|
||||
|
||||
vec2 travel = maxP - minP;
|
||||
vec2 phase = fract(vec2(iTime * 0.060, iTime * 0.047) + vec2(0.21, 0.58));
|
||||
vec2 tri = abs(phase * 2.0 - 1.0);
|
||||
vec2 center = minP + travel * tri;
|
||||
|
||||
vec2 p = uv - center;
|
||||
p.x *= iResolution.x / iResolution.y;
|
||||
|
||||
vec2 halfSize = vec2(badgeSize.x * 0.5 * iResolution.x / iResolution.y, badgeSize.y * 0.5);
|
||||
|
||||
// q = normalized coordinates inside the badge
|
||||
vec2 q = p / halfSize;
|
||||
q = q * 0.5 + 0.5;
|
||||
|
||||
float outer = fill(rectSDF(p, halfSize), aa);
|
||||
float border = frame01(p, vec2(0.0), halfSize, 0.006, aa);
|
||||
|
||||
// shadow
|
||||
float shadow = fill(rectSDF(p - vec2(0.010, -0.012), halfSize), aa) * 0.18;
|
||||
col = mix(col, col * 0.80, shadow);
|
||||
|
||||
// white sticker body
|
||||
vec3 logoCol = vec3(0.0);
|
||||
logoCol += outer * vec3(0.96);
|
||||
logoCol = mix(logoCol, vec3(0.04), border);
|
||||
|
||||
// top word: CASH MONEY
|
||||
float top = 0.0;
|
||||
float y0 = 0.78;
|
||||
float y1 = 0.96;
|
||||
float w = 0.075;
|
||||
float gap = 0.010;
|
||||
|
||||
top = max(top, placeGlyph(q, vec4(0.04, y0, 0.04 + w, y1), 0, aa)); // C
|
||||
top = max(top, placeGlyph(q, vec4(0.04 + 1.0*(w+gap), y0, 0.04 + 1.0*(w+gap) + w, y1), 1, aa)); // A
|
||||
top = max(top, placeGlyph(q, vec4(0.04 + 2.0*(w+gap), y0, 0.04 + 2.0*(w+gap) + w, y1), 2, aa)); // S
|
||||
top = max(top, placeGlyph(q, vec4(0.04 + 3.0*(w+gap), y0, 0.04 + 3.0*(w+gap) + w, y1), 3, aa)); // H
|
||||
|
||||
float start2 = 0.40;
|
||||
top = max(top, placeGlyph(q, vec4(start2 + 0.0*(w+gap), y0, start2 + 0.0*(w+gap) + w, y1), 4, aa)); // M
|
||||
top = max(top, placeGlyph(q, vec4(start2 + 1.0*(w+gap), y0, start2 + 1.0*(w+gap) + w, y1), 5, aa)); // O
|
||||
top = max(top, placeGlyph(q, vec4(start2 + 2.0*(w+gap), y0, start2 + 2.0*(w+gap) + w, y1), 6, aa)); // N
|
||||
top = max(top, placeGlyph(q, vec4(start2 + 3.0*(w+gap), y0, start2 + 3.0*(w+gap) + w, y1), 7, aa)); // E
|
||||
top = max(top, placeGlyph(q, vec4(start2 + 4.0*(w+gap), y0, start2 + 4.0*(w+gap) + w, y1), 8, aa)); // Y
|
||||
|
||||
// bottom word: RECORDS
|
||||
float bottom = 0.0;
|
||||
float by0 = 0.03;
|
||||
float by1 = 0.19;
|
||||
float bw = 0.095;
|
||||
float bg = 0.012;
|
||||
float bstart = 0.10;
|
||||
|
||||
bottom = max(bottom, placeGlyph(q, vec4(bstart + 0.0*(bw+bg), by0, bstart + 0.0*(bw+bg) + bw, by1), 9, aa)); // R
|
||||
bottom = max(bottom, placeGlyph(q, vec4(bstart + 1.0*(bw+bg), by0, bstart + 1.0*(bw+bg) + bw, by1), 7, aa)); // E
|
||||
bottom = max(bottom, placeGlyph(q, vec4(bstart + 2.0*(bw+bg), by0, bstart + 2.0*(bw+bg) + bw, by1), 0, aa)); // C
|
||||
bottom = max(bottom, placeGlyph(q, vec4(bstart + 3.0*(bw+bg), by0, bstart + 3.0*(bw+bg) + bw, by1), 5, aa)); // O
|
||||
bottom = max(bottom, placeGlyph(q, vec4(bstart + 4.0*(bw+bg), by0, bstart + 4.0*(bw+bg) + bw, by1), 9, aa)); // R
|
||||
bottom = max(bottom, placeGlyph(q, vec4(bstart + 5.0*(bw+bg), by0, bstart + 5.0*(bw+bg) + bw, by1), 10, aa)); // D
|
||||
bottom = max(bottom, placeGlyph(q, vec4(bstart + 6.0*(bw+bg), by0, bstart + 6.0*(bw+bg) + bw, by1), 2, aa)); // S
|
||||
|
||||
// central $
|
||||
vec2 suv = (q - vec2(0.18, 0.23)) / vec2(0.64, 0.50);
|
||||
float dollar = dollarMark(suv, aa);
|
||||
|
||||
// black print
|
||||
float printMask = max(max(top, bottom), dollar);
|
||||
logoCol = mix(logoCol, vec3(0.03), printMask);
|
||||
|
||||
// small gold glint so it still fits the bling theme
|
||||
float glint = pow(max(0.0, sin((uv.x * 4.0 + uv.y * 2.0) * PI * 2.0 - iTime * 1.4)), 18.0);
|
||||
logoCol += outer * glint * vec3(1.0, 0.84, 0.35) * 0.12;
|
||||
|
||||
// subtle sticker highlight
|
||||
float shine = 1.0 - smoothstep(0.0, 0.25, abs(q.x - 0.25) + abs(q.y - 0.78));
|
||||
logoCol += outer * shine * vec3(1.0) * 0.08;
|
||||
|
||||
// composite behind text
|
||||
col = mix(col, col + logoCol, outer * 0.22);
|
||||
|
||||
fragColor = vec4(clamp(col, 0.0, 1.0), base.a);
|
||||
}
|
||||
142
dot_config/ghostty/shaders/custom/cash_money_dvd.glsl
Normal file
142
dot_config/ghostty/shaders/custom/cash_money_dvd.glsl
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
#define PI 3.141592653589793
|
||||
|
||||
float sdEllipse(vec2 p, vec2 r) {
|
||||
vec2 q = p / r;
|
||||
return (length(q) - 1.0) * min(r.x, r.y);
|
||||
}
|
||||
|
||||
float sdCircle(vec2 p, float r) {
|
||||
return length(p) - r;
|
||||
}
|
||||
|
||||
float sdBox(vec2 p, vec2 b) {
|
||||
vec2 d = abs(p) - b;
|
||||
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
|
||||
}
|
||||
|
||||
float opStroke(float d, float w) {
|
||||
return abs(d) - w;
|
||||
}
|
||||
|
||||
float fill(float d) {
|
||||
return 1.0 - smoothstep(0.0, 0.004, d);
|
||||
}
|
||||
|
||||
float stroke(float d, float w) {
|
||||
return 1.0 - smoothstep(0.0, 0.004, opStroke(d, w));
|
||||
}
|
||||
|
||||
// Simple dollar sign SDF-ish shape
|
||||
float dollarSign(vec2 p) {
|
||||
float s = 0.0;
|
||||
|
||||
// main vertical bar
|
||||
float bar = fill(sdBox(p, vec2(0.018, 0.18)));
|
||||
|
||||
// upper curve
|
||||
vec2 pu = p - vec2(0.02, 0.07);
|
||||
float upperOuter = stroke(sdCircle(pu, 0.11), 0.020);
|
||||
float upperCut = fill(sdBox(pu - vec2(-0.07, 0.00), vec2(0.08, 0.14)));
|
||||
float upper = upperOuter * (1.0 - upperCut);
|
||||
|
||||
// lower curve
|
||||
vec2 pl = p - vec2(-0.02, -0.07);
|
||||
float lowerOuter = stroke(sdCircle(pl, 0.11), 0.020);
|
||||
float lowerCut = fill(sdBox(pl - vec2(0.07, 0.00), vec2(0.08, 0.14)));
|
||||
float lower = lowerOuter * (1.0 - lowerCut);
|
||||
|
||||
s = max(bar, max(upper, lower));
|
||||
return s;
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
vec4 base = texture(iChannel0, uv);
|
||||
vec3 col = base.rgb;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Bouncing "DVD logo" style motion
|
||||
// ------------------------------------------------------------------
|
||||
vec2 logoSize = vec2(0.23, 0.13); // width/height of medallion in UV space
|
||||
vec2 minP = logoSize * 0.5 + vec2(0.03, 0.04);
|
||||
vec2 maxP = vec2(1.0) - minP;
|
||||
|
||||
// Ping-pong motion
|
||||
vec2 travel = maxP - minP;
|
||||
vec2 phase = fract(vec2(iTime * 0.070, iTime * 0.052) + vec2(0.17, 0.61));
|
||||
vec2 tri = abs(phase * 2.0 - 1.0);
|
||||
vec2 center = minP + travel * tri;
|
||||
|
||||
// Local coordinates around logo center
|
||||
vec2 p = uv - center;
|
||||
p.x *= iResolution.x / iResolution.y; // aspect correction
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Cash Money inspired medallion
|
||||
// ------------------------------------------------------------------
|
||||
float outer = sdEllipse(p, vec2(0.17, 0.095));
|
||||
float inner = sdEllipse(p, vec2(0.145, 0.078));
|
||||
float core = sdEllipse(p, vec2(0.122, 0.060));
|
||||
|
||||
float outerFill = fill(outer);
|
||||
float innerRing = stroke(inner, 0.010);
|
||||
float coreFill = fill(core);
|
||||
|
||||
// Rim beading / jewelry vibe
|
||||
float angle = atan(p.y, p.x);
|
||||
float beads = pow(0.5 + 0.5 * sin(angle * 26.0 - iTime * 2.2), 8.0);
|
||||
beads *= stroke(sdEllipse(p, vec2(0.158, 0.086)), 0.008);
|
||||
|
||||
// Chrome/gold light sweep
|
||||
float sweep = pow(max(0.0, sin((uv.x * 4.0 + uv.y * 2.6) * PI * 2.0 - iTime * 1.7)), 18.0);
|
||||
|
||||
vec3 darkGold = vec3(0.28, 0.12, 0.02);
|
||||
vec3 gold = vec3(0.95, 0.67, 0.16);
|
||||
vec3 paleGold = vec3(1.00, 0.88, 0.52);
|
||||
vec3 diamond = vec3(1.00, 0.96, 0.85);
|
||||
|
||||
vec3 logoCol = vec3(0.0);
|
||||
|
||||
// outer medallion
|
||||
logoCol += outerFill * mix(darkGold, gold, 0.65);
|
||||
logoCol += innerRing * paleGold * 0.9;
|
||||
logoCol += beads * paleGold * 0.8;
|
||||
logoCol += coreFill * mix(gold, paleGold, 0.35);
|
||||
|
||||
// embossed center
|
||||
float emboss = 0.5 + 0.5 * sin(p.x * 28.0 + p.y * 12.0 - iTime * 0.6);
|
||||
logoCol += coreFill * emboss * vec3(0.10, 0.05, 0.01);
|
||||
|
||||
// dollar sign centerpiece
|
||||
float ds = dollarSign(p * 1.7);
|
||||
logoCol = mix(logoCol, diamond, ds * 0.9);
|
||||
logoCol += ds * paleGold * 0.35;
|
||||
|
||||
// little sparkle hits
|
||||
float sparkle1 = exp(-length((p - vec2(-0.07, 0.03)) * vec2(1.0, 1.2)) * 60.0);
|
||||
float sparkle2 = exp(-length((p - vec2(0.08, -0.01)) * vec2(1.0, 1.2)) * 80.0);
|
||||
float cross1 = (1.0 - smoothstep(0.0, 0.004, abs(p.x + 0.07))) * (1.0 - smoothstep(0.0, 0.05, abs(p.y - 0.03)));
|
||||
cross1 += (1.0 - smoothstep(0.0, 0.004, abs(p.y - 0.03))) * (1.0 - smoothstep(0.0, 0.05, abs(p.x + 0.07)));
|
||||
float cross2 = (1.0 - smoothstep(0.0, 0.003, abs(p.x - 0.08))) * (1.0 - smoothstep(0.0, 0.04, abs(p.y + 0.01)));
|
||||
cross2 += (1.0 - smoothstep(0.0, 0.003, abs(p.y + 0.01))) * (1.0 - smoothstep(0.0, 0.04, abs(p.x - 0.08)));
|
||||
|
||||
float twinkle = 0.65 + 0.35 * sin(iTime * 5.0);
|
||||
logoCol += (sparkle1 * cross1 + sparkle2 * cross2) * paleGold * twinkle * 0.9;
|
||||
|
||||
// moving light sweep across logo
|
||||
logoCol += outerFill * sweep * vec3(1.0, 0.92, 0.60) * 0.45;
|
||||
|
||||
// subtle shadow behind logo
|
||||
float shadow = fill(sdEllipse(p - vec2(0.010, -0.010), vec2(0.17, 0.095)));
|
||||
shadow *= 0.18;
|
||||
|
||||
// Logo mask
|
||||
float logoMask = outerFill;
|
||||
|
||||
// Keep it in background so text stays readable
|
||||
// Darken behind medallion slightly, then add logo
|
||||
col = mix(col, col * 0.82, shadow);
|
||||
col = mix(col, col + logoCol, logoMask * 0.32);
|
||||
|
||||
fragColor = vec4(clamp(col, 0.0, 1.0), base.a);
|
||||
}
|
||||
5
dot_config/ghostty/shaders/custom/probe_invert.glsl
Normal file
5
dot_config/ghostty/shaders/custom/probe_invert.glsl
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
vec4 c = texture(iChannel0, uv);
|
||||
fragColor = vec4(1.0 - c.rgb, 1.0);
|
||||
}
|
||||
30
dot_config/ghostty/shaders/dot_claude/settings.local.json
Normal file
30
dot_config/ghostty/shaders/dot_claude/settings.local.json
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(mount)",
|
||||
"Bash(getenforce)",
|
||||
"Bash(podman --version)",
|
||||
"Read(//etc/**)",
|
||||
"Bash(grep \"^$\\(whoami\\):\")",
|
||||
"Bash(mkdir -p \"/run/media/mr0xb/1TB Samsung 860/postgres-data\")",
|
||||
"Bash(mkdir -p ~/podman)",
|
||||
"Bash(podman unshare *)",
|
||||
"Bash(podman secret *)",
|
||||
"Bash(openssl rand *)",
|
||||
"Bash(podman kube *)",
|
||||
"Bash(podman pod *)",
|
||||
"Bash(podman ps *)",
|
||||
"Bash(podman logs *)",
|
||||
"Bash(rm -rf \"/run/media/mr0xb/1TB Samsung 860/postgres-data\")",
|
||||
"Bash(podman exec *)",
|
||||
"Bash(podman inspect *)",
|
||||
"Bash(podman image *)",
|
||||
"Bash(podman run *)",
|
||||
"Bash(chcon -Rt container_file_t \"/run/media/mr0xb/1TB Samsung 860/postgres-data\")",
|
||||
"Bash(PGPASSWORD='ksJZqsVlMZZ2G+f6qSp+GdykGIIKjZq3' psql -h 127.0.0.1 -p 5432 -U postgres -c \"select 1;\")",
|
||||
"Bash(timeout 2 bash -c \"echo > /dev/tcp/127.0.0.1/5432\")",
|
||||
"Bash(ip -4 addr show)",
|
||||
"Bash(timeout 2 bash -c \"echo > /dev/tcp/192.168.1.69/5432\")"
|
||||
]
|
||||
}
|
||||
}
|
||||
109
dot_config/ghostty/shaders/fireworks-rockets.glsl
Normal file
109
dot_config/ghostty/shaders/fireworks-rockets.glsl
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
// This Ghostty shader is a lightly modified port of https://www.shadertoy.com/view/4dBGRw
|
||||
|
||||
#define BLACK_BLEND_THRESHOLD .4
|
||||
|
||||
//Creates a diagonal red-and-white striped pattern.
|
||||
vec3 barberpole(vec2 pos, vec2 rocketpos) {
|
||||
float d = (pos.x - rocketpos.x) + (pos.y - rocketpos.y);
|
||||
vec3 col = vec3(1.0);
|
||||
|
||||
d = mod(d * 20., 2.0);
|
||||
if (d > 1.0) {
|
||||
col = vec3(1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
vec3 rocket(vec2 pos, vec2 rocketpos) {
|
||||
vec3 col = vec3(0.0);
|
||||
float f = 0.;
|
||||
float absx = abs(rocketpos.x - pos.x);
|
||||
float absy = abs(rocketpos.y - pos.y);
|
||||
|
||||
// Wooden stick
|
||||
if (absx < 0.01 && absy < 0.22) {
|
||||
col = vec3(1.0, 0.5, 0.5);
|
||||
}
|
||||
|
||||
// Barberpole
|
||||
if (absx < 0.05 && absy < 0.15) {
|
||||
col = barberpole(pos, rocketpos);
|
||||
}
|
||||
|
||||
// Rocket Point
|
||||
float pointw = (rocketpos.y - pos.y - 0.25) * -0.7;
|
||||
if ((rocketpos.y - pos.y) > 0.1) {
|
||||
f = smoothstep(pointw - 0.001, pointw + 0.001, absx);
|
||||
|
||||
col = mix(vec3(1.0, 0.0, 0.0), col, f);
|
||||
}
|
||||
|
||||
// Shadow
|
||||
f = -.5 + smoothstep(-0.05, 0.05, (rocketpos.x - pos.x));
|
||||
col *= 0.7 + f;
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
float rand(float val, float seed) {
|
||||
return cos(val * sin(val * seed) * seed);
|
||||
}
|
||||
|
||||
float distance2(in vec2 a, in vec2 b) {
|
||||
return dot(a - b, a - b);
|
||||
}
|
||||
|
||||
mat2 rr = mat2(cos(1.0), -sin(1.0), sin(1.0), cos(1.0));
|
||||
|
||||
vec3 drawParticles(vec2 pos, vec3 particolor, float time, vec2 cpos, float gravity, float seed, float timelength) {
|
||||
vec3 col = vec3(0.0);
|
||||
vec2 pp = vec2(1.0, 0.0);
|
||||
for (float i = 1.0; i <= 128.0; i++) {
|
||||
float d = rand(i, seed);
|
||||
float fade = (i / 128.0) * time;
|
||||
vec2 particpos = cpos + time * pp * d;
|
||||
pp = rr * pp;
|
||||
col = mix(particolor / fade, col, smoothstep(0.0, 0.0001, distance2(particpos, pos)));
|
||||
}
|
||||
col *= smoothstep(0.0, 1.0, (timelength - time) / timelength);
|
||||
|
||||
return col;
|
||||
}
|
||||
vec3 drawFireworks(float time, vec2 uv, vec3 particolor, float seed) {
|
||||
float timeoffset = 2.0;
|
||||
vec3 col = vec3(0.0);
|
||||
if (time <= 0.) {
|
||||
return col;
|
||||
}
|
||||
if (mod(time, 6.0) > timeoffset) {
|
||||
col = drawParticles(uv, particolor, mod(time, 6.0) - timeoffset, vec2(rand(ceil(time / 6.0), seed), -0.5), 0.5, ceil(time / 6.0), seed);
|
||||
} else {
|
||||
col = rocket(uv * 3., vec2(3. * rand(ceil(time / 6.0), seed), 3. * (-0.5 + (timeoffset - mod(time, 6.0)))));
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord)
|
||||
{
|
||||
vec2 uv = 1.0 - 2.0 * fragCoord.xy / iResolution.xy;
|
||||
uv.x *= iResolution.x / iResolution.y;
|
||||
vec3 col = vec3(0.1, 0.1, 0.2);
|
||||
|
||||
// Flip the y-axis so that the rocket is drawn from the bottom of the screen
|
||||
uv.y = -uv.y;
|
||||
|
||||
col += 0.1 * uv.y;
|
||||
|
||||
col += drawFireworks(iTime, uv, vec3(1.0, 0.1, 0.1), 1.);
|
||||
col += drawFireworks(iTime - 2.0, uv, vec3(0.0, 1.0, 0.5), 2.);
|
||||
col += drawFireworks(iTime - 4.0, uv, vec3(1.0, 1.0, 0.1), 3.);
|
||||
|
||||
vec2 termUV = fragCoord.xy / iResolution.xy;
|
||||
vec4 terminalColor = texture(iChannel0, termUV);
|
||||
|
||||
float alpha = step(length(terminalColor.rgb), BLACK_BLEND_THRESHOLD);
|
||||
vec3 blendedColor = mix(terminalColor.rgb * 1.0, col.rgb * 0.3, alpha);
|
||||
|
||||
fragColor = vec4(blendedColor, terminalColor.a);
|
||||
}
|
||||
139
dot_config/ghostty/shaders/galaxy.glsl
Normal file
139
dot_config/ghostty/shaders/galaxy.glsl
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
float triangle(float x, float period) {
|
||||
return 2.0 * abs(3.0* ((x / period) - floor((x / period) + 0.5))) - 1.0;
|
||||
}
|
||||
|
||||
float field(in vec3 position) {
|
||||
float strength = 7.0 + 0.03 * log(1.0e-6 + fract(sin(iTime) * 373.11));
|
||||
float accumulated = 0.0;
|
||||
float previousMagnitude = 0.0;
|
||||
float totalWeight = 0.0;
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
float magnitude = dot(position, position);
|
||||
position = abs(position) / magnitude + vec3(-0.5, -0.8 + 0.1 * sin(-iTime * 0.1 + 2.0), -1.1 + 0.3 * cos(iTime * 0.3));
|
||||
float weight = exp(-float(i) / 7.0);
|
||||
accumulated += weight * exp(-strength * pow(abs(magnitude - previousMagnitude), 2.3));
|
||||
totalWeight += weight;
|
||||
previousMagnitude = magnitude;
|
||||
}
|
||||
|
||||
return max(0.0, 5.0 * accumulated / totalWeight - 0.7);
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
const float baseSpeed = 0.02;
|
||||
const int maxIterations = 16;
|
||||
const float formulaParameter = 0.79;
|
||||
const float volumeSteps = 7.0;
|
||||
const float stepSize = 0.24;
|
||||
const float zoomFactor = 0.1;
|
||||
const float tilingFactor = 0.85;
|
||||
const float baseBrightness = 0.0008;
|
||||
const float darkMatter = 0.2;
|
||||
const float distanceFading = 0.56;
|
||||
const float colorSaturation = 0.9;
|
||||
const float transverseMotion = 0.2;
|
||||
const float cloudOpacity = 0.28;
|
||||
const float zoomSpeed = 0.00002;
|
||||
const float effectIntensity = 0.02; // 0.0 = terminal only, 1.0 = original intensity
|
||||
|
||||
vec2 normalizedCoordinates = 2.0 * fragCoord.xy / vec2(512) - 1.0;
|
||||
vec2 scaledCoordinates = normalizedCoordinates * vec2(512) / 512.0;
|
||||
|
||||
float timeElapsed = iTime;
|
||||
float speedAdjustment = -baseSpeed;
|
||||
float formulaAdjustment = formulaParameter;
|
||||
|
||||
speedAdjustment = zoomSpeed * cos(iTime * 0.02 + 3.1415926 / 4.0);
|
||||
|
||||
vec2 uvCoordinates = scaledCoordinates;
|
||||
|
||||
float rotationXZ = 0.9;
|
||||
float rotationYZ = -0.6;
|
||||
float rotationXY = 0.9 + iTime * 0.08;
|
||||
|
||||
mat2 rotationMatrixXZ = mat2(vec2(cos(rotationXZ), sin(rotationXZ)), vec2(-sin(rotationXZ), cos(rotationXZ)));
|
||||
mat2 rotationMatrixYZ = mat2(vec2(cos(rotationYZ), sin(rotationYZ)), vec2(-sin(rotationYZ), cos(rotationYZ)));
|
||||
mat2 rotationMatrixXY = mat2(vec2(cos(rotationXY), sin(rotationXY)), vec2(-sin(rotationXY), cos(rotationXY)));
|
||||
|
||||
vec2 canvasCenter = vec2(0.5, 0.5);
|
||||
vec3 rayDirection = vec3(uvCoordinates * zoomFactor, 1.0);
|
||||
vec3 cameraPosition = vec3(0.0, 0.0, 0.0);
|
||||
cameraPosition.x -= 2.0 * (canvasCenter.x - 0.5);
|
||||
cameraPosition.y -= 2.0 * (canvasCenter.y - 0.5);
|
||||
|
||||
vec3 forwardVector = vec3(0.0, 0.0, 1.0);
|
||||
cameraPosition.x += transverseMotion * cos(0.01 * iTime) + 0.001 * iTime;
|
||||
cameraPosition.y += transverseMotion * sin(0.01 * iTime) + 0.001 * iTime;
|
||||
cameraPosition.z += 0.003 * iTime;
|
||||
|
||||
rayDirection.xz *= rotationMatrixXZ;
|
||||
forwardVector.xz *= rotationMatrixXZ;
|
||||
rayDirection.yz *= rotationMatrixYZ;
|
||||
forwardVector.yz *= rotationMatrixYZ;
|
||||
|
||||
cameraPosition.xy *= -1.0 * rotationMatrixXY;
|
||||
cameraPosition.xz *= rotationMatrixXZ;
|
||||
cameraPosition.yz *= rotationMatrixYZ;
|
||||
|
||||
float zoomOffset = (timeElapsed - 3311.0) * speedAdjustment;
|
||||
cameraPosition += forwardVector * zoomOffset;
|
||||
float sampleOffset = mod(zoomOffset, stepSize);
|
||||
float normalizedSampleOffset = sampleOffset / stepSize;
|
||||
|
||||
float stepDistance = 0.24;
|
||||
float secondaryStepDistance = stepDistance + stepSize / 2.0;
|
||||
vec3 accumulatedColor = vec3(0.0);
|
||||
float fieldContribution = 0.0;
|
||||
vec3 backgroundColor = vec3(0.0);
|
||||
|
||||
for (float stepIndex = 0.0; stepIndex < volumeSteps; ++stepIndex) {
|
||||
vec3 primaryPosition = cameraPosition + (stepDistance + sampleOffset) * rayDirection;
|
||||
vec3 secondaryPosition = cameraPosition + (secondaryStepDistance + sampleOffset) * rayDirection;
|
||||
|
||||
primaryPosition = abs(vec3(tilingFactor) - mod(primaryPosition, vec3(tilingFactor * 2.0)));
|
||||
secondaryPosition = abs(vec3(tilingFactor) - mod(secondaryPosition, vec3(tilingFactor * 2.0)));
|
||||
|
||||
fieldContribution = field(secondaryPosition);
|
||||
|
||||
float particleAccumulator = 0.0, particleDistance = 0.0;
|
||||
for (int i = 0; i < maxIterations; ++i) {
|
||||
primaryPosition = abs(primaryPosition) / dot(primaryPosition, primaryPosition) - formulaAdjustment;
|
||||
float distanceChange = abs(length(primaryPosition) - particleDistance);
|
||||
particleAccumulator += i > 2 ? min(12.0, distanceChange) : distanceChange;
|
||||
particleDistance = length(primaryPosition);
|
||||
}
|
||||
particleAccumulator *= particleAccumulator * particleAccumulator;
|
||||
|
||||
float fadeFactor = pow(distanceFading, max(0.0, float(stepIndex) - normalizedSampleOffset));
|
||||
accumulatedColor += vec3(stepDistance, stepDistance * stepDistance, stepDistance * stepDistance * stepDistance * stepDistance)
|
||||
* particleAccumulator * baseBrightness * fadeFactor;
|
||||
backgroundColor += mix(0.4, 1.0, cloudOpacity) * vec3(1.8 * fieldContribution * fieldContribution * fieldContribution,
|
||||
1.4 * fieldContribution * fieldContribution, fieldContribution) * fadeFactor;
|
||||
stepDistance += stepSize;
|
||||
secondaryStepDistance += stepSize;
|
||||
}
|
||||
|
||||
accumulatedColor = mix(vec3(length(accumulatedColor)), accumulatedColor, colorSaturation);
|
||||
|
||||
vec4 foregroundColor = vec4(accumulatedColor * 0.01, 1.0);
|
||||
backgroundColor *= cloudOpacity;
|
||||
backgroundColor.b *= 1.8;
|
||||
backgroundColor.r *= 0.05;
|
||||
|
||||
backgroundColor.b = 0.5 * mix(backgroundColor.g, backgroundColor.b, 0.8);
|
||||
backgroundColor.g = 0.0;
|
||||
backgroundColor.bg = mix(backgroundColor.gb, backgroundColor.bg, 0.5 * (cos(iTime * 0.01) + 1.0));
|
||||
|
||||
vec2 terminalUV = fragCoord.xy / iResolution.xy;
|
||||
vec4 terminalColor = texture(iChannel0, terminalUV);
|
||||
|
||||
float brightnessThreshold = 0.1;
|
||||
float terminalBrightness = dot(terminalColor.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
|
||||
if (terminalBrightness < brightnessThreshold) {
|
||||
fragColor = mix(terminalColor, vec4(foregroundColor.rgb + backgroundColor, 1.0), 0.24 * effectIntensity);
|
||||
} else {
|
||||
fragColor = terminalColor;
|
||||
}
|
||||
}
|
||||
202
dot_config/ghostty/shaders/geocities.glsl
Normal file
202
dot_config/ghostty/shaders/geocities.glsl
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
// geocities.glsl — a tribute to the golden age of blinking, tiled,
|
||||
// under-construction personal homepages. Caution-stripe wallpaper,
|
||||
// a rainbow sparkle field with hard blink (not a gentle twinkle),
|
||||
// a scrolling pixel-font "UNDER CONSTRUCTION" marquee, and a bouncing
|
||||
// rotating star badge, DVD-logo style.
|
||||
|
||||
// transparent background
|
||||
const bool transparent = true;
|
||||
|
||||
// terminal contents luminance threshold to be considered background (0.0 to 1.0)
|
||||
const float threshold = 0.02;
|
||||
|
||||
// show/hide individual gimmicks
|
||||
const bool showStripes = true;
|
||||
const bool showSparkles = true;
|
||||
const bool showMarquee = true;
|
||||
const bool showBadge = true;
|
||||
|
||||
// caution-stripe wallpaper opacity (0.0 to 1.0)
|
||||
const float stripeOpacity = 0.02;
|
||||
|
||||
// sparkle field brightness
|
||||
const float sparkleIntensity = 0.1;
|
||||
|
||||
// marquee scroll speed, in pixels per second
|
||||
const float scrollSpeed = 90.0;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// helpers
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
float luminance(vec3 color) {
|
||||
return dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||
}
|
||||
|
||||
vec3 hsv2rgb(vec3 c) {
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
float hash21(vec2 p) {
|
||||
p = fract(p * vec2(233.34, 851.73));
|
||||
p += dot(p, p + 23.45);
|
||||
return fract(p.x * p.y);
|
||||
}
|
||||
|
||||
// 0 -> 1 -> 0 triangle wave, used to ping-pong the bouncing badge
|
||||
float triangleWave(float x, float period) {
|
||||
float t = fract(x / period);
|
||||
return 1.0 - abs(2.0 * t - 1.0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// tiny 5x7 pixel font, just enough glyphs to spell "UNDER CONSTRUCTION"
|
||||
// each row is packed as a 5-bit value, bit weight 16 = leftmost column
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
const int FONT_ROWS = 7;
|
||||
const int FONT[77] = int[77](
|
||||
0, 0, 0, 0, 0, 0, 0, // 0: space
|
||||
17, 17, 17, 17, 17, 17, 14, // 1: U
|
||||
17, 25, 21, 21, 19, 17, 17, // 2: N
|
||||
30, 17, 17, 17, 17, 17, 30, // 3: D
|
||||
31, 16, 16, 30, 16, 16, 31, // 4: E
|
||||
30, 17, 17, 30, 20, 18, 17, // 5: R
|
||||
15, 16, 16, 16, 16, 16, 15, // 6: C
|
||||
14, 17, 17, 17, 17, 17, 14, // 7: O
|
||||
15, 16, 16, 14, 1, 1, 30, // 8: S
|
||||
31, 4, 4, 4, 4, 4, 4, // 9: T
|
||||
31, 4, 4, 4, 4, 4, 31 // 10: I
|
||||
);
|
||||
|
||||
// "UNDER CONSTRUCTION" as indices into the glyph table above
|
||||
const int MSG_LEN = 18;
|
||||
const int MSG[18] = int[18](1, 2, 3, 4, 5, 0, 6, 7, 2, 8, 9, 5, 1, 6, 9, 10, 7, 2);
|
||||
|
||||
float fontBit(int code, int row, int col) {
|
||||
int rowVal = FONT[code * FONT_ROWS + row];
|
||||
float shifted = floor(float(rowVal) / pow(2.0, float(4 - col)));
|
||||
return mod(shifted, 2.0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// background gimmicks
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
vec3 hazardStripes(vec2 fragCoord) {
|
||||
float stripeWidth = 18.0;
|
||||
float diag = (fragCoord.x + fragCoord.y) + iTime * 40.0;
|
||||
float m = mod(diag, stripeWidth * 2.0);
|
||||
vec3 yellow = vec3(1.0, 0.82, 0.0);
|
||||
vec3 blk = vec3(0.05);
|
||||
return m < stripeWidth ? yellow : blk;
|
||||
}
|
||||
|
||||
vec3 sparkleStars(vec2 uv, vec2 resolution) {
|
||||
vec2 gridUV = uv;
|
||||
gridUV.x *= resolution.x / resolution.y;
|
||||
gridUV *= 26.0;
|
||||
|
||||
vec2 ipos = floor(gridUV);
|
||||
vec2 fpos = fract(gridUV);
|
||||
|
||||
// only a fraction of cells host a star
|
||||
float rnd = hash21(ipos);
|
||||
if (rnd > 0.12) return vec3(0.0);
|
||||
|
||||
vec2 center = vec2(hash21(ipos + 3.1), hash21(ipos + 7.7));
|
||||
float d = length(fpos - center);
|
||||
|
||||
// hard on/off blink rather than a smooth twinkle, tacky on purpose
|
||||
float phase = hash21(ipos + 11.0) * 10.0;
|
||||
float blink = step(0.5, fract(iTime * (1.5 + rnd * 4.0) + phase));
|
||||
|
||||
float glow = smoothstep(0.12, 0.0, d);
|
||||
vec3 hue = hsv2rgb(vec3(fract(rnd * 4.0 + iTime * 0.1), 1.0, 1.0));
|
||||
return hue * glow * blink;
|
||||
}
|
||||
|
||||
vec3 starBadge(vec2 fragCoord, vec2 resolution) {
|
||||
float radius = 26.0;
|
||||
float px = mix(radius, resolution.x - radius, triangleWave(iTime * 0.09, 1.0));
|
||||
float py = mix(radius, resolution.y - radius, triangleWave(iTime * 0.13 + 0.37, 1.0));
|
||||
vec2 p = fragCoord - vec2(px, py);
|
||||
|
||||
float d = length(p);
|
||||
float a = atan(p.y, p.x) - iTime * 2.0;
|
||||
float starR = radius * (0.55 + 0.45 * cos(a * 5.0));
|
||||
float shape = smoothstep(1.5, -1.5, d - starR);
|
||||
|
||||
vec3 hue = hsv2rgb(vec3(fract(iTime * 0.3), 1.0, 1.0));
|
||||
return hue * shape;
|
||||
}
|
||||
|
||||
// returns rgb + coverage alpha for the scrolling marquee ticker
|
||||
vec4 marquee(vec2 fragCoord, vec2 resolution) {
|
||||
float scale = clamp(resolution.y / 220.0, 2.0, 6.0);
|
||||
float charW = 6.0 * scale; // 5 columns + 1 spacing column
|
||||
float charH = 8.0 * scale; // 7 rows + 1 spacing row
|
||||
|
||||
int gap = 6; // blank characters between loops of the message
|
||||
int totalChars = MSG_LEN + gap;
|
||||
|
||||
// band hugs the bottom edge of the terminal
|
||||
float bandY0 = resolution.y - charH - scale * 2.0;
|
||||
float localY = fragCoord.y - bandY0;
|
||||
if (localY < 0.0 || localY >= charH) return vec4(0.0);
|
||||
int row = int(floor(localY / scale));
|
||||
if (row >= FONT_ROWS) return vec4(0.0);
|
||||
|
||||
float scrollX = fragCoord.x + iTime * scrollSpeed;
|
||||
float totalWidth = float(totalChars) * charW;
|
||||
float wrapped = mod(scrollX, totalWidth);
|
||||
int charIndex = int(floor(wrapped / charW));
|
||||
if (charIndex >= MSG_LEN) return vec4(0.0); // in the gap, blank
|
||||
|
||||
float localX = mod(wrapped, charW);
|
||||
int col = int(floor(localX / scale));
|
||||
if (col >= 5) return vec4(0.0);
|
||||
|
||||
int code = MSG[charIndex];
|
||||
if (fontBit(code, row, col) < 0.5) return vec4(0.0);
|
||||
|
||||
vec3 color = hsv2rgb(vec3(fract(float(charIndex) / float(MSG_LEN) + iTime * 0.15), 1.0, 1.0));
|
||||
return vec4(color, 1.0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// main
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
vec2 uv = fragCoord / iResolution.xy;
|
||||
vec4 terminalColor = texture(iChannel0, uv);
|
||||
|
||||
vec3 deco = vec3(0.0);
|
||||
|
||||
if (showStripes) {
|
||||
deco += hazardStripes(fragCoord) * stripeOpacity;
|
||||
}
|
||||
if (showSparkles) {
|
||||
deco += sparkleStars(uv, iResolution.xy) * sparkleIntensity;
|
||||
}
|
||||
if (showBadge) {
|
||||
deco = max(deco, starBadge(fragCoord, iResolution.xy));
|
||||
}
|
||||
if (showMarquee) {
|
||||
vec4 marq = marquee(fragCoord, iResolution.xy);
|
||||
deco = mix(deco, marq.rgb, marq.a);
|
||||
}
|
||||
|
||||
if (transparent) {
|
||||
deco += terminalColor.rgb;
|
||||
}
|
||||
|
||||
// only show the effect where the terminal is background (not text)
|
||||
float mask = 1.0 - step(threshold, luminance(terminalColor.rgb));
|
||||
vec3 blended = mix(terminalColor.rgb, deco, mask);
|
||||
|
||||
fragColor = vec4(blended, terminalColor.a);
|
||||
}
|
||||
91
dot_config/ghostty/shaders/iamond_teeth_cursor.glsl
Normal file
91
dot_config/ghostty/shaders/iamond_teeth_cursor.glsl
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#define PI 3.141592653589793
|
||||
|
||||
vec2 pxToNdc(vec2 p, float isPosition) {
|
||||
return (p * 2.0 - iResolution.xy * isPosition) / iResolution.y;
|
||||
}
|
||||
|
||||
float segPos(vec2 p, vec2 a, vec2 b) {
|
||||
vec2 ba = b - a;
|
||||
return clamp(dot(p - a, ba) / max(dot(ba, ba), 0.000001), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float segDist(vec2 p, vec2 a, vec2 b) {
|
||||
float h = segPos(p, a, b);
|
||||
return length(p - (a + (b - a) * h));
|
||||
}
|
||||
|
||||
float diamond(vec2 p, vec2 c, float r) {
|
||||
float d = abs(p.x - c.x) + abs(p.y - c.y);
|
||||
return 1.0 - smoothstep(r * 0.25, r, d);
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
vec4 base = texture(iChannel0, uv);
|
||||
vec3 col = base.rgb;
|
||||
|
||||
vec2 p = pxToNdc(fragCoord.xy, 1.0);
|
||||
|
||||
// Ghostty cursor rect: xy is the top-left-ish corner, zw is width/height.
|
||||
vec2 curPx = vec2(
|
||||
iCurrentCursor.x + iCurrentCursor.z * 0.5,
|
||||
iCurrentCursor.y - iCurrentCursor.w * 0.5
|
||||
);
|
||||
|
||||
vec2 prevPx = vec2(
|
||||
iPreviousCursor.x + iPreviousCursor.z * 0.5,
|
||||
iPreviousCursor.y - iPreviousCursor.w * 0.5
|
||||
);
|
||||
|
||||
vec2 cur = pxToNdc(curPx, 1.0);
|
||||
vec2 prev = pxToNdc(prevPx, 1.0);
|
||||
|
||||
float cell = max(0.008, max(iCurrentCursor.z, iCurrentCursor.w) * 2.0 / iResolution.y);
|
||||
float age = clamp(iTime - iTimeCursorChange, 0.0, 2.0);
|
||||
float pulse = exp(-age * 4.5);
|
||||
|
||||
float moved = smoothstep(cell * 1.2, cell * 5.0, distance(cur, prev));
|
||||
|
||||
// Orange-gold trail after cursor jumps.
|
||||
float h = segPos(p, prev, cur);
|
||||
float trailD = segDist(p, prev, cur);
|
||||
float trail = (1.0 - smoothstep(cell * 0.18, cell * 0.85, trailD));
|
||||
trail *= sin(h * PI) * moved * pulse;
|
||||
|
||||
col += trail * vec3(1.0, 0.36, 0.05) * 0.90;
|
||||
|
||||
// Gold glow around current cursor.
|
||||
float d = length(p - cur);
|
||||
float shimmer = 0.75 + 0.25 * sin(iTime * 9.0 + d * 90.0);
|
||||
float glow = exp(-d / (cell * 4.0)) * 0.28 * shimmer;
|
||||
col += glow * vec3(1.0, 0.62, 0.12);
|
||||
|
||||
// Expanding diamond ring when cursor moves.
|
||||
float ringRadius = cell * (1.30 + 2.20 * pulse);
|
||||
float ring = 1.0 - smoothstep(cell * 0.10, cell * 0.35, abs(d - ringRadius));
|
||||
col += ring * vec3(1.0, 0.92, 0.65) * (0.42 + 0.75 * pulse);
|
||||
|
||||
// Tiny orbiting diamonds: pinky ring / grill sparkle.
|
||||
float orbit = 0.0;
|
||||
for (int k = 0; k < 8; k++) {
|
||||
float fi = float(k);
|
||||
float dir = mix(-1.0, 1.0, step(0.5, mod(fi, 2.0)));
|
||||
float a = fi * PI * 2.0 / 8.0 + iTime * (1.5 + 0.1 * fi) * dir;
|
||||
float rad = cell * (2.4 + 0.45 * sin(iTime * 2.0 + fi * 1.7));
|
||||
vec2 q = cur + vec2(cos(a), sin(a)) * rad;
|
||||
|
||||
float tw = 0.65 + 0.35 * sin(iTime * 7.0 + fi * 2.0);
|
||||
orbit += diamond(p, q, cell * 0.45) * tw;
|
||||
}
|
||||
|
||||
col += orbit * vec3(1.0, 0.86, 0.50) * 0.70;
|
||||
|
||||
// Cross flare directly on cursor.
|
||||
float flareX = (1.0 - smoothstep(0.0, cell * 0.035, abs(p.y - cur.y))) *
|
||||
(1.0 - smoothstep(0.0, cell * 4.5, abs(p.x - cur.x)));
|
||||
float flareY = (1.0 - smoothstep(0.0, cell * 0.035, abs(p.x - cur.x))) *
|
||||
(1.0 - smoothstep(0.0, cell * 4.5, abs(p.y - cur.y)));
|
||||
col += (flareX + flareY) * vec3(1.0, 0.92, 0.60) * 0.11;
|
||||
|
||||
fragColor = vec4(clamp(col, 0.0, 1.0), base.a);
|
||||
}
|
||||
154
dot_config/ghostty/shaders/rectangle_boom_cursor.glsl
Normal file
154
dot_config/ghostty/shaders/rectangle_boom_cursor.glsl
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
// 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 ANIMATION_START_OFFSET = 0.0; // Start the ripple slightly progressed (0.0 - 1.0)
|
||||
vec4 COLOR = vec4(0.35, 0.36, 0.44, 1.0); // change to iCurrentCursorColor for your cursor's color
|
||||
const float CURSOR_WIDTH_CHANGE_THRESHOLD = 0.5; // Triggers ripple if cursor width changes by this fraction
|
||||
const float BLUR = 3.0; // Blur level in pixels
|
||||
|
||||
// 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 smoothstepPulse(float t) {
|
||||
return 4.0 * t * (1.0 - t);
|
||||
}
|
||||
float easeOutPulse(float t) {
|
||||
return t * (2.0 - t);
|
||||
}
|
||||
float powerCurvePulse(float t) {
|
||||
float x = t * 2.0 - 1.0;
|
||||
return 1.0 - x * x;
|
||||
}
|
||||
float doubleSmoothstepPulse(float t) {
|
||||
return smoothstep(0.0, 0.5, t) * (1.0 - smoothstep(0.5, 1.0, t));
|
||||
}
|
||||
float exponentialDecayPulse(float t) {
|
||||
return exp(-3.0 * t) * sin(t * 3.1415916);
|
||||
}
|
||||
float sinPulse(float t) {
|
||||
return 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
|
||||
|
||||
// WHY NOT BRANCHLESS??? here ya go:
|
||||
// because we NEVER have divergence, even in this if/else branchfull logic
|
||||
// why? because its UNIFORM branching (ie, all fragments take the same path) which modern GPUs handles efficiently
|
||||
// its far more efficient than calculating the ripple EVERY FRAME even when not needed(branchless)
|
||||
if (isModeChange > 0.0 && isAnimating > 0.0) {
|
||||
// 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);
|
||||
|
||||
// easedProgress = clamp(easedProgress, 0.0, 1.0);
|
||||
|
||||
// RIPPLE CALCULATION
|
||||
float rippleExpansion = easedProgress * MAX_SIZE;
|
||||
|
||||
// float fade = 1.0; // no fade
|
||||
// float fade = 1.0 - easedProgress; // linear fade
|
||||
// float fade = 1.0 - smoothstepPulse(rippleProgress);
|
||||
float fade = 1.0 - easeOutPulse(rippleProgress);
|
||||
// float fade = 1.0 - powerCurvePulse(rippleProgress);
|
||||
// float fade = doubleSmoothstepPulse(rippleProgress);
|
||||
// float fade = exponentialDecayPulse(rippleProgress);
|
||||
// float fade = sinPulse(rippleProgress);
|
||||
|
||||
vec2 halfSizeCC = vec2(currentCursor.z, currentCursor.w) * 0.5 + vec2(rippleExpansion);
|
||||
float sdfRectRing = getSdfRectangle(vu, centerCC, halfSizeCC);
|
||||
|
||||
// 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
|
||||
}
|
||||
132
dot_config/ghostty/shaders/ripple_cursor.glsl
Normal file
132
dot_config/ghostty/shaders/ripple_cursor.glsl
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
// CONFIGURATION
|
||||
const float DURATION = 0.15; // How long the ripple animates (seconds)
|
||||
const float MAX_RADIUS = 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 = 3.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;
|
||||
}
|
||||
|
||||
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 rippleRadius = easedProgress * MAX_RADIUS;
|
||||
|
||||
// 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 - rippleRadius) - 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, sdfRing)) * fade;
|
||||
|
||||
// Apply ripple effect
|
||||
fragColor = mix(fragColor, COLOR, ripple * COLOR.a);
|
||||
}
|
||||
// else: do nothing, keep original fragColor
|
||||
}
|
||||
138
dot_config/ghostty/shaders/ripple_rectangle_cursor.glsl
Normal file
138
dot_config/ghostty/shaders/ripple_rectangle_cursor.glsl
Normal file
|
|
@ -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
|
||||
}
|
||||
148
dot_config/ghostty/shaders/sonic_boom_cursor.glsl
Normal file
148
dot_config/ghostty/shaders/sonic_boom_cursor.glsl
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
// CONFIGURATION
|
||||
const float DURATION = 0.15; // How long the ripple animates (seconds)
|
||||
const float MAX_RADIUS = 0.06; // Max radius in normalized coords (0.5 = 1/4 screen height)
|
||||
const float ANIMATION_START_OFFSET = 0.0; // Start the ripple slightly progressed (0.0 - 1.0)
|
||||
vec4 COLOR = vec4(0.35, 0.36, 0.44, 1.0); // change to iCurrentCursorColor for your cursor's color
|
||||
const float CURSOR_WIDTH_CHANGE_THRESHOLD = 0.5; // Triggers ripple if cursor width changes by this fraction
|
||||
const float BLUR = 3.0; // Blur level in pixels
|
||||
|
||||
|
||||
// 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 smoothstepPulse(float t) {
|
||||
return 4.0 * t * (1.0 - t);
|
||||
}
|
||||
float easeOutPulse(float t) {
|
||||
return t * (2.0 - t);
|
||||
}
|
||||
float powerCurvePulse(float t) {
|
||||
float x = t * 2.0 - 1.0;
|
||||
return 1.0 - x * x;
|
||||
}
|
||||
float doubleSmoothstepPulse(float t) {
|
||||
return smoothstep(0.0, 0.5, t) * (1.0 - smoothstep(0.5, 1.0, t));
|
||||
}
|
||||
float exponentialDecayPulse(float t) {
|
||||
return exp(-3.0 * t) * sin(t * 3.1415916);
|
||||
}
|
||||
float sinPulse(float t) {
|
||||
return sin(t * 3.1415916);
|
||||
}
|
||||
|
||||
vec2 normalize(vec2 value, float isPosition) {
|
||||
return (value * 2.0 - (iResolution.xy * isPosition)) / iResolution.y;
|
||||
}
|
||||
|
||||
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) {
|
||||
// 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);
|
||||
|
||||
// easedProgress = clamp(easedProgress, 0.0, 1.0);
|
||||
|
||||
// RIPPLE CALCULATION
|
||||
float rippleRadius = easedProgress * MAX_RADIUS;
|
||||
|
||||
// float fade = 1.0; // no fade
|
||||
// float fade = 1.0 - easedProgress; // linear fade
|
||||
// float fade = 1.0 - smoothstepPulse(rippleProgress);
|
||||
float fade = 1.0 - easeOutPulse(rippleProgress);
|
||||
// float fade = 1.0 - powerCurvePulse(rippleProgress);
|
||||
// float fade = doubleSmoothstepPulse(rippleProgress);
|
||||
// float fade = exponentialDecayPulse(rippleProgress);
|
||||
// float fade = sinPulse(rippleProgress);
|
||||
|
||||
// Calculate distance from frag to cursor center
|
||||
float dist = distance(vu, centerCC);
|
||||
|
||||
float sdfCircle = dist - rippleRadius;
|
||||
|
||||
// Antialias (1-pixel width in normalized coords)
|
||||
float antiAliasSize = normalize(vec2(BLUR, BLUR), 0.0).x;
|
||||
float ripple = (1.0 - smoothstep(-antiAliasSize, antiAliasSize, sdfCircle)) * fade;
|
||||
|
||||
// Apply ripple effect
|
||||
fragColor = mix(fragColor, COLOR, ripple * COLOR.a);
|
||||
}
|
||||
}
|
||||
162
dot_config/ghostty/shaders/starfield-colors.glsl
Normal file
162
dot_config/ghostty/shaders/starfield-colors.glsl
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
// transparent background
|
||||
const bool transparent = true;
|
||||
|
||||
// terminal contents luminance threshold to be considered background (0.0 to 1.0)
|
||||
const float threshold = 0.05;
|
||||
|
||||
// overall star brightness (0.0 = invisible, 1.0 = original brightness)
|
||||
const float intensity = 0.09;
|
||||
|
||||
// divisions of grid
|
||||
const float repeats = 15.;
|
||||
|
||||
// number of layers
|
||||
const float layers = 20.;
|
||||
|
||||
// star colours
|
||||
const vec3 blue = vec3(51., 64., 195.) / 255.;
|
||||
const vec3 cyan = vec3(117., 250., 254.) / 255.;
|
||||
const vec3 white = vec3(255., 255., 255.) / 255.;
|
||||
const vec3 yellow = vec3(251., 245., 44.) / 255.;
|
||||
const vec3 red = vec3(247, 2., 20.) / 255.;
|
||||
|
||||
float luminance(vec3 color) {
|
||||
return dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||
}
|
||||
|
||||
// spectrum function
|
||||
vec3 spectrum(vec2 pos) {
|
||||
pos.x *= 4.;
|
||||
vec3 outCol = vec3(0);
|
||||
if (pos.x > 0.) {
|
||||
outCol = mix(blue, cyan, fract(pos.x));
|
||||
}
|
||||
if (pos.x > 1.) {
|
||||
outCol = mix(cyan, white, fract(pos.x));
|
||||
}
|
||||
if (pos.x > 2.) {
|
||||
outCol = mix(white, yellow, fract(pos.x));
|
||||
}
|
||||
if (pos.x > 3.) {
|
||||
outCol = mix(yellow, red, fract(pos.x));
|
||||
}
|
||||
|
||||
return 1. - (pos.y * (1. - outCol));
|
||||
}
|
||||
|
||||
float N21(vec2 p) {
|
||||
p = fract(p * vec2(233.34, 851.73));
|
||||
p += dot(p, p + 23.45);
|
||||
return fract(p.x * p.y);
|
||||
}
|
||||
|
||||
vec2 N22(vec2 p) {
|
||||
float n = N21(p);
|
||||
return vec2(n, N21(p + n));
|
||||
}
|
||||
|
||||
mat2 scale(vec2 _scale) {
|
||||
return mat2(_scale.x, 0.0,
|
||||
0.0, _scale.y);
|
||||
}
|
||||
|
||||
// 2D Noise based on Morgan McGuire
|
||||
float noise(in vec2 st) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
|
||||
// Four corners in 2D of a tile
|
||||
float a = N21(i);
|
||||
float b = N21(i + vec2(1.0, 0.0));
|
||||
float c = N21(i + vec2(0.0, 1.0));
|
||||
float d = N21(i + vec2(1.0, 1.0));
|
||||
|
||||
// Smooth Interpolation
|
||||
vec2 u = f * f * (3.0 - 2.0 * f); // Cubic Hermite Curve
|
||||
|
||||
// Mix 4 corners percentages
|
||||
return mix(a, b, u.x) +
|
||||
(c - a) * u.y * (1.0 - u.x) +
|
||||
(d - b) * u.x * u.y;
|
||||
}
|
||||
|
||||
float perlin2(vec2 uv, int octaves, float pscale) {
|
||||
float col = 1.;
|
||||
float initScale = 4.;
|
||||
for (int l; l < octaves; l++) {
|
||||
float val = noise(uv * initScale);
|
||||
if (col <= 0.01) {
|
||||
col = 0.;
|
||||
break;
|
||||
}
|
||||
val -= 0.01;
|
||||
val *= 0.5;
|
||||
col *= val;
|
||||
initScale *= pscale;
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
vec3 stars(vec2 uv, float offset) {
|
||||
float timeScale = -(iTime + offset) / layers;
|
||||
float trans = fract(timeScale);
|
||||
float newRnd = floor(timeScale);
|
||||
vec3 col = vec3(0.);
|
||||
|
||||
// Translate uv then scale for center
|
||||
uv -= vec2(0.5);
|
||||
uv = scale(vec2(trans)) * uv;
|
||||
uv += vec2(0.5);
|
||||
|
||||
// Create square aspect ratio
|
||||
uv.x *= iResolution.x / iResolution.y;
|
||||
|
||||
// Create boxes
|
||||
uv *= repeats;
|
||||
|
||||
// Get position
|
||||
vec2 ipos = floor(uv);
|
||||
|
||||
// Return uv as 0 to 1
|
||||
uv = fract(uv);
|
||||
|
||||
// Calculate random xy and size
|
||||
vec2 rndXY = N22(newRnd + ipos * (offset + 1.)) * 0.9 + 0.05;
|
||||
float rndSize = N21(ipos) * 100. + 200.;
|
||||
|
||||
vec2 j = (rndXY - uv) * rndSize;
|
||||
float sparkle = 1. / dot(j, j);
|
||||
|
||||
// Set stars to be pure white
|
||||
col += spectrum(fract(rndXY * newRnd * ipos)) * vec3(sparkle);
|
||||
|
||||
col *= smoothstep(1., 0.8, trans);
|
||||
return col; // Return pure white stars only
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord)
|
||||
{
|
||||
// Normalized pixel coordinates (from 0 to 1)
|
||||
vec2 uv = fragCoord / iResolution.xy;
|
||||
|
||||
vec3 col = vec3(0.);
|
||||
|
||||
for (float i = 0.; i < layers; i++) {
|
||||
col += stars(uv, i);
|
||||
}
|
||||
col *= intensity;
|
||||
|
||||
// Sample the terminal screen texture including alpha channel
|
||||
vec4 terminalColor = texture(iChannel0, uv);
|
||||
|
||||
if (transparent) {
|
||||
col += terminalColor.rgb;
|
||||
}
|
||||
|
||||
// Make a mask that is 1.0 where the terminal content is not black
|
||||
float mask = 1 - step(threshold, luminance(terminalColor.rgb));
|
||||
vec3 blendedColor = mix(terminalColor.rgb, col, mask);
|
||||
|
||||
// Apply terminal's alpha to control overall opacity
|
||||
fragColor = vec4(blendedColor, terminalColor.a);
|
||||
}
|
||||
135
dot_config/ghostty/shaders/starfield.glsl
Normal file
135
dot_config/ghostty/shaders/starfield.glsl
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
// transparent background
|
||||
const bool transparent = false;
|
||||
|
||||
// terminal contents luminance threshold to be considered background (0.0 to 1.0)
|
||||
const float threshold = 0.15;
|
||||
|
||||
// divisions of grid
|
||||
const float repeats = 30.;
|
||||
|
||||
// number of layers
|
||||
const float layers = 21.;
|
||||
|
||||
// star colors
|
||||
const vec3 white = vec3(1.0); // Set star color to pure white
|
||||
|
||||
float luminance(vec3 color) {
|
||||
return dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||
}
|
||||
|
||||
float N21(vec2 p) {
|
||||
p = fract(p * vec2(233.34, 851.73));
|
||||
p += dot(p, p + 23.45);
|
||||
return fract(p.x * p.y);
|
||||
}
|
||||
|
||||
vec2 N22(vec2 p) {
|
||||
float n = N21(p);
|
||||
return vec2(n, N21(p + n));
|
||||
}
|
||||
|
||||
mat2 scale(vec2 _scale) {
|
||||
return mat2(_scale.x, 0.0,
|
||||
0.0, _scale.y);
|
||||
}
|
||||
|
||||
// 2D Noise based on Morgan McGuire
|
||||
float noise(in vec2 st) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
|
||||
// Four corners in 2D of a tile
|
||||
float a = N21(i);
|
||||
float b = N21(i + vec2(1.0, 0.0));
|
||||
float c = N21(i + vec2(0.0, 1.0));
|
||||
float d = N21(i + vec2(1.0, 1.0));
|
||||
|
||||
// Smooth Interpolation
|
||||
vec2 u = f * f * (3.0 - 2.0 * f); // Cubic Hermite Curve
|
||||
|
||||
// Mix 4 corners percentages
|
||||
return mix(a, b, u.x) +
|
||||
(c - a) * u.y * (1.0 - u.x) +
|
||||
(d - b) * u.x * u.y;
|
||||
}
|
||||
|
||||
float perlin2(vec2 uv, int octaves, float pscale) {
|
||||
float col = 1.;
|
||||
float initScale = 4.;
|
||||
for (int l; l < octaves; l++) {
|
||||
float val = noise(uv * initScale);
|
||||
if (col <= 0.01) {
|
||||
col = 0.;
|
||||
break;
|
||||
}
|
||||
val -= 0.01;
|
||||
val *= 0.5;
|
||||
col *= val;
|
||||
initScale *= pscale;
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
vec3 stars(vec2 uv, float offset) {
|
||||
float timeScale = -(iTime + offset) / layers;
|
||||
float trans = fract(timeScale);
|
||||
float newRnd = floor(timeScale);
|
||||
vec3 col = vec3(0.);
|
||||
|
||||
// Translate uv then scale for center
|
||||
uv -= vec2(0.5);
|
||||
uv = scale(vec2(trans)) * uv;
|
||||
uv += vec2(0.5);
|
||||
|
||||
// Create square aspect ratio
|
||||
uv.x *= iResolution.x / iResolution.y;
|
||||
|
||||
// Create boxes
|
||||
uv *= repeats;
|
||||
|
||||
// Get position
|
||||
vec2 ipos = floor(uv);
|
||||
|
||||
// Return uv as 0 to 1
|
||||
uv = fract(uv);
|
||||
|
||||
// Calculate random xy and size
|
||||
vec2 rndXY = N22(newRnd + ipos * (offset + 1.)) * 0.9 + 0.05;
|
||||
float rndSize = N21(ipos) * 100. + 200.;
|
||||
|
||||
vec2 j = (rndXY - uv) * rndSize;
|
||||
float sparkle = 1. / dot(j, j);
|
||||
|
||||
// Set stars to be pure white
|
||||
col += white * sparkle;
|
||||
|
||||
col *= smoothstep(1., 0.8, trans);
|
||||
return col; // Return pure white stars only
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord)
|
||||
{
|
||||
// Normalized pixel coordinates (from 0 to 1)
|
||||
vec2 uv = fragCoord / iResolution.xy;
|
||||
|
||||
vec3 col = vec3(0.);
|
||||
|
||||
for (float i = 0.; i < layers; i++) {
|
||||
col += stars(uv, i);
|
||||
}
|
||||
|
||||
// Sample the terminal screen texture including alpha channel
|
||||
vec4 terminalColor = texture(iChannel0, uv);
|
||||
|
||||
if (transparent) {
|
||||
col += terminalColor.rgb;
|
||||
}
|
||||
|
||||
// Make a mask that is 1.0 where the terminal content is not black
|
||||
float mask = 1 - step(threshold, luminance(terminalColor.rgb));
|
||||
|
||||
vec3 blendedColor = mix(terminalColor.rgb, col, mask);
|
||||
|
||||
// Apply terminal's alpha to control overall opacity
|
||||
fragColor = vec4(blendedColor, terminalColor.a);
|
||||
}
|
||||
23
dot_config/ghostty/themes/cyberdream
Normal file
23
dot_config/ghostty/themes/cyberdream
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# cyberdream theme for ghostty
|
||||
palette = 0=#16181a
|
||||
palette = 1=#ff6e5e
|
||||
palette = 2=#5eff6c
|
||||
palette = 3=#f1ff5e
|
||||
palette = 4=#5ea1ff
|
||||
palette = 5=#bd5eff
|
||||
palette = 6=#5ef1ff
|
||||
palette = 7=#ffffff
|
||||
palette = 8=#3c4048
|
||||
palette = 9=#ff6e5e
|
||||
palette = 10=#5eff6c
|
||||
palette = 11=#f1ff5e
|
||||
palette = 12=#5ea1ff
|
||||
palette = 13=#bd5eff
|
||||
palette = 14=#5ef1ff
|
||||
palette = 15=#ffffff
|
||||
|
||||
background = #16181a
|
||||
foreground = #ffffff
|
||||
cursor-color = #ffffff
|
||||
selection-background = #3c4048
|
||||
selection-foreground = #ffffff
|
||||
23
dot_config/ghostty/themes/cyberdream-light
Normal file
23
dot_config/ghostty/themes/cyberdream-light
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# cyberdream theme for ghostty
|
||||
palette = 0=#ffffff
|
||||
palette = 1=#d11500
|
||||
palette = 2=#008b0c
|
||||
palette = 3=#997b00
|
||||
palette = 4=#0057d1
|
||||
palette = 5=#a018ff
|
||||
palette = 6=#008c99
|
||||
palette = 7=#16181a
|
||||
palette = 8=#acacac
|
||||
palette = 9=#d11500
|
||||
palette = 10=#008b0c
|
||||
palette = 11=#997b00
|
||||
palette = 12=#0057d1
|
||||
palette = 13=#a018ff
|
||||
palette = 14=#008c99
|
||||
palette = 15=#16181a
|
||||
|
||||
background = #ffffff
|
||||
foreground = #16181a
|
||||
cursor-color = #16181a
|
||||
selection-background = #acacac
|
||||
selection-foreground = #16181a
|
||||
23
dot_config/ghostty/themes/cyberpunk
Normal file
23
dot_config/ghostty/themes/cyberpunk
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# cyberpunk theme for ghostty
|
||||
palette = 0=#000000
|
||||
palette = 1=#ff0055
|
||||
palette = 2=#00ff9f
|
||||
palette = 3=#f3e600
|
||||
palette = 4=#00baff
|
||||
palette = 5=#ff00ff
|
||||
palette = 6=#00ffff
|
||||
palette = 7=#e0e0e0
|
||||
palette = 8=#555555
|
||||
palette = 9=#ff5585
|
||||
palette = 10=#55ffbf
|
||||
palette = 11=#ffff55
|
||||
palette = 12=#55ccff
|
||||
palette = 13=#ff55ff
|
||||
palette = 14=#55ffff
|
||||
palette = 15=#ffffff
|
||||
|
||||
background = #0d0d0f
|
||||
foreground = #e0e0e0
|
||||
cursor-color = #f3e600
|
||||
selection-background = #2d2d30
|
||||
selection-foreground = #ffffff
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
0
dot_config/go/telemetry/local/empty_upload.token
Normal file
0
dot_config/go/telemetry/local/empty_upload.token
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1
dot_config/go/telemetry/local/weekends
Normal file
1
dot_config/go/telemetry/local/weekends
Normal file
|
|
@ -0,0 +1 @@
|
|||
6
|
||||
0
dot_config/go/telemetry/upload/.keep
Normal file
0
dot_config/go/telemetry/upload/.keep
Normal file
29
dot_config/themes/executable_fzf-challengerdeep.sh
Normal file
29
dot_config/themes/executable_fzf-challengerdeep.sh
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env sh
|
||||
# Challenger Deep theme for fzf
|
||||
# Palette: https://github.com/challenger-deep-theme/themes
|
||||
#
|
||||
# Two ways to use this file:
|
||||
#
|
||||
# 1. Source it from ~/.zshrc AFTER your existing FZF_DEFAULT_OPTS line:
|
||||
# export FZF_DEFAULT_OPTS='--height 40% --layout=reverse --border'
|
||||
# . ~/.config/themes/fzf-challengerdeep.sh
|
||||
# The snippet appends --color=... to whatever FZF_DEFAULT_OPTS already holds,
|
||||
# so your existing flags are preserved.
|
||||
#
|
||||
# 2. Or copy the FZF_CHALLENGERDEEP_COLORS value below and paste it directly
|
||||
# into your FZF_DEFAULT_OPTS string.
|
||||
#
|
||||
# bg and gutter are -1 (transparent) so the theme inherits your terminal bg —
|
||||
# replace with #1b182c if you want the theme to be self-contained.
|
||||
|
||||
FZF_CHALLENGERDEEP_COLORS='--color='\
|
||||
'fg:#cbe3e7,bg:-1,hl:#ffe9aa,'\
|
||||
'fg+:#cbe3e7,bg+:#3b3470,hl+:#ffb378,'\
|
||||
'gutter:-1,'\
|
||||
'border:#3b3470,separator:#3b3470,scrollbar:#3b3470,label:#a6b3cc,'\
|
||||
'info:#a6b3cc,prompt:#906cff,pointer:#c991e1,marker:#62d196,'\
|
||||
'spinner:#906cff,header:#63f2f1,query:#cbe3e7,disabled:#5a5475,'\
|
||||
'preview-fg:#cbe3e7,preview-bg:-1,preview-border:#3b3470,'\
|
||||
'preview-scrollbar:#3b3470,preview-label:#a6b3cc'
|
||||
|
||||
export FZF_DEFAULT_OPTS="${FZF_DEFAULT_OPTS:+$FZF_DEFAULT_OPTS }$FZF_CHALLENGERDEEP_COLORS"
|
||||
580
dot_config/zellij/config.kdl
Normal file
580
dot_config/zellij/config.kdl
Normal file
|
|
@ -0,0 +1,580 @@
|
|||
keybinds clear-defaults=true {
|
||||
locked {
|
||||
bind "Ctrl g" { SwitchToMode "normal"; }
|
||||
}
|
||||
pane {
|
||||
bind "left" { MoveFocus "left"; }
|
||||
bind "down" { MoveFocus "down"; }
|
||||
bind "up" { MoveFocus "up"; }
|
||||
bind "right" { MoveFocus "right"; }
|
||||
bind "c" { SwitchToMode "renamepane"; PaneNameInput 0; }
|
||||
bind "d" { NewPane "down"; SwitchToMode "normal"; }
|
||||
bind "e" { TogglePaneEmbedOrFloating; SwitchToMode "normal"; }
|
||||
bind "f" { ToggleFocusFullscreen; SwitchToMode "normal"; }
|
||||
bind "h" { MoveFocus "left"; }
|
||||
bind "i" { TogglePanePinned; SwitchToMode "normal"; }
|
||||
bind "j" { MoveFocus "down"; }
|
||||
bind "k" { MoveFocus "up"; }
|
||||
bind "l" { MoveFocus "right"; }
|
||||
bind "n" { NewPane; SwitchToMode "normal"; }
|
||||
bind "p" { SwitchFocus; }
|
||||
bind "Ctrl p" { SwitchToMode "normal"; }
|
||||
bind "r" { NewPane "right"; SwitchToMode "normal"; }
|
||||
bind "s" { NewPane "stacked"; SwitchToMode "normal"; }
|
||||
bind "w" { ToggleFloatingPanes; SwitchToMode "normal"; }
|
||||
bind "z" { TogglePaneFrames; SwitchToMode "normal"; }
|
||||
}
|
||||
tab {
|
||||
bind "left" { GoToPreviousTab; }
|
||||
bind "down" { GoToNextTab; }
|
||||
bind "up" { GoToPreviousTab; }
|
||||
bind "right" { GoToNextTab; }
|
||||
bind "1" { GoToTab 1; SwitchToMode "normal"; }
|
||||
bind "2" { GoToTab 2; SwitchToMode "normal"; }
|
||||
bind "3" { GoToTab 3; SwitchToMode "normal"; }
|
||||
bind "4" { GoToTab 4; SwitchToMode "normal"; }
|
||||
bind "5" { GoToTab 5; SwitchToMode "normal"; }
|
||||
bind "6" { GoToTab 6; SwitchToMode "normal"; }
|
||||
bind "7" { GoToTab 7; SwitchToMode "normal"; }
|
||||
bind "8" { GoToTab 8; SwitchToMode "normal"; }
|
||||
bind "9" { GoToTab 9; SwitchToMode "normal"; }
|
||||
bind "[" { BreakPaneLeft; SwitchToMode "normal"; }
|
||||
bind "]" { BreakPaneRight; SwitchToMode "normal"; }
|
||||
bind "b" { BreakPane; SwitchToMode "normal"; }
|
||||
bind "h" { GoToPreviousTab; }
|
||||
bind "j" { GoToNextTab; }
|
||||
bind "k" { GoToPreviousTab; }
|
||||
bind "l" { GoToNextTab; }
|
||||
bind "n" { NewTab; SwitchToMode "normal"; }
|
||||
bind "r" { SwitchToMode "renametab"; TabNameInput 0; }
|
||||
bind "s" { ToggleActiveSyncTab; SwitchToMode "normal"; }
|
||||
bind "Ctrl t" { SwitchToMode "normal"; }
|
||||
bind "x" { CloseTab; SwitchToMode "normal"; }
|
||||
bind "tab" { ToggleTab; }
|
||||
}
|
||||
resize {
|
||||
bind "left" { Resize "Increase left"; }
|
||||
bind "down" { Resize "Increase down"; }
|
||||
bind "up" { Resize "Increase up"; }
|
||||
bind "right" { Resize "Increase right"; }
|
||||
bind "+" { Resize "Increase"; }
|
||||
bind "-" { Resize "Decrease"; }
|
||||
bind "=" { Resize "Increase"; }
|
||||
bind "H" { Resize "Decrease left"; }
|
||||
bind "J" { Resize "Decrease down"; }
|
||||
bind "K" { Resize "Decrease up"; }
|
||||
bind "L" { Resize "Decrease right"; }
|
||||
bind "h" { Resize "Increase left"; }
|
||||
bind "j" { Resize "Increase down"; }
|
||||
bind "k" { Resize "Increase up"; }
|
||||
bind "l" { Resize "Increase right"; }
|
||||
bind "Ctrl n" { SwitchToMode "normal"; }
|
||||
}
|
||||
move {
|
||||
bind "left" { MovePane "left"; }
|
||||
bind "down" { MovePane "down"; }
|
||||
bind "up" { MovePane "up"; }
|
||||
bind "right" { MovePane "right"; }
|
||||
bind "h" { MovePane "left"; }
|
||||
bind "Ctrl h" { SwitchToMode "normal"; }
|
||||
bind "j" { MovePane "down"; }
|
||||
bind "k" { MovePane "up"; }
|
||||
bind "l" { MovePane "right"; }
|
||||
bind "n" { MovePane; }
|
||||
bind "p" { MovePaneBackwards; }
|
||||
bind "tab" { MovePane; }
|
||||
}
|
||||
scroll {
|
||||
bind "e" { EditScrollback; SwitchToMode "normal"; }
|
||||
bind "s" { SwitchToMode "entersearch"; SearchInput 0; }
|
||||
}
|
||||
search {
|
||||
bind "c" { SearchToggleOption "CaseSensitivity"; }
|
||||
bind "n" { Search "down"; }
|
||||
bind "o" { SearchToggleOption "WholeWord"; }
|
||||
bind "p" { Search "up"; }
|
||||
bind "w" { SearchToggleOption "Wrap"; }
|
||||
}
|
||||
session {
|
||||
bind "a" {
|
||||
LaunchOrFocusPlugin "zellij:about" {
|
||||
floating true
|
||||
move_to_focused_tab true
|
||||
}
|
||||
SwitchToMode "normal"
|
||||
}
|
||||
bind "c" {
|
||||
LaunchOrFocusPlugin "configuration" {
|
||||
floating true
|
||||
move_to_focused_tab true
|
||||
}
|
||||
SwitchToMode "normal"
|
||||
}
|
||||
bind "l" {
|
||||
LaunchOrFocusPlugin "zellij:layout-manager" {
|
||||
floating true
|
||||
move_to_focused_tab true
|
||||
}
|
||||
SwitchToMode "normal"
|
||||
}
|
||||
bind "Ctrl o" { SwitchToMode "normal"; }
|
||||
bind "p" {
|
||||
LaunchOrFocusPlugin "plugin-manager" {
|
||||
floating true
|
||||
move_to_focused_tab true
|
||||
}
|
||||
SwitchToMode "normal"
|
||||
}
|
||||
bind "s" {
|
||||
LaunchOrFocusPlugin "zellij:share" {
|
||||
floating true
|
||||
move_to_focused_tab true
|
||||
}
|
||||
SwitchToMode "normal"
|
||||
}
|
||||
bind "w" {
|
||||
LaunchOrFocusPlugin "session-manager" {
|
||||
floating true
|
||||
move_to_focused_tab true
|
||||
}
|
||||
SwitchToMode "normal"
|
||||
}
|
||||
}
|
||||
shared_except "locked" {
|
||||
bind "Alt left" { MoveFocusOrTab "left"; }
|
||||
bind "Alt down" { MoveFocus "down"; }
|
||||
bind "Alt up" { MoveFocus "up"; }
|
||||
bind "Alt right" { MoveFocusOrTab "right"; }
|
||||
bind "Alt +" { Resize "Increase"; }
|
||||
bind "Alt -" { Resize "Decrease"; }
|
||||
bind "Alt =" { Resize "Increase"; }
|
||||
bind "Alt [" { PreviousSwapLayout; }
|
||||
bind "Alt ]" { NextSwapLayout; }
|
||||
bind "Alt f" { ToggleFloatingPanes; }
|
||||
bind "Ctrl g" { SwitchToMode "locked"; }
|
||||
bind "Alt h" { MoveFocusOrTab "left"; }
|
||||
bind "Alt i" { MoveTab "left"; }
|
||||
bind "Alt j" { MoveFocus "down"; }
|
||||
bind "Alt k" { MoveFocus "up"; }
|
||||
bind "Alt l" { MoveFocusOrTab "right"; }
|
||||
bind "Alt n" { NewPane; }
|
||||
bind "Alt o" { MoveTab "right"; }
|
||||
bind "Alt p" { TogglePaneInGroup; }
|
||||
bind "Alt Shift p" { ToggleGroupMarking; }
|
||||
bind "Ctrl q" { Quit; }
|
||||
}
|
||||
shared_except "locked" "move" {
|
||||
bind "Ctrl h" { SwitchToMode "move"; }
|
||||
}
|
||||
shared_except "locked" "session" {
|
||||
bind "Ctrl o" { SwitchToMode "session"; }
|
||||
}
|
||||
shared_except "locked" "scroll" "search" "tmux" {
|
||||
bind "Ctrl b" { SwitchToMode "tmux"; }
|
||||
}
|
||||
shared_except "locked" "scroll" "search" {
|
||||
bind "Ctrl s" { SwitchToMode "scroll"; }
|
||||
}
|
||||
shared_except "locked" "tab" {
|
||||
bind "Ctrl t" { SwitchToMode "tab"; }
|
||||
}
|
||||
shared_except "locked" "pane" {
|
||||
bind "Ctrl p" { SwitchToMode "pane"; }
|
||||
}
|
||||
shared_except "locked" "resize" {
|
||||
bind "Ctrl n" { SwitchToMode "resize"; }
|
||||
}
|
||||
shared_except "normal" "locked" "entersearch" {
|
||||
bind "enter" { SwitchToMode "normal"; }
|
||||
}
|
||||
shared_except "normal" "locked" "entersearch" "renametab" "renamepane" {
|
||||
bind "esc" { SwitchToMode "normal"; }
|
||||
}
|
||||
shared_among "pane" "tmux" {
|
||||
bind "x" { CloseFocus; SwitchToMode "normal"; }
|
||||
}
|
||||
shared_among "scroll" "search" {
|
||||
bind "PageDown" { PageScrollDown; }
|
||||
bind "PageUp" { PageScrollUp; }
|
||||
bind "left" { PageScrollUp; }
|
||||
bind "down" { ScrollDown; }
|
||||
bind "up" { ScrollUp; }
|
||||
bind "right" { PageScrollDown; }
|
||||
bind "Ctrl b" { PageScrollUp; }
|
||||
bind "Ctrl c" { ScrollToBottom; SwitchToMode "normal"; }
|
||||
bind "d" { HalfPageScrollDown; }
|
||||
bind "Ctrl f" { PageScrollDown; }
|
||||
bind "h" { PageScrollUp; }
|
||||
bind "j" { ScrollDown; }
|
||||
bind "k" { ScrollUp; }
|
||||
bind "l" { PageScrollDown; }
|
||||
bind "Ctrl s" { SwitchToMode "normal"; }
|
||||
bind "u" { HalfPageScrollUp; }
|
||||
}
|
||||
entersearch {
|
||||
bind "Ctrl c" { SwitchToMode "scroll"; }
|
||||
bind "esc" { SwitchToMode "scroll"; }
|
||||
bind "enter" { SwitchToMode "search"; }
|
||||
}
|
||||
renametab {
|
||||
bind "esc" { UndoRenameTab; SwitchToMode "tab"; }
|
||||
}
|
||||
shared_among "renametab" "renamepane" {
|
||||
bind "Ctrl c" { SwitchToMode "normal"; }
|
||||
}
|
||||
renamepane {
|
||||
bind "esc" { UndoRenamePane; SwitchToMode "pane"; }
|
||||
}
|
||||
shared_among "session" "tmux" {
|
||||
bind "d" { Detach; }
|
||||
}
|
||||
tmux {
|
||||
bind "left" { MoveFocus "left"; SwitchToMode "normal"; }
|
||||
bind "down" { MoveFocus "down"; SwitchToMode "normal"; }
|
||||
bind "up" { MoveFocus "up"; SwitchToMode "normal"; }
|
||||
bind "right" { MoveFocus "right"; SwitchToMode "normal"; }
|
||||
bind "space" { NextSwapLayout; }
|
||||
bind "\"" { NewPane "down"; SwitchToMode "normal"; }
|
||||
bind "%" { NewPane "right"; SwitchToMode "normal"; }
|
||||
bind "," { SwitchToMode "renametab"; }
|
||||
bind "[" { SwitchToMode "scroll"; }
|
||||
bind "Ctrl b" { Write 2; SwitchToMode "normal"; }
|
||||
bind "c" { NewTab; SwitchToMode "normal"; }
|
||||
bind "h" { MoveFocus "left"; SwitchToMode "normal"; }
|
||||
bind "j" { MoveFocus "down"; SwitchToMode "normal"; }
|
||||
bind "k" { MoveFocus "up"; SwitchToMode "normal"; }
|
||||
bind "l" { MoveFocus "right"; SwitchToMode "normal"; }
|
||||
bind "n" { GoToNextTab; SwitchToMode "normal"; }
|
||||
bind "o" { FocusNextPane; }
|
||||
bind "p" { GoToPreviousTab; SwitchToMode "normal"; }
|
||||
bind "z" { ToggleFocusFullscreen; SwitchToMode "normal"; }
|
||||
}
|
||||
}
|
||||
|
||||
// Plugin aliases - can be used to change the implementation of Zellij
|
||||
// changing these requires a restart to take effect
|
||||
plugins {
|
||||
about location="zellij:about"
|
||||
compact-bar location="zellij:compact-bar"
|
||||
configuration location="zellij:configuration"
|
||||
filepicker location="zellij:strider" {
|
||||
cwd "/"
|
||||
}
|
||||
plugin-manager location="zellij:plugin-manager"
|
||||
session-manager location="zellij:session-manager"
|
||||
status-bar location="zellij:status-bar"
|
||||
strider location="zellij:strider"
|
||||
tab-bar location="zellij:tab-bar"
|
||||
welcome-screen location="zellij:session-manager" {
|
||||
welcome_screen true
|
||||
}
|
||||
}
|
||||
|
||||
// Plugins to load in the background when a new session starts
|
||||
// eg. "file:/path/to/my-plugin.wasm"
|
||||
// eg. "https://example.com/my-plugin.wasm"
|
||||
load_plugins {
|
||||
zellij:link
|
||||
}
|
||||
web_client {
|
||||
font "monospace"
|
||||
}
|
||||
|
||||
// Use a simplified UI without special fonts (arrow glyphs)
|
||||
// Options:
|
||||
// - true
|
||||
// - false (Default)
|
||||
//
|
||||
// simplified_ui true
|
||||
|
||||
// Enable OSC8 hyperlink output
|
||||
// Options:
|
||||
// - true (Default)
|
||||
// - false
|
||||
//
|
||||
// osc8_hyperlinks true
|
||||
|
||||
// Choose the theme that is specified in the themes section.
|
||||
// Default: default
|
||||
//
|
||||
// theme "dracula"
|
||||
theme "tokyo-night"
|
||||
// Theme to use when the host terminal reports a dark color palette.
|
||||
// Requires `theme_light` to also be set; otherwise `theme` is used.
|
||||
//
|
||||
// theme_dark "dracula"
|
||||
|
||||
// Theme to use when the host terminal reports a light color palette.
|
||||
// Requires `theme_dark` to also be set; otherwise `theme` is used.
|
||||
//
|
||||
// theme_light "solarized-light"
|
||||
|
||||
// Choose the base input mode of zellij.
|
||||
// Default: normal
|
||||
//
|
||||
// default_mode "locked"
|
||||
|
||||
// Choose the path to the default shell that zellij will use for opening new panes
|
||||
// Default: $SHELL
|
||||
//
|
||||
// default_shell "fish"
|
||||
|
||||
// Choose the path to override cwd that zellij will use for opening new panes
|
||||
//
|
||||
// default_cwd "/tmp"
|
||||
|
||||
// The name of the default layout to load on startup
|
||||
// Default: "default"
|
||||
//
|
||||
// default_layout "compact"
|
||||
|
||||
// The folder in which Zellij will look for layouts
|
||||
// (Requires restart)
|
||||
//
|
||||
// layout_dir "/tmp"
|
||||
|
||||
// The folder in which Zellij will look for themes
|
||||
// (Requires restart)
|
||||
//
|
||||
// theme_dir "/tmp"
|
||||
|
||||
// Toggle enabling the mouse mode.
|
||||
// On certain configurations, or terminals this could
|
||||
// potentially interfere with copying text.
|
||||
// Options:
|
||||
// - true (default)
|
||||
// - false
|
||||
//
|
||||
// mouse_mode false
|
||||
|
||||
// Toggle having pane frames around the panes
|
||||
// Options:
|
||||
// - true (default, enabled)
|
||||
// - false
|
||||
//
|
||||
// pane_frames false
|
||||
|
||||
// When attaching to an existing session with other users,
|
||||
// should the session be mirrored (true)
|
||||
// or should each user have their own cursor (false)
|
||||
// (Requires restart)
|
||||
// Default: false
|
||||
//
|
||||
// mirror_session true
|
||||
|
||||
// Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP
|
||||
// eg. when terminal window with an active zellij session is closed
|
||||
// (Requires restart)
|
||||
// Options:
|
||||
// - detach (Default)
|
||||
// - quit
|
||||
//
|
||||
// on_force_close "quit"
|
||||
|
||||
// Configure the scroll back buffer size
|
||||
// This is the number of lines zellij stores for each pane in the scroll back
|
||||
// buffer. Excess number of lines are discarded in a FIFO fashion.
|
||||
// (Requires restart)
|
||||
// Valid values: positive integers
|
||||
// Default value: 10000
|
||||
//
|
||||
// scroll_buffer_size 10000
|
||||
|
||||
// Provide a command to execute when copying text. The text will be piped to
|
||||
// the stdin of the program to perform the copy. This can be used with
|
||||
// terminal emulators which do not support the OSC 52 ANSI control sequence
|
||||
// that will be used by default if this option is not set.
|
||||
// Examples:
|
||||
//
|
||||
// copy_command "xclip -selection clipboard" // x11
|
||||
// copy_command "wl-copy" // wayland
|
||||
// copy_command "pbcopy" // osx
|
||||
//
|
||||
// copy_command "pbcopy"
|
||||
|
||||
// Choose the destination for copied text
|
||||
// Allows using the primary selection buffer (on x11/wayland) instead of the system clipboard.
|
||||
// Does not apply when using copy_command.
|
||||
// Options:
|
||||
// - system (default)
|
||||
// - primary
|
||||
//
|
||||
// copy_clipboard "primary"
|
||||
|
||||
// Enable automatic copying (and clearing) of selection when releasing mouse
|
||||
// Default: true
|
||||
//
|
||||
// copy_on_select true
|
||||
|
||||
// Path to the default editor to use to edit pane scrollbuffer
|
||||
// Default: $EDITOR or $VISUAL
|
||||
// scrollback_editor "/usr/bin/vim"
|
||||
|
||||
// A fixed name to always give the Zellij session.
|
||||
// Consider also setting `attach_to_session true,`
|
||||
// otherwise this will error if such a session exists.
|
||||
// Default: <RANDOM>
|
||||
//
|
||||
// session_name "My singleton session"
|
||||
|
||||
// When `session_name` is provided, attaches to that session
|
||||
// if it is already running or creates it otherwise.
|
||||
// Default: false
|
||||
//
|
||||
// attach_to_session true
|
||||
|
||||
// Toggle between having Zellij lay out panes according to a predefined set of layouts whenever possible
|
||||
// Options:
|
||||
// - true (default)
|
||||
// - false
|
||||
//
|
||||
// auto_layout false
|
||||
|
||||
// Whether sessions should be serialized to the cache folder (including their tabs/panes, cwds and running commands) so that they can later be resurrected
|
||||
// Options:
|
||||
// - true (default)
|
||||
// - false
|
||||
//
|
||||
// session_serialization false
|
||||
|
||||
// Whether pane viewports are serialized along with the session, default is false
|
||||
// Options:
|
||||
// - true
|
||||
// - false (default)
|
||||
//
|
||||
// serialize_pane_viewport false
|
||||
|
||||
// Scrollback lines to serialize along with the pane viewport when serializing sessions, 0
|
||||
// defaults to the scrollback size. If this number is higher than the scrollback size, it will
|
||||
// also default to the scrollback size. This does nothing if `serialize_pane_viewport` is not true.
|
||||
//
|
||||
// scrollback_lines_to_serialize 10000
|
||||
|
||||
// Enable or disable the rendering of styled and colored underlines (undercurl).
|
||||
// May need to be disabled for certain unsupported terminals
|
||||
// (Requires restart)
|
||||
// Default: true
|
||||
//
|
||||
// styled_underlines false
|
||||
|
||||
// How often in seconds sessions are serialized
|
||||
//
|
||||
// serialization_interval 10000
|
||||
|
||||
// Enable or disable writing of session metadata to disk (if disabled, other sessions might not know
|
||||
// metadata info on this session)
|
||||
// (Requires restart)
|
||||
// Default: false
|
||||
//
|
||||
// disable_session_metadata false
|
||||
|
||||
// Enable or disable support for the enhanced Kitty Keyboard Protocol (the host terminal must also support it)
|
||||
// (Requires restart)
|
||||
// Default: true (if the host terminal supports it)
|
||||
//
|
||||
// support_kitty_keyboard_protocol false
|
||||
// Whether to make sure a local web server is running when a new Zellij session starts.
|
||||
// This web server will allow creating new sessions and attaching to existing ones that have
|
||||
// opted in to being shared in the browser.
|
||||
// When enabled, navigate to http://127.0.0.1:8082
|
||||
// (Requires restart)
|
||||
//
|
||||
// Note: a local web server can still be manually started from within a Zellij session or from the CLI.
|
||||
// If this is not desired, one can use a version of Zellij compiled without
|
||||
// `web_server_capability`
|
||||
//
|
||||
// Possible values:
|
||||
// - true
|
||||
// - false
|
||||
// Default: false
|
||||
//
|
||||
// web_server false
|
||||
// Whether to allow sessions started in the terminal to be shared through a local web server, assuming one is
|
||||
// running (see the `web_server` option for more details).
|
||||
// (Requires restart)
|
||||
//
|
||||
// Note: This is an administrative separation and not intended as a security measure.
|
||||
//
|
||||
// Possible values:
|
||||
// - "on" (allow web sharing through the local web server if it
|
||||
// is online)
|
||||
// - "off" (do not allow web sharing unless sessions explicitly opt-in to it)
|
||||
// - "disabled" (do not allow web sharing and do not permit sessions started in the terminal to opt-in to it)
|
||||
// Default: "off"
|
||||
//
|
||||
// web_sharing "off"
|
||||
// A path to a certificate file to be used when setting up the web client to serve the
|
||||
// connection over HTTPs
|
||||
//
|
||||
// web_server_cert "/path/to/cert.pem"
|
||||
// A path to a key file to be used when setting up the web client to serve the
|
||||
// connection over HTTPs
|
||||
//
|
||||
// web_server_key "/path/to/key.pem"
|
||||
/// Whether to enforce https connections to the web server when it is bound to localhost
|
||||
/// (127.0.0.0/8)
|
||||
///
|
||||
/// Note: https is ALWAYS enforced when bound to non-local interfaces
|
||||
///
|
||||
/// Default: false
|
||||
//
|
||||
// enforce_https_for_localhost false
|
||||
|
||||
// Whether to stack panes when resizing beyond a certain size
|
||||
// Default: true
|
||||
//
|
||||
// stacked_resize false
|
||||
|
||||
// Whether to show tips on startup
|
||||
// Default: true
|
||||
//
|
||||
// show_startup_tips false
|
||||
|
||||
// Whether to show release notes on first version run
|
||||
// Default: true
|
||||
//
|
||||
// show_release_notes false
|
||||
|
||||
// Whether to enable mouse hover effects and pane grouping functionality
|
||||
// default is true
|
||||
// advanced_mouse_actions false
|
||||
|
||||
// Whether to enable mouse hover visual effects (frame highlight and help text)
|
||||
// default is true
|
||||
// mouse_hover_effects false
|
||||
|
||||
// Whether to show visual bell indicators (pane/tab frame flash and [!] suffix)
|
||||
// default is true
|
||||
// visual_bell true
|
||||
|
||||
// Whether to focus panes on mouse hover
|
||||
// default is false
|
||||
// focus_follows_mouse false
|
||||
|
||||
// Whether clicking a pane to focus it also sends the click into the pane
|
||||
// default is false
|
||||
// mouse_click_through false
|
||||
|
||||
// The ip address the web server should listen on when it starts
|
||||
// Default: "127.0.0.1"
|
||||
// (Requires restart)
|
||||
// web_server_ip "127.0.0.1"
|
||||
|
||||
// The port the web server should listen on when it starts
|
||||
// Default: 8082
|
||||
// (Requires restart)
|
||||
// web_server_port 8082
|
||||
|
||||
// A command to run (will be wrapped with sh -c and provided the RESURRECT_COMMAND env variable)
|
||||
// after Zellij attempts to discover a command inside a pane when resurrecting sessions, the STDOUT
|
||||
// of this command will be used instead of the discovered RESURRECT_COMMAND
|
||||
// can be useful for removing wrappers around commands
|
||||
// Note: be sure to escape backslashes and similar characters properly
|
||||
// post_command_discovery_hook "echo $RESURRECT_COMMAND | sed <your_regex_here>"
|
||||
|
||||
// Number of async worker tasks to spawn per active client.
|
||||
//
|
||||
// Allocating few tasks may result in resource contention and lags. Small values (around 4) should
|
||||
// typically work best. Set to 0 to use the number of (physical) CPU cores.
|
||||
// Note: This only applies to web clients at the moment.
|
||||
// client_async_worker_tasks 4
|
||||
90
dot_local/bin/executable_fedora-backup-home
Normal file
90
dot_local/bin/executable_fedora-backup-home
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage: fedora-backup-home DESTINATION [options]
|
||||
|
||||
Rsync your home folder to an external drive or mounted network share.
|
||||
Dry-run is the default. Add --run when the preview looks right.
|
||||
|
||||
Examples:
|
||||
fedora-backup-home /run/media/$USER/BackupDrive
|
||||
fedora-backup-home /run/media/$USER/BackupDrive --run
|
||||
fedora-backup-home /mnt/nas/backups --run --delete
|
||||
|
||||
Options:
|
||||
--run Actually copy files. Without this, rsync runs in dry-run mode.
|
||||
--delete Delete files in the backup that no longer exist in your home folder.
|
||||
-h, --help Show this help.
|
||||
USAGE
|
||||
}
|
||||
|
||||
log() { printf '\n\033[1m==> %s\033[0m\n' "$*"; }
|
||||
die() { printf '\033[31mERROR:\033[0m %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
[[ $# -gt 0 ]] || { usage; exit 1; }
|
||||
|
||||
DEST_ROOT=""
|
||||
RUN=false
|
||||
DELETE=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--run) RUN=true ;;
|
||||
--delete) DELETE=true ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
-*) die "Unknown option: $1" ;;
|
||||
*)
|
||||
if [[ -z "$DEST_ROOT" ]]; then DEST_ROOT="$1"; else die "Unexpected extra argument: $1"; fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
[[ -n "$DEST_ROOT" ]] || die "Missing DESTINATION."
|
||||
command -v rsync >/dev/null 2>&1 || die "rsync is not installed. Run: sudo dnf5 install rsync"
|
||||
[[ -d "$DEST_ROOT" ]] || die "Destination does not exist: $DEST_ROOT"
|
||||
|
||||
HOST="$(hostname -s 2>/dev/null || hostname)"
|
||||
DEST="$DEST_ROOT/${HOST}-${USER}-home"
|
||||
mkdir -p "$DEST"
|
||||
|
||||
# Prevent accidental recursive backup if destination is inside $HOME.
|
||||
case "$(realpath -m "$DEST")" in
|
||||
"$(realpath -m "$HOME")"/*) die "Destination is inside your home folder; choose an external path." ;;
|
||||
esac
|
||||
|
||||
RSYNC_OPTS=(-aAXH --human-readable --info=progress2)
|
||||
[[ "$RUN" == "false" ]] && RSYNC_OPTS+=(--dry-run --itemize-changes)
|
||||
[[ "$DELETE" == "true" ]] && RSYNC_OPTS+=(--delete)
|
||||
|
||||
EXCLUDES=(
|
||||
--exclude='/.cache/'
|
||||
--exclude='/.local/share/Trash/'
|
||||
--exclude='/.var/app/*/cache/'
|
||||
--exclude='/Downloads/*.iso'
|
||||
--exclude='/Downloads/*.img'
|
||||
--exclude='/Downloads/*.qcow2'
|
||||
--exclude='/.npm/_cacache/'
|
||||
--exclude='/.cargo/registry/'
|
||||
--exclude='/.cargo/git/'
|
||||
--exclude='/.gradle/caches/'
|
||||
--exclude='/**/node_modules/'
|
||||
--exclude='/**/.venv/'
|
||||
)
|
||||
|
||||
log "Backing up $HOME to $DEST"
|
||||
if [[ "$RUN" == "false" ]]; then
|
||||
printf 'Mode: DRY RUN. Add --run to actually copy files.\n'
|
||||
else
|
||||
printf 'Mode: REAL RUN.\n'
|
||||
fi
|
||||
[[ "$DELETE" == "true" ]] && printf 'Delete mode: enabled.\n'
|
||||
|
||||
rsync "${RSYNC_OPTS[@]}" "${EXCLUDES[@]}" "$HOME/" "$DEST/"
|
||||
|
||||
log "Done"
|
||||
if [[ "$RUN" == "false" ]]; then
|
||||
printf 'Review the dry-run above, then rerun with --run when ready.\n'
|
||||
fi
|
||||
82
dot_local/bin/executable_fedora-clean
Normal file
82
dot_local/bin/executable_fedora-clean
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage: fedora-clean [options]
|
||||
|
||||
Clean common Fedora desktop clutter.
|
||||
|
||||
Options:
|
||||
--aggressive Also clear thumbnails, browser crash dumps, and offer Podman prune.
|
||||
-y, --yes Accept this script's prompts and pass -y where possible.
|
||||
-h, --help Show this help.
|
||||
USAGE
|
||||
}
|
||||
|
||||
log() { printf '\n\033[1m==> %s\033[0m\n' "$*"; }
|
||||
warn() { printf '\033[33mWARN:\033[0m %s\n' "$*" >&2; }
|
||||
die() { printf '\033[31mERROR:\033[0m %s\n' "$*" >&2; exit 1; }
|
||||
have() { command -v "$1" >/dev/null 2>&1; }
|
||||
confirm() {
|
||||
local prompt="$1" answer
|
||||
if [[ "${ASSUME_YES}" == "true" ]]; then return 0; fi
|
||||
read -r -p "$prompt [y/N] " answer
|
||||
[[ "$answer" =~ ^[Yy]$ ]]
|
||||
}
|
||||
|
||||
DNF="$(command -v dnf5 || command -v dnf || true)"
|
||||
[[ -n "$DNF" ]] || die "Could not find dnf5 or dnf."
|
||||
|
||||
AGGRESSIVE=false
|
||||
ASSUME_YES=false
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--aggressive) AGGRESSIVE=true ;;
|
||||
-y|--yes) ASSUME_YES=true ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) die "Unknown option: $1" ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
YUM_YES=()
|
||||
[[ "$ASSUME_YES" == "true" ]] && YUM_YES=(-y)
|
||||
|
||||
log "Disk usage before cleanup"
|
||||
df -hT -x tmpfs -x devtmpfs / "$HOME" 2>/dev/null || df -hT -x tmpfs -x devtmpfs
|
||||
|
||||
log "Removing unused RPM packages"
|
||||
sudo "$DNF" autoremove "${YUM_YES[@]}" || warn "DNF autoremove did not complete. Review the output above."
|
||||
|
||||
log "Cleaning downloaded DNF packages"
|
||||
sudo "$DNF" clean packages || warn "DNF clean packages failed."
|
||||
|
||||
if have flatpak; then
|
||||
log "Removing unused Flatpak runtimes"
|
||||
flatpak uninstall --unused "${YUM_YES[@]}" || warn "Flatpak unused-runtime cleanup did not complete."
|
||||
fi
|
||||
|
||||
if have journalctl; then
|
||||
log "Current journal disk usage"
|
||||
journalctl --disk-usage || true
|
||||
if confirm "Vacuum systemd journal to 14 days?"; then
|
||||
sudo journalctl --vacuum-time=14d
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$AGGRESSIVE" == "true" ]]; then
|
||||
log "Aggressive user-cache cleanup"
|
||||
if confirm "Clear GNOME thumbnail cache?"; then
|
||||
rm -rf -- "$HOME/.cache/thumbnails"/* 2>/dev/null || true
|
||||
fi
|
||||
if confirm "Clear user crash-report cache under ~/.cache/abrt?"; then
|
||||
rm -rf -- "$HOME/.cache/abrt"/* 2>/dev/null || true
|
||||
fi
|
||||
if have podman && confirm "Prune unused Podman images/containers/networks?"; then
|
||||
podman system prune -a
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Disk usage after cleanup"
|
||||
df -hT -x tmpfs -x devtmpfs / "$HOME" 2>/dev/null || df -hT -x tmpfs -x devtmpfs
|
||||
20
dot_local/bin/executable_fedora-reset-audio
Normal file
20
dot_local/bin/executable_fedora-reset-audio
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage: fedora-reset-audio
|
||||
|
||||
Restart the common Fedora Workstation audio user services:
|
||||
pipewire, pipewire-pulse, wireplumber
|
||||
|
||||
Useful when Bluetooth/audio devices disappear or sound gets weird.
|
||||
USAGE
|
||||
}
|
||||
|
||||
[[ "${1:-}" == "-h" || "${1:-}" == "--help" ]] && { usage; exit 0; }
|
||||
|
||||
printf '\nRestarting audio user services...\n'
|
||||
systemctl --user restart pipewire pipewire-pulse wireplumber
|
||||
printf '\nStatus:\n'
|
||||
systemctl --user --no-pager --full status pipewire pipewire-pulse wireplumber || true
|
||||
108
dot_local/bin/executable_fedora-update
Normal file
108
dot_local/bin/executable_fedora-update
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage: fedora-update [options]
|
||||
|
||||
Update Fedora RPM packages, Flatpaks, and firmware.
|
||||
|
||||
Options:
|
||||
--offline Prepare the DNF transaction as an offline update, then ask before rebooting.
|
||||
--no-flatpak Skip Flatpak updates.
|
||||
--no-firmware Skip fwupd firmware checks/updates.
|
||||
-y, --yes Pass -y to DNF/Flatpak where possible and accept prompts from this script.
|
||||
-h, --help Show this help.
|
||||
USAGE
|
||||
}
|
||||
|
||||
log() { printf '\n\033[1m==> %s\033[0m\n' "$*"; }
|
||||
warn() { printf '\033[33mWARN:\033[0m %s\n' "$*" >&2; }
|
||||
die() { printf '\033[31mERROR:\033[0m %s\n' "$*" >&2; exit 1; }
|
||||
have() { command -v "$1" >/dev/null 2>&1; }
|
||||
confirm() {
|
||||
local prompt="$1" answer
|
||||
if [[ "${ASSUME_YES}" == "true" ]]; then return 0; fi
|
||||
read -r -p "$prompt [y/N] " answer
|
||||
[[ "$answer" =~ ^[Yy]$ ]]
|
||||
}
|
||||
|
||||
DNF="$(command -v dnf5 || command -v dnf || true)"
|
||||
[[ -n "$DNF" ]] || die "Could not find dnf5 or dnf."
|
||||
|
||||
OFFLINE=false
|
||||
DO_FLATPAK=true
|
||||
DO_FIRMWARE=true
|
||||
ASSUME_YES=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--offline) OFFLINE=true ;;
|
||||
--no-flatpak) DO_FLATPAK=false ;;
|
||||
--no-firmware) DO_FIRMWARE=false ;;
|
||||
-y|--yes) ASSUME_YES=true ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) die "Unknown option: $1" ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
YUM_YES=()
|
||||
[[ "$ASSUME_YES" == "true" ]] && YUM_YES=(-y)
|
||||
|
||||
log "Refreshing and updating RPM packages with $(basename "$DNF")"
|
||||
if [[ "$OFFLINE" == "true" ]]; then
|
||||
sudo "$DNF" upgrade --refresh --offline "${YUM_YES[@]}"
|
||||
log "DNF offline transaction prepared"
|
||||
else
|
||||
sudo "$DNF" upgrade --refresh "${YUM_YES[@]}"
|
||||
fi
|
||||
|
||||
if [[ "$DO_FLATPAK" == "true" ]]; then
|
||||
if have flatpak; then
|
||||
log "Updating Flatpaks"
|
||||
flatpak update "${YUM_YES[@]}"
|
||||
log "Removing unused Flatpak runtimes"
|
||||
flatpak uninstall --unused "${YUM_YES[@]}" || true
|
||||
else
|
||||
warn "flatpak not found; skipping Flatpak updates."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$DO_FIRMWARE" == "true" ]]; then
|
||||
if have fwupdmgr; then
|
||||
log "Checking firmware updates with fwupd"
|
||||
sudo fwupdmgr refresh --force || warn "fwupdmgr refresh failed; continuing."
|
||||
sudo fwupdmgr get-updates || true
|
||||
if confirm "Run firmware updates now?"; then
|
||||
sudo fwupdmgr update || warn "Firmware update command returned a non-zero status."
|
||||
fi
|
||||
else
|
||||
warn "fwupdmgr not found; install fwupd to manage firmware updates."
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Checking whether a reboot is recommended"
|
||||
NEEDS_RESTARTING_OUTPUT="$(mktemp)"
|
||||
set +e
|
||||
sudo "$DNF" needs-restarting >"$NEEDS_RESTARTING_OUTPUT" 2>&1
|
||||
status=$?
|
||||
set -e
|
||||
|
||||
if [[ $status -eq 0 ]]; then
|
||||
printf 'No reboot required according to dnf needs-restarting.\n'
|
||||
elif grep -qiE 'No such command|unknown command|unrecognized|Unable to resolve|not found' "$NEEDS_RESTARTING_OUTPUT"; then
|
||||
warn "Could not run '$(basename "$DNF") needs-restarting'. Try: sudo $DNF install dnf5-plugins"
|
||||
else
|
||||
cat "$NEEDS_RESTARTING_OUTPUT"
|
||||
warn "A reboot is recommended."
|
||||
fi
|
||||
rm -f "$NEEDS_RESTARTING_OUTPUT"
|
||||
|
||||
if [[ "$OFFLINE" == "true" ]]; then
|
||||
if confirm "Reboot now to run the offline DNF transaction?"; then
|
||||
sudo "$DNF" offline reboot
|
||||
else
|
||||
printf 'Run this later to apply it: sudo %s offline reboot\n' "$DNF"
|
||||
fi
|
||||
fi
|
||||
8
dot_zshrc
Normal file
8
dot_zshrc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# fzf: fuzzy completion + key bindings (Ctrl-T, Ctrl-R, Alt-C)
|
||||
if command -v fzf >/dev/null 2>&1; then
|
||||
eval "$(fzf --zsh)"
|
||||
fi
|
||||
|
||||
eval "$(/home/mr0xb/.local/bin/mise activate zsh)"
|
||||
# starship prompt
|
||||
eval "$(starship init zsh)"
|
||||
Loading…
Reference in a new issue