feat: violet-chaton v2 — palette originale, kitty, AGS, Maple Mono NF

Refonte complete du rice. Palette 100% originale (Mitsuri Kanroji inspired),
zero emprunt Dracula/Catppuccin. 50 fichiers, 3200+ lignes.

Palette v2:
- palette.sh source de verite unique (dark + light)
- 5 accents (magenta, lilac, mitsuri, lavande, champagne)
- 4 semantiques derivees, 4 niveaux texte, 6 fonds
- Gradient signature: magenta → lilac → lavande → mitsuri
- Variante Light: fonds lavande, accents assombris WCAG

Terminal:
- kitty (remplace COSMIC Term comme principal)
- Maple Mono NF (cursive italics, ligatures)
- Cursor trail magenta, splits/layouts tiling, undercurl
- Vi-mode zsh avec cursor shape adaptatif

Shell:
- starship 3 lignes (palette nommee, brain_name, battery, sudo)
- zshrc v2 (nouveaux outils, fzf pimp, shell functions, vi-mode)
- Commandes custom: proj, glog, fkill, colors, hotkeys, weather, y

Desktop:
- AGS config (bar 3-pills, OSD gradient, launcher, notifications)
- COSMIC Dark + Light v2 (7 fichiers RON chacun)
- COSMIC Term v2 (color schemes dark/light, Maple Mono NF)
- GTK3/GTK4 dark + light css
- Vivaldi theme v2

Outils:
- +kitty +dust +procs +tokei +sd +hyperfine +gping +Maple Mono NF
- Propagation palette sur: bat, btop, cava, yazi, lazygit, rofi,
  delta, fastfetch, atuin, ls-colors, vivaldi
- Claude Code statusline brain-aware

Docs:
- README v2 complet (palette, structure, raccourcis, commandes)
- help.md v2 (reference exhaustive)
This commit is contained in:
Tetardtek-Cortex
2026-03-26 03:57:18 +01:00
parent 7d4d54c5b8
commit 7e9d12e640
50 changed files with 3250 additions and 1633 deletions

View File

@@ -0,0 +1,34 @@
// ── violet-chaton v2 — AGS config ───────────────────────────────────────────
// Barre + OSD + Launcher + Notifications
// Modulaire : Hyprland = full, COSMIC = bar + OSD + launcher + notifs
import { Bar } from "./widgets/Bar.js";
import { OSD } from "./widgets/OSD.js";
import { Launcher } from "./widgets/Launcher.js";
import { Notifications } from "./widgets/Notifications.js";
// ── Compositor detection ────────────────────────────────────────────────────
const compositor = (() => {
const session = Utils.exec("echo $XDG_CURRENT_DESKTOP").trim();
if (session.includes("Hyprland")) return "hyprland";
if (session.includes("COSMIC")) return "cosmic";
return "unknown";
})();
print(`[violet-chaton] compositor: ${compositor}`);
// ── Windows ─────────────────────────────────────────────────────────────────
const windows = (monitor) => {
const wins = [
Bar(monitor, compositor),
OSD(monitor),
Launcher(monitor),
Notifications(monitor),
];
return wins;
};
export default {
style: `${App.configDir}/css/style.css`,
windows: windows(0).flat(),
};

View File

@@ -0,0 +1,385 @@
/* ── violet-chaton v2 — AGS stylesheet ────────────────────────────────────────
*
* Palette :
* crust #1a0e27
* base #261537
* mantle #341c4a
* surface0 #3d2454
* surface1 #493161
* surface2 #5a3875
* magenta #ff4da6 accent primaire
* lilac #c9a0ff accent secondaire
* mitsuri #9adba8 vert pastel
* lavande #a4b4ff bleu-violet
* champagne #e8c87a or chaud
* danger #f25c7a
* text #f0eaf8
* subtext1 #c4b8d4
* subtext0 #9a8fad
* muted #716686
*
* ─────────────────────────────────────────────────────────────────────────── */
/* ── Reset ───────────────────────────────────────────────────────────────── */
* {
font-family: "Maple Mono NF", "MapleMono Nerd Font", monospace;
font-size: 13px;
font-weight: bold;
}
/* ══════════════════════════════════════════════════════════════════════════
* BAR — 3 pills glassmorphism (island floating)
* ══════════════════════════════════════════════════════════════════════════ */
.bar {
background: transparent;
}
.bar .modules-left,
.bar .modules-center,
.bar .modules-right {
background: alpha(#261537, 0.88);
border-radius: 14px;
border: 3px solid alpha(#ff4da6, 0.60);
margin: 8px 4px;
padding: 0 4px;
}
.bar .modules-left:hover,
.bar .modules-center:hover,
.bar .modules-right:hover {
border-color: #ff4da6;
box-shadow: 0 4px 28px alpha(#c9a0ff, 0.18);
}
/* ── Launcher button ─────────────────────────────────────────────────────── */
.bar .launcher-btn {
color: #ff4da6;
font-size: 19px;
padding: 0 14px 0 18px;
min-width: 0;
min-height: 0;
}
.bar .launcher-btn:hover {
color: #c9a0ff;
}
/* ── Separator ───────────────────────────────────────────────────────────── */
.bar .separator {
color: alpha(#f0eaf8, 0.12);
font-size: 11px;
padding: 0 4px;
font-weight: normal;
}
/* ── Clock ───────────────────────────────────────────────────────────────── */
.bar .clock {
color: #ff4da6;
font-weight: 900;
font-size: 14px;
letter-spacing: 0.04em;
padding: 0 10px;
}
.bar .clock:hover {
color: #c9a0ff;
}
/* ── Date ────────────────────────────────────────────────────────────────── */
.bar .date {
color: #a4b4ff;
font-size: 12px;
font-weight: normal;
padding: 0 10px 0 2px;
}
/* ── System modules ──────────────────────────────────────────────────────── */
.bar .cpu { color: #a4b4ff; }
.bar .cpu.warning { color: #e8c87a; }
.bar .cpu.critical { color: #f25c7a; }
.bar .ram { color: #ff4da6; }
.bar .ram.warning { color: #e8c87a; }
.bar .ram.critical { color: #f25c7a; }
.bar .temp {
color: alpha(#a4b4ff, 0.60);
font-size: 11px;
font-weight: normal;
}
.bar .temp.warning { color: #e8c87a; }
.bar .temp.critical { color: #f25c7a; }
/* ── Network ─────────────────────────────────────────────────────────────── */
.bar .network {
color: #a4b4ff;
font-size: 11px;
font-weight: normal;
}
.bar .network.disconnected { color: #f25c7a; }
.bar .network.wifi { color: alpha(#a4b4ff, 0.80); }
/* ── Volume ──────────────────────────────────────────────────────────────── */
.bar .volume { color: #ff4da6; }
.bar .volume.muted { color: alpha(#ff4da6, 0.30); }
/* ── Battery ─────────────────────────────────────────────────────────────── */
.bar .battery { color: #ff4da6; }
.bar .battery.charging { color: #9adba8; }
.bar .battery.low { color: #f25c7a; }
.bar .battery.warning { color: #e8c87a; }
/* ── Media (MPRIS) ───────────────────────────────────────────────────────── */
.bar .media {
color: #c9a0ff;
font-size: 12px;
font-weight: normal;
padding: 0 10px;
}
.bar .media.paused {
color: alpha(#c9a0ff, 0.50);
font-style: italic;
}
/* ── Systray ─────────────────────────────────────────────────────────────── */
.bar .systray { padding: 0 8px; }
.bar .systray .passive { opacity: 0.5; }
/* ── Workspaces (Hyprland only) ──────────────────────────────────────────── */
.bar .workspaces button {
background: transparent;
color: #716686;
min-width: 24px;
min-height: 24px;
border-radius: 8px;
margin: 2px;
padding: 0;
}
.bar .workspaces button.active {
background: alpha(#ff4da6, 0.20);
color: #ff4da6;
border: 1px solid alpha(#ff4da6, 0.40);
}
.bar .workspaces button.occupied {
color: #c9a0ff;
}
.bar .workspaces button:hover {
background: alpha(#c9a0ff, 0.12);
color: #c9a0ff;
}
/* ── Power button ────────────────────────────────────────────────────────── */
.bar .power-btn {
color: #f25c7a;
font-size: 15px;
padding: 0 14px 0 8px;
min-width: 0;
min-height: 0;
}
.bar .power-btn:hover { color: #ff4da6; }
/* ── Hover global modules ────────────────────────────────────────────────── */
.bar .cpu:hover,
.bar .ram:hover,
.bar .temp:hover,
.bar .network:hover,
.bar .volume:hover,
.bar .battery:hover {
color: #c9a0ff;
}
/* ══════════════════════════════════════════════════════════════════════════
* OSD — volume / brightness overlay
* ══════════════════════════════════════════════════════════════════════════ */
.osd {
background: alpha(#261537, 0.92);
border-radius: 14px;
border: 2px solid alpha(#ff4da6, 0.40);
padding: 12px 20px;
margin: 0 0 40px 0;
}
.osd .icon {
color: #ff4da6;
font-size: 24px;
margin-right: 12px;
}
.osd progressbar trough {
background: #3d2454;
border-radius: 8px;
min-height: 8px;
min-width: 200px;
}
.osd progressbar progress {
border-radius: 8px;
min-height: 8px;
background: linear-gradient(to right, #ff4da6, #c9a0ff, #a4b4ff, #9adba8);
}
.osd .label {
color: #f0eaf8;
font-size: 12px;
margin-left: 8px;
}
/* ══════════════════════════════════════════════════════════════════════════
* LAUNCHER — app search
* ══════════════════════════════════════════════════════════════════════════ */
.launcher {
background: alpha(#1a0e27, 0.94);
border-radius: 14px;
border: 2px solid alpha(#ff4da6, 0.38);
padding: 10px;
min-width: 500px;
}
.launcher .search {
background: alpha(#261537, 0.75);
border-radius: 12px;
border: 1px solid alpha(#5a3875, 0.50);
padding: 9px 14px;
color: #f0eaf8;
caret-color: #ff4da6;
font-size: 14px;
}
.launcher .search:focus {
border-color: alpha(#ff4da6, 0.60);
}
.launcher .app-item {
background: transparent;
border-radius: 8px;
padding: 7px 10px;
color: #f0eaf8;
}
.launcher .app-item:hover,
.launcher .app-item:focus {
background: alpha(#ff4da6, 0.16);
border: 1px solid alpha(#ff4da6, 0.32);
}
.launcher .app-item:hover label,
.launcher .app-item:focus label {
color: #ff4da6;
}
.launcher .app-item image {
margin-right: 10px;
}
.launcher .no-results {
color: #716686;
padding: 20px;
}
/* ══════════════════════════════════════════════════════════════════════════
* NOTIFICATIONS
* ══════════════════════════════════════════════════════════════════════════ */
.notification {
background: alpha(#261537, 0.94);
border-radius: 14px;
border: 2px solid alpha(#c9a0ff, 0.30);
padding: 12px;
margin: 8px;
min-width: 350px;
}
.notification .title {
color: #ff4da6;
font-weight: bold;
font-size: 13px;
}
.notification .body {
color: #c4b8d4;
font-weight: normal;
font-size: 12px;
}
.notification .app-name {
color: #716686;
font-size: 11px;
}
.notification .time {
color: #716686;
font-size: 10px;
}
.notification .close-btn {
color: #716686;
font-size: 14px;
min-width: 0;
min-height: 0;
padding: 2px 6px;
border-radius: 6px;
}
.notification .close-btn:hover {
color: #f25c7a;
background: alpha(#f25c7a, 0.12);
}
.notification .actions button {
background: alpha(#5a3875, 0.50);
color: #c9a0ff;
border-radius: 8px;
padding: 4px 12px;
margin: 4px 4px 0 0;
}
.notification .actions button:hover {
background: alpha(#ff4da6, 0.20);
color: #ff4da6;
}
/* ── Urgency levels ──────────────────────────────────────────────────────── */
.notification.critical {
border-color: alpha(#f25c7a, 0.60);
}
.notification.critical .title {
color: #f25c7a;
}
/* ══════════════════════════════════════════════════════════════════════════
* TOOLTIP — shared
* ══════════════════════════════════════════════════════════════════════════ */
tooltip {
background: alpha(#1a0e27, 0.96);
border: 1px solid alpha(#ff4da6, 0.30);
border-radius: 10px;
color: #f0eaf8;
padding: 6px 10px;
}

View File

@@ -0,0 +1,228 @@
// ── violet-chaton v2 — Bar widget ───────────────────────────────────────────
// 3 pills glassmorphism — modulaire selon compositor
const audio = await Service.import("audio");
const battery = await Service.import("battery");
const network = await Service.import("network");
const systemtray = await Service.import("systemtray");
const mpris = await Service.import("mpris");
// ── Helpers ─────────────────────────────────────────────────────────────────
const Separator = () => Widget.Label({ className: "separator", label: "│" });
const Clock = () => Widget.Label({
className: "clock",
connections: [[1000, (self) => {
self.label = Utils.exec("date +%H:%M");
}]],
});
const DateWidget = () => Widget.Label({
className: "date",
connections: [[60000, (self) => {
self.label = Utils.exec("date '+%a %d %b'");
}]],
});
// ── System ──────────────────────────────────────────────────────────────────
const CPU = () => Widget.Label({
className: "cpu",
connections: [[2000, (self) => {
const usage = Math.round(
Number(Utils.exec(`bash -c "top -bn1 | awk '/^%Cpu/ {print 100-$8}'"`)
));
self.label = `󰻠 ${usage}%`;
self.toggleClassName("warning", usage > 70);
self.toggleClassName("critical", usage > 90);
}]],
});
const RAM = () => Widget.Label({
className: "ram",
connections: [[2000, (self) => {
const used = Utils.exec(`bash -c "free -m | awk '/^Mem:/ {printf \"%.1f\", $3/1024}'"`)
const total = Utils.exec(`bash -c "free -m | awk '/^Mem:/ {printf \"%.1f\", $2/1024}'"`)
const pct = Math.round((parseFloat(used) / parseFloat(total)) * 100);
self.label = `󰑭 ${used}G`;
self.toggleClassName("warning", pct > 70);
self.toggleClassName("critical", pct > 90);
}]],
});
// ── Network ─────────────────────────────────────────────────────────────────
const Network = () => Widget.Label({
className: "network",
connections: [[network, (self) => {
if (network.primary === "wifi") {
const wifi = network.wifi;
self.label = `󰤨 ${wifi?.ssid || ""}`;
self.toggleClassName("wifi", true);
self.toggleClassName("disconnected", false);
} else if (network.primary === "wired") {
self.label = "󰈀 Eth";
self.toggleClassName("wifi", false);
self.toggleClassName("disconnected", false);
} else {
self.label = "󰤮 ";
self.toggleClassName("disconnected", true);
}
}]],
});
// ── Volume ──────────────────────────────────────────────────────────────────
const Volume = () => Widget.Button({
className: "volume",
onClicked: () => { audio.speaker.isMuted = !audio.speaker.isMuted; },
child: Widget.Label({
connections: [[audio, (self) => {
const vol = Math.round((audio.speaker?.volume || 0) * 100);
const muted = audio.speaker?.isMuted;
const icon = muted ? "󰝟" : vol > 66 ? "󰕾" : vol > 33 ? "󰖀" : "󰕿";
self.label = `${icon} ${vol}%`;
self.parent?.toggleClassName("muted", muted);
}, "speaker-changed"]],
}),
});
// ── Battery ─────────────────────────────────────────────────────────────────
const Battery = () => Widget.Label({
className: "battery",
visible: battery.bind("available"),
connections: [[battery, (self) => {
const pct = battery.percent;
const charging = battery.charging;
const icon = charging ? "󰂄" : pct > 80 ? "󰁹" : pct > 60 ? "󰂀" :
pct > 40 ? "󰁾" : pct > 20 ? "󰁻" : "󰂎";
self.label = `${icon} ${pct}%`;
self.toggleClassName("charging", charging);
self.toggleClassName("low", pct <= 20 && !charging);
self.toggleClassName("warning", pct <= 30 && !charging);
}]],
});
// ── Media ───────────────────────────────────────────────────────────────────
const Media = () => Widget.Label({
className: "media",
connections: [[mpris, (self) => {
const player = mpris.players[0];
if (!player) {
self.visible = false;
return;
}
self.visible = true;
const artist = player.trackArtists?.join(", ") || "";
const title = player.trackTitle || "";
const icon = player.playBackStatus === "Playing" ? " " : " ";
self.label = `${icon}${artist ? artist + " — " : ""}${title}`.slice(0, 50);
self.toggleClassName("paused", player.playBackStatus !== "Playing");
}]],
});
// ── Systray ─────────────────────────────────────────────────────────────────
const SysTray = () => Widget.Box({
className: "systray",
children: systemtray.bind("items").transform((items) =>
items.map((item) =>
Widget.Button({
child: Widget.Icon({ icon: item.bind("icon"), size: 16 }),
tooltipMarkup: item.bind("tooltip-markup"),
onPrimaryClick: (_, event) => item.activate(event),
onSecondaryClick: (_, event) => item.openMenu(event),
})
)
),
});
// ── Launcher button ─────────────────────────────────────────────────────────
const LauncherBtn = () => Widget.Button({
className: "launcher-btn",
label: "󱄅",
onClicked: () => App.toggleWindow("launcher"),
});
// ── Power button ────────────────────────────────────────────────────────────
const PowerBtn = () => Widget.Button({
className: "power-btn",
label: "⏻",
onClicked: () => Utils.exec("bash -c 'systemctl poweroff'"),
});
// ── Workspaces (Hyprland only) ──────────────────────────────────────────────
const Workspaces = (compositor) => {
if (compositor !== "hyprland") return Widget.Box({});
const hyprland = await Service.import("hyprland");
return Widget.Box({
className: "workspaces",
children: hyprland.bind("workspaces").transform((ws) =>
ws.sort((a, b) => a.id - b.id)
.filter((w) => w.id > 0)
.map((w) =>
Widget.Button({
onClicked: () => hyprland.messageAsync(`dispatch workspace ${w.id}`),
child: Widget.Label({ label: `${w.id}` }),
className: hyprland.active.workspace.bind("id").transform(
(id) => id === w.id ? "active" : w.windows > 0 ? "occupied" : ""
),
})
)
),
});
};
// ── Bar assembly ────────────────────────────────────────────────────────────
export const Bar = (monitor, compositor) => Widget.Window({
name: `bar-${monitor}`,
monitor,
anchor: ["top", "left", "right"],
exclusivity: "exclusive",
className: "bar",
child: Widget.CenterBox({
startWidget: Widget.Box({
className: "modules-left",
children: [
LauncherBtn(),
Separator(),
Workspaces(compositor),
Separator(),
CPU(),
RAM(),
],
}),
centerWidget: Widget.Box({
className: "modules-center",
children: [
Media(),
],
}),
endWidget: Widget.Box({
className: "modules-right",
hpack: "end",
children: [
Network(),
Separator(),
Volume(),
Separator(),
Battery(),
Separator(),
DateWidget(),
Clock(),
Separator(),
SysTray(),
Separator(),
PowerBtn(),
],
}),
}),
});

View File

@@ -0,0 +1,99 @@
// ── violet-chaton v2 — Launcher widget ──────────────────────────────────────
// App launcher avec recherche fuzzy
const applications = await Service.import("applications");
const AppItem = (app) => Widget.Button({
className: "app-item",
onClicked: () => {
app.launch();
App.closeWindow("launcher");
},
child: Widget.Box({
children: [
Widget.Icon({ icon: app.iconName || "application-x-executable", size: 24 }),
Widget.Box({
vertical: true,
children: [
Widget.Label({
label: app.name,
xalign: 0,
truncate: "end",
}),
Widget.Label({
label: app.description || "",
xalign: 0,
truncate: "end",
className: "description",
css: "color: #716686; font-size: 11px; font-weight: normal;",
}),
],
}),
],
}),
});
export const Launcher = (monitor) => {
let apps = applications.list;
const list = Widget.Box({
vertical: true,
spacing: 2,
});
const entry = Widget.Entry({
className: "search",
placeholderText: "Rechercher...",
onAccept: () => {
const first = apps[0];
if (first) {
first.launch();
App.closeWindow("launcher");
}
},
onChange: ({ text }) => {
apps = applications.query(text || "");
list.children = apps.slice(0, 12).map(AppItem);
if (apps.length === 0) {
list.children = [Widget.Label({
className: "no-results",
label: "Aucun resultat",
})];
}
},
});
return Widget.Window({
name: "launcher",
monitor,
anchor: ["top"],
layer: "overlay",
visible: false,
keymode: "exclusive",
setup: (self) => {
self.keybind("Escape", () => App.closeWindow("launcher"));
self.hook(App, (_, name, visible) => {
if (name === "launcher" && visible) {
entry.text = "";
apps = applications.list;
list.children = apps.slice(0, 12).map(AppItem);
entry.grab_focus();
}
});
},
child: Widget.Box({
className: "launcher",
vertical: true,
children: [
Widget.Scrollable({
hscroll: "never",
vscroll: "automatic",
css: "min-height: 400px;",
child: list,
}),
entry,
],
}),
});
};

View File

@@ -0,0 +1,105 @@
// ── violet-chaton v2 — Notifications widget ─────────────────────────────────
// Popup notifications stylees — urgency-aware
const notifications = await Service.import("notifications");
// Ne pas déranger
notifications.popupTimeout = 5000;
notifications.cacheActions = true;
const NotificationIcon = (notif) => {
if (notif.image) {
return Widget.Box({
css: `
min-width: 48px; min-height: 48px;
background-image: url("${notif.image}");
background-size: cover;
background-position: center;
border-radius: 8px;
margin-right: 10px;
`,
});
}
return Widget.Icon({
icon: notif.appIcon || notif.appEntry || "dialog-information",
size: 36,
css: "margin-right: 10px;",
});
};
const Notification = (notif) => Widget.Box({
className: `notification ${notif.urgency}`,
vertical: true,
children: [
Widget.Box({
children: [
NotificationIcon(notif),
Widget.Box({
vertical: true,
hexpand: true,
children: [
Widget.Box({
children: [
Widget.Label({
className: "title",
label: notif.summary,
xalign: 0,
hexpand: true,
truncate: "end",
}),
Widget.Label({
className: "time",
label: new Date(notif.time * 1000)
.toLocaleTimeString("fr-FR", {
hour: "2-digit",
minute: "2-digit",
}),
}),
Widget.Button({
className: "close-btn",
label: "✕",
onClicked: () => notif.close(),
}),
],
}),
Widget.Label({
className: "app-name",
label: notif.appName || "",
xalign: 0,
}),
],
}),
],
}),
...(notif.body ? [Widget.Label({
className: "body",
label: notif.body,
xalign: 0,
wrap: true,
useMarkup: true,
})] : []),
...(notif.actions.length > 0 ? [Widget.Box({
className: "actions",
children: notif.actions.map((action) =>
Widget.Button({
label: action.label,
onClicked: () => notif.invoke(action.id),
})
),
})] : []),
],
});
export const Notifications = (monitor) => Widget.Window({
name: `notifications-${monitor}`,
monitor,
anchor: ["top", "right"],
layer: "overlay",
child: Widget.Box({
vertical: true,
css: "min-width: 350px;",
children: notifications.bind("popups").transform((popups) =>
popups.map(Notification)
),
}),
});

View File

@@ -0,0 +1,95 @@
// ── violet-chaton v2 — OSD widget ───────────────────────────────────────────
// Overlay volume / brightness avec gradient Mitsuri
const audio = await Service.import("audio");
// ── OSD reveal timer ────────────────────────────────────────────────────────
let osdTimeout = null;
const showOSD = (window) => {
window.visible = true;
if (osdTimeout) clearTimeout(osdTimeout);
osdTimeout = setTimeout(() => {
window.visible = false;
}, 1500);
};
// ── Volume OSD ──────────────────────────────────────────────────────────────
const VolumeOSD = () => {
const icon = Widget.Label({ className: "icon" });
const progress = Widget.ProgressBar();
const label = Widget.Label({ className: "label" });
const box = Widget.Box({
className: "osd",
children: [icon, progress, label],
connections: [[audio, (self) => {
const vol = audio.speaker?.volume || 0;
const muted = audio.speaker?.isMuted;
icon.label = muted ? "󰝟" : vol > 0.66 ? "󰕾" : vol > 0.33 ? "󰖀" : "󰕿";
progress.value = vol;
label.label = `${Math.round(vol * 100)}%`;
}, "speaker-changed"]],
});
return box;
};
// ── Brightness OSD ──────────────────────────────────────────────────────────
const BrightnessOSD = () => {
const icon = Widget.Label({ className: "icon", label: "󰃞" });
const progress = Widget.ProgressBar();
const label = Widget.Label({ className: "label" });
const getBrightness = () => {
try {
const max = Number(Utils.exec("brightnessctl max"));
const cur = Number(Utils.exec("brightnessctl get"));
return max > 0 ? cur / max : 0;
} catch {
return 0;
}
};
const box = Widget.Box({
className: "osd",
children: [icon, progress, label],
connections: [[500, (self) => {
const val = getBrightness();
progress.value = val;
label.label = `${Math.round(val * 100)}%`;
}]],
});
return box;
};
// ── OSD windows ─────────────────────────────────────────────────────────────
export const OSD = (monitor) => {
const volumeWin = Widget.Window({
name: `osd-volume-${monitor}`,
monitor,
anchor: ["bottom"],
layer: "overlay",
visible: false,
child: VolumeOSD(),
});
const brightnessWin = Widget.Window({
name: `osd-brightness-${monitor}`,
monitor,
anchor: ["bottom"],
layer: "overlay",
visible: false,
child: BrightnessOSD(),
});
// Auto-show on volume change
Utils.merge([audio.speaker?.bind("volume")], () => showOSD(volumeWin));
return [volumeWin, brightnessWin];
};

View File

@@ -1,376 +1,19 @@
## ── violet-chaton config ──────────────────────────────────────────────────────
dialect = "uk" # format de date européen
## ── violet-chaton v2 — atuin config ──────────────────────────────────────────
dialect = "uk"
timezone = "local"
search_mode = "fuzzy" # recherche floue comme fzf
filter_mode = "global" # cherche dans tout l'historique
style = "full" # interface complète
inline_height = 40 # occupe 40% du terminal
invert = true # barre de recherche en haut
show_preview = true # aperçu de la commande sélectionnée
enter_accept = true # Entrée accepte directement
search_mode = "fuzzy"
filter_mode = "global"
style = "full"
inline_height = 40
invert = true
show_preview = true
enter_accept = true
[theme]
name = "violet-chaton"
## ── fin config violet-chaton ──────────────────────────────────────────────────
## Base directory for Atuin data files (databases, keys, session, etc.)
## All data file paths default to being relative to this directory.
## linux/mac: ~/.local/share/atuin (or XDG_DATA_HOME/atuin)
## windows: %USERPROFILE%/.local/share/atuin
# data_dir = "~/.local/share/atuin"
## where to store your database, default is your system data directory
## linux/mac: ~/.local/share/atuin/history.db
## windows: %USERPROFILE%/.local/share/atuin/history.db
# db_path = "~/.history.db"
## where to store your encryption key, default is your system data directory
## linux/mac: ~/.local/share/atuin/key
## windows: %USERPROFILE%/.local/share/atuin/key
# key_path = "~/.key"
## where to store your auth session token, default is your system data directory
## linux/mac: ~/.local/share/atuin/session
## windows: %USERPROFILE%/.local/share/atuin/session
# session_path = "~/.session"
## date format used, either "us" or "uk"
# dialect = "us"
## default timezone to use when displaying time
## either "l", "local" to use the system's current local timezone, or an offset
## from UTC in the format of "<+|->H[H][:M[M][:S[S]]]"
## for example: "+9", "-05", "+03:30", "-01:23:45", etc.
# timezone = "local"
## enable or disable automatic sync
# auto_sync = true
## enable or disable automatic update checks
# update_check = true
## address of the sync server
# sync_address = "https://api.atuin.sh"
## how often to sync history. note that this is only triggered when a command
## is ran, so sync intervals may well be longer
## set it to 0 to sync after every command
# sync_frequency = "10m"
## which search mode to use
## possible values: prefix, fulltext, fuzzy, skim
# search_mode = "fuzzy"
## which filter mode to use by default
## possible values: "global", "host", "session", "session-preload", "directory", "workspace"
## consider using search.filters to customize the enablement and order of filter modes
# filter_mode = "global"
## With workspace filtering enabled, Atuin will filter for commands executed
## in any directory within a git repository tree (default: false).
##
## To use workspace mode by default when available, set this to true and
## set filter_mode to "workspace" or leave it unspecified and
## set search.filters to include "workspace" before other filter modes.
# workspaces = false
## which filter mode to use when atuin is invoked from a shell up-key binding
## the accepted values are identical to those of "filter_mode"
## leave unspecified to use same mode set in "filter_mode"
# filter_mode_shell_up_key_binding = "global"
## which search mode to use when atuin is invoked from a shell up-key binding
## the accepted values are identical to those of "search_mode"
## leave unspecified to use same mode set in "search_mode"
# search_mode_shell_up_key_binding = "fuzzy"
## which style to use
## possible values: auto, full, compact
# style = "auto"
## the maximum number of lines the interface should take up
## set it to 0 to always go full screen
# inline_height = 0
## the maximum number of lines the interface should take up
## when atuin is invoked from a shell up-key binding
## the accepted values are identical to those of "inline_height"
# inline_height_shell_up_key_binding = 0
## Invert the UI - put the search bar at the top , Default to `false`
# invert = false
## enable or disable showing a preview of the selected command
## useful when the command is longer than the terminal width and is cut off
# show_preview = true
## what to do when the escape key is pressed when searching
## possible values: return-original, return-query
# exit_mode = "return-original"
## possible values: emacs, subl
# word_jump_mode = "emacs"
## characters that count as a part of a word
# word_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
## number of context lines to show when scrolling by pages
# scroll_context_lines = 1
## use ctrl instead of alt as the shortcut modifier key for numerical UI shortcuts
## alt-0 .. alt-9
# ctrl_n_shortcuts = false
## Show numeric shortcuts (1..9) beside list items in the TUI
## set to false to hide the moving numbers if you find them distracting
# show_numeric_shortcuts = true
## default history list format - can also be specified with the --format arg
# history_format = "{time}\t{command}\t{duration}"
## prevent commands matching any of these regexes from being written to history.
## Note that these regular expressions are unanchored, i.e. if they don't start
## with ^ or end with $, they'll match anywhere in the command.
## For details on the supported regular expression syntax, see
## https://docs.rs/regex/latest/regex/#syntax
# history_filter = [
# "^secret-cmd",
# "^innocuous-cmd .*--secret=.+",
# ]
## prevent commands run with cwd matching any of these regexes from being written
## to history. Note that these regular expressions are unanchored, i.e. if they don't
## start with ^ or end with $, they'll match anywhere in CWD.
## For details on the supported regular expression syntax, see
## https://docs.rs/regex/latest/regex/#syntax
# cwd_filter = [
# "^/very/secret/area",
# ]
## Configure the maximum height of the preview to show.
## Useful when you have long scripts in your history that you want to distinguish
## by more than the first few lines.
# max_preview_height = 4
## Configure whether or not to show the help row, which includes the current Atuin
## version (and whether an update is available), a keymap hint, and the total
## amount of commands in your history.
# show_help = true
## Configure whether or not to show tabs for search and inspect
# show_tabs = true
## Configure whether or not the tabs row may be auto-hidden, which includes the current Atuin
## tab, such as Search or Inspector, and other tabs you may wish to see. This will
## only be hidden if there are fewer than this count of lines available, and does not affect the use
## of keyboard shortcuts to switch tab. 0 to never auto-hide, default is 8 (lines).
## This is ignored except in `compact` mode.
# auto_hide_height = 8
## Defaults to true. This matches history against a set of default regex, and will not save it if we get a match. Defaults include
## 1. AWS key id
## 2. Github pat (old and new)
## 3. Slack oauth tokens (bot, user)
## 4. Slack webhooks
## 5. Stripe live/test keys
# secrets_filter = true
## Defaults to true. If enabled, upon hitting enter Atuin will immediately execute the command,
## whereas tab will put the command in the prompt for editing.
## If set to false, both enter and tab will place the command in the prompt for editing.
## This applies for new installs. Old installs will keep the old behaviour unless configured otherwise.
enter_accept = true
## Defaults to false. If enabled, when triggered after &&, || or |, Atuin will complete commands to chain rather than replace the current line.
# command_chaining = false
## Defaults to "emacs". This specifies the keymap on the startup of `atuin
## search`. If this is set to "auto", the startup keymap mode in the Atuin
## search is automatically selected based on the shell's keymap where the
## keybinding is defined. If this is set to "emacs", "vim-insert", or
## "vim-normal", the startup keymap mode in the Atuin search is forced to be
## the specified one.
# keymap_mode = "auto"
## Cursor style in each keymap mode. If specified, the cursor style is changed
## in entering the cursor shape. Available values are "default" and
## "{blink,steady}-{block,underline,bar}".
# keymap_cursor = { emacs = "blink-block", vim_insert = "blink-block", vim_normal = "steady-block" }
# network_connect_timeout = 5
# network_timeout = 5
## Timeout (in seconds) for acquiring a local database connection (sqlite)
# local_timeout = 5
## Set this to true and Atuin will minimize motion in the UI - timers will not update live, etc.
## Alternatively, set env NO_MOTION=true
# prefers_reduced_motion = false
[stats]
## Set commands where we should consider the subcommand for statistics. Eg, kubectl get vs just kubectl
# common_subcommands = [
# "apt",
# "cargo",
# "composer",
# "dnf",
# "docker",
# "dotnet",
# "git",
# "go",
# "ip",
# "jj",
# "kubectl",
# "nix",
# "nmcli",
# "npm",
# "pecl",
# "pnpm",
# "podman",
# "port",
# "systemctl",
# "tmux",
# "yarn",
# ]
## Set commands that should be totally stripped and ignored from stats
# common_prefix = ["sudo"]
## Set commands that will be completely ignored from stats
# ignored_commands = [
# "cd",
# "ls",
# "vi"
# ]
[keys]
# Defaults to true. If disabled, using the up/down key won't exit the TUI when scrolled past the first/last entry.
# scroll_exits = true
# Defaults to true. The left arrow key will exit the TUI when scrolling before the first character
# exit_past_line_start = true
# Defaults to true. The right arrow key performs the same functionality as Tab and copies the selected line to the command line to be modified.
# accept_past_line_end = true
# Defaults to false. The left arrow key performs the same functionality as Tab and copies the selected line to the command line to be modified.
# accept_past_line_start = false
# Defaults to false. The backspace key performs the same functionality as Tab and copies the selected line to the command line to be modified when at the start of the line.
# accept_with_backspace = false
[sync]
# Enable sync v2 by default
# This ensures that sync v2 is enabled for new installs only
# In a later release it will become the default across the board
records = true
[preview]
## which preview strategy to use to calculate the preview height (respects max_preview_height).
## possible values: auto, static
## auto: length of the selected command.
## static: length of the longest command stored in the history.
## fixed: use max_preview_height as fixed height.
# strategy = "auto"
[daemon]
## Enables using the daemon to sync. Requires the daemon to be running in the background. Start it with `atuin daemon`
# enabled = false
## How often the daemon should sync in seconds
# sync_frequency = 300
## The path to the unix socket used by the daemon (on unix systems)
## linux/mac: ~/.local/share/atuin/atuin.sock
## windows: Not Supported
# socket_path = "~/.local/share/atuin/atuin.sock"
## Use systemd socket activation rather than opening the given path (the path must still be correct for the client)
## linux: false
## mac/windows: Not Supported
# systemd_socket = false
## The port that should be used for TCP on non unix systems
# tcp_port = 8889
# [theme]
## Color theme to use for rendering in the terminal.
## There are some built-in themes, including the base theme ("default"),
## "autumn" and "marine". You can add your own themes to the "./themes" subdirectory of your
## Atuin config (or ATUIN_THEME_DIR, if provided) as TOML files whose keys should be one or
## more of AlertInfo, AlertWarn, AlertError, Annotation, Base, Guidance, Important, and
## the string values as lowercase entries from this list:
## https://ogeon.github.io/docs/palette/master/palette/named/index.html
## If you provide a custom theme file, it should be called "NAME.toml" and the theme below
## should be the stem, i.e. `theme = "NAME"` for your chosen NAME.
# name = "autumn"
## Whether the theme manager should output normal or extra information to help fix themes.
## Boolean, true or false. If unset, left up to the theme manager.
# debug = true
[search]
## The list of enabled filter modes, in order of priority.
## The "workspace" mode is skipped when not in a workspace or workspaces = false.
## Default filter mode can be overridden with the filter_mode setting.
# filters = [ "global", "host", "session", "session-preload", "workspace", "directory" ]
[tmux]
## Enable using atuin with tmux popup (requires tmux >= 3.2)
## When enabled and running inside tmux, Atuin will use a popup window for interactive search.
## Set to false to disable the popup.
## This can also be controlled with the ATUIN_TMUX_POPUP environment variable.
## Note: The tmux popup is currently supported in zsh, bash, and fish shells. This currently doesn't work with iTerm native tmux integration.
# enabled = false
## Width of the tmux popup window
## Can be a percentage, or integer (e.g. "100" means 100 characters wide)
# width = "80%"
## Height of the tmux popup window
## Can be a percentage, or integer (e.g. "100" means 100 lines tall)
# height = "60%"
[ui]
columns = ["exit", "duration", "time", "command"]
## Columns to display in the interactive search, from left to right.
## The selection indicator (" > ") is always shown first implicitly.
##
## Each column can be specified as a simple string (uses default width)
## or as an object with type, width, and expand:
## { type = "directory", width = 30, expand = true }
##
## Available column types (with default widths):
## duration (5) - Command execution duration (e.g., "123ms")
## time (8) - Relative time since execution (e.g., "59m ago")
## datetime (16) - Absolute timestamp (e.g., "2025-01-22 14:35")
## directory (20) - Working directory (truncated if too long)
## host (15) - Hostname where command was run
## user (10) - Username
## exit (3) - Exit code (colored by success/failure)
## command (*) - The command itself (expands by default)
##
## The "expand" option (default: true for command, false for others) makes a
## column fill remaining space. Only one column should have expand = true.
##
## Default:
# columns = ["duration", "time", "command"]
##
## Examples:
##
## Minimal - more space for commands:
# columns = ["duration", "command"]
##
## With wider directory column:
# columns = ["duration", { type = "directory", width = 30 }, "command"]
##
## Show host for multi-machine sync users:
# columns = ["duration", "time", "host", "command"]
##
## Show exit codes prominently:
# columns = ["exit", "duration", "command"]
##
## Make directory expand instead of command:
# columns = ["duration", "time", { type = "directory", expand = true }, { type = "command", expand = false }]

View File

@@ -4,58 +4,74 @@
"type": "none"
},
"display": {
"separator": " ",
"separator": " ",
"color": {
"keys": "magenta",
"title": "cyan"
"keys": "#ff4da6",
"title": "#c9a0ff",
"separator": "#5a3875"
}
},
"modules": [
"title",
"separator",
{"type": "os", "key": "󰣚 Système ", "keyColor": "magenta"},
{"type": "kernel", "key": " Kernel ", "keyColor": "magenta"},
{"type": "shell", "key": " Shell ", "keyColor": "magenta"},
{"type": "terminal", "key": " Terminal ", "keyColor": "magenta"},
{"type": "wm", "key": " Bureau ", "keyColor": "magenta"},
{"type": "packages", "key": "󰏖 Paquets ", "keyColor": "magenta"},
{
"type": "title",
"format": "{user-name}@{host-name}",
"keyColor": "#ff4da6"
},
{
"type": "custom",
"format": "───────────────────────────────────",
"outputColor": "#3d2454"
},
"break",
{"type": "cpu", "key": "󰻠 CPU ", "keyColor": "magenta"},
{"type": "os", "key": " sys", "keyColor": "#ff4da6"},
{"type": "kernel", "key": " ker", "keyColor": "#c9a0ff"},
{"type": "shell", "key": " sh ", "keyColor": "#a4b4ff"},
{"type": "terminal", "key": " trm", "keyColor": "#9adba8"},
{"type": "wm", "key": " wm ", "keyColor": "#c9a0ff"},
{"type": "packages", "key": " pkg", "keyColor": "#e8c87a"},
"break",
{"type": "cpu", "key": " cpu", "keyColor": "#ff4da6"},
{
"type": "gpu",
"key": "󰍛 GPU ",
"keyColor": "magenta",
"key": " gpu",
"keyColor": "#c9a0ff",
"hideTypes": ["Integrated"]
},
{
"type": "display",
"key": "󰹆 Écran ",
"keyColor": "magenta",
"key": " dsp",
"keyColor": "#a4b4ff",
"format": "{width}x{height} @ {refresh-rate}Hz"
},
{"type": "memory", "key": "󰑭 Mémoire ", "keyColor": "magenta"},
{"type": "memory", "key": " mem", "keyColor": "#ff4da6"},
{
"type": "disk",
"key": "󰋊 Disque ",
"keyColor": "magenta",
"key": " dsk",
"keyColor": "#e8c87a",
"folders": "/"
},
{"type": "processes", "key": "󰙲 Processus", "keyColor": "magenta"},
{"type": "uptime", "key": "󰅐 Uptime ", "keyColor": "magenta"},
{"type": "uptime", "key": " up ", "keyColor": "#716686"},
"break",
{
"type": "media",
"key": " Musique ",
"keyColor": "magenta",
"key": " now",
"keyColor": "#ff4da6",
"format": "{artist} — {title}"
},
"break",
{
"type": "custom",
"format": "───────────────────────────────────",
"outputColor": "#3d2454"
},
"colors"
]
}

View File

@@ -18,38 +18,38 @@
navigate = true
hyperlinks = true
# Lignes supprimées : fond rose sombre
minus-style = syntax "#3d1a2e"
minus-emph-style = syntax "#5a1a38"
# Lignes supprimees : fond magenta sombre
minus-style = syntax "#3a1230"
minus-emph-style = syntax "#5a1848"
# Lignes ajoutées : fond cyan sombre
plus-style = syntax "#0d2a35"
plus-emph-style = syntax "#0d3a48"
# Lignes ajoutees : fond mitsuri sombre
plus-style = syntax "#1a3025"
plus-emph-style = syntax "#1a4530"
# Numéros de ligne
line-numbers-minus-style = "#ff79c6"
line-numbers-plus-style = "#8be9fd"
line-numbers-zero-style = "#6c7086"
# Numeros de ligne
line-numbers-minus-style = "#ff4da6"
line-numbers-plus-style = "#9adba8"
line-numbers-zero-style = "#716686"
line-numbers-left-format = " {nm} │"
line-numbers-right-format = " {np} │"
# En-tête de fichier
file-style = "bold #e79cfe"
# En-tete de fichier
file-style = "bold #c9a0ff"
file-decoration-style = "#3d2454 box"
file-added-label = "[+]"
file-removed-label = "[-]"
file-modified-label = "[~]"
file-renamed-label = "[»]"
# En-tête de hunk
# En-tete de hunk
hunk-header-style = "syntax #261537"
hunk-header-decoration-style = "#6c7086 box"
hunk-header-file-style = "bold #e79cfe"
hunk-header-line-number-style = "#7f849c"
hunk-header-decoration-style = "#716686 box"
hunk-header-file-style = "bold #c9a0ff"
hunk-header-line-number-style = "#9a8fad"
# Commit
commit-decoration-style = "bold #ff79c6 box"
commit-style = "bold #f8f8f2"
commit-decoration-style = "bold #ff4da6 box"
commit-style = "bold #f0eaf8"
[merge]
conflictstyle = diff3

182
INSTALL/configs/kitty.conf Normal file
View File

@@ -0,0 +1,182 @@
# ── violet-chaton v2 — kitty terminal ────────────────────────────────────────
# Font : Maple Mono NF — cursive italics + ligatures
# Palette : violet-chaton v2 (source : themes/palette.sh)
# ── Font ─────────────────────────────────────────────────────────────────────
font_family Maple Mono NF
bold_font Maple Mono NF Bold
italic_font Maple Mono NF Italic
bold_italic_font Maple Mono NF Bold Italic
font_size 13.0
# Ligatures et font features (cursive italics pour commentaires)
disable_ligatures never
font_features MapleMono-NF-Regular +cv01 +ss01 +ss02 +ss03 +ss05
font_features MapleMono-NF-Italic +cv01 +ss01 +ss02 +ss03 +ss05
font_features MapleMono-NF-Bold +cv01 +ss01 +ss02 +ss03 +ss05
font_features MapleMono-NF-BoldItalic +cv01 +ss01 +ss02 +ss03 +ss05
# ── Cursor + trail effect ────────────────────────────────────────────────────
cursor #ff4da6
cursor_text_color #1a0e27
cursor_shape beam
cursor_beam_thickness 1.8
cursor_blink_interval 0.4
# Undercurl style — vagues violettes pour les erreurs/warnings
undercurl_style thin-sparse
# Couleurs undercurl (utilisees par les apps qui supportent les colored underlines)
# Les terminaux modernes + neovim/bat utilisent ces couleurs automatiquement
# Trail — trainee lumineuse magenta derriere le curseur
cursor_trail 15
cursor_trail_decay 0.05 0.3
cursor_trail_start_threshold 0
# ── Scrollback ───────────────────────────────────────────────────────────────
scrollback_lines 10000
wheel_scroll_multiplier 3
# ── Mouse ────────────────────────────────────────────────────────────────────
mouse_hide_wait 2.0
url_color #a4b4ff
url_style curly
open_url_with default
detect_urls yes
# ── Bell ─────────────────────────────────────────────────────────────────────
enable_audio_bell no
visual_bell_duration 0.0
# ── Window ───────────────────────────────────────────────────────────────────
window_padding_width 8 12
background_opacity 0.92
dynamic_background_opacity yes
dim_opacity 0.75
# Blur (compositor dependent — works on KWin, Hyprland, COSMIC)
# background_blur 24
confirm_os_window_close 0
initial_window_width 120c
initial_window_height 35c
# ── Tab bar ──────────────────────────────────────────────────────────────────
tab_bar_edge top
tab_bar_style powerline
tab_powerline_style slanted
tab_bar_min_tabs 2
active_tab_foreground #1a0e27
active_tab_background #ff4da6
active_tab_font_style bold
inactive_tab_foreground #c4b8d4
inactive_tab_background #3d2454
inactive_tab_font_style normal
tab_bar_background #1a0e27
# ── Palette violet-chaton v2 ─────────────────────────────────────────────────
# Fond
foreground #f0eaf8
background #261537
selection_foreground #1a0e27
selection_background #c9a0ff
# Noir (fonds)
color0 #261537
color8 #5a3875
# Rouge (danger)
color1 #f25c7a
color9 #ff7a96
# Vert (mitsuri)
color2 #9adba8
color10 #b5e8c0
# Jaune (champagne)
color3 #e8c87a
color11 #f0d99a
# Bleu (lavande)
color4 #a4b4ff
color12 #bcc8ff
# Magenta
color5 #ff4da6
color13 #c9a0ff
# Cyan (lilac — pas de vrai cyan, on reste violet)
color6 #c9a0ff
color14 #dfc0ff
# Blanc (texte)
color7 #c4b8d4
color15 #f0eaf8
# ── Marks ────────────────────────────────────────────────────────────────────
mark1_foreground #1a0e27
mark1_background #ff4da6
mark2_foreground #1a0e27
mark2_background #c9a0ff
mark3_foreground #1a0e27
mark3_background #a4b4ff
# ── Keyboard shortcuts ──────────────────────────────────────────────────────
# Clipboard
map ctrl+v paste_from_clipboard
map ctrl+c copy_or_interrupt
# Tabs
map ctrl+shift+t new_tab_with_cwd
map ctrl+shift+l next_tab
map ctrl+shift+h previous_tab
map ctrl+shift+w close_tab
map ctrl+shift+, set_tab_title
# Splits / Windows — tiling dans le terminal
map ctrl+shift+enter new_window_with_cwd
map ctrl+shift+\ launch --cwd=current --location=vsplit
map ctrl+shift+- launch --cwd=current --location=hsplit
map ctrl+shift+z toggle_layout stack
map ctrl+shift+r start_resizing_window
# Navigation entre splits
map ctrl+shift+left neighboring_window left
map ctrl+shift+right neighboring_window right
map ctrl+shift+up neighboring_window up
map ctrl+shift+down neighboring_window down
# Swap splits
map ctrl+shift+f move_window_forward
map ctrl+shift+b move_window_backward
# Zoom
map ctrl+shift+equal change_font_size all +1.0
map ctrl+shift+minus change_font_size all -1.0
map ctrl+shift+0 change_font_size all 0
# Reload
map ctrl+shift+f5 load_config_file
# Quick layouts
map ctrl+shift+1 goto_layout tall
map ctrl+shift+2 goto_layout fat
map ctrl+shift+3 goto_layout grid
map ctrl+shift+4 goto_layout horizontal
map ctrl+shift+5 goto_layout vertical
# ── Layouts ──────────────────────────────────────────────────────────────────
enabled_layouts tall,fat,grid,horizontal,vertical,stack
# ── Splits styling ──────────────────────────────────────────────────────────
active_border_color #ff4da6
inactive_border_color #3d2454
bell_border_color #f25c7a
window_border_width 1.5pt
window_margin_width 2
single_window_margin_width 0
draw_minimal_borders yes
inactive_text_alpha 0.7

View File

@@ -0,0 +1,37 @@
// violet-chaton v2 — subtle glow shader for kitty
// Adds a soft bloom/glow around bright text characters
// Usage: kitty --override 'background_shader=~/.config/kitty/violet-chaton-glow.glsl'
void main() {
// Sample the original pixel
vec4 color = texture(image, texCoord);
// Only glow on non-background pixels (bright enough)
float brightness = dot(color.rgb, vec3(0.299, 0.587, 0.114));
if (brightness > 0.15) {
// Sample surrounding pixels for bloom
vec2 pixel = 1.0 / textureSize(image, 0);
vec4 glow = vec4(0.0);
float total = 0.0;
for (int x = -2; x <= 2; x++) {
for (int y = -2; y <= 2; y++) {
float weight = 1.0 / (1.0 + float(x*x + y*y));
glow += texture(image, texCoord + vec2(float(x), float(y)) * pixel) * weight;
total += weight;
}
}
glow /= total;
// Blend glow with original — subtle violet tint
float glowBrightness = dot(glow.rgb, vec3(0.299, 0.587, 0.114));
vec3 violetTint = vec3(0.85, 0.55, 1.0); // lilac-ish
vec3 glowColor = glow.rgb * violetTint;
// Mix: 85% original + 15% glow, only where text is
color.rgb = mix(color.rgb, color.rgb + glowColor * 0.12, smoothstep(0.1, 0.4, glowBrightness));
}
gl_FragColor = color;
}

View File

@@ -1,15 +1,15 @@
gui:
theme:
activeBorderColor: ['#ff79c6', 'bold'] # pink — fenêtre active
inactiveBorderColor: ['#6c7086'] # muted — fenêtre inactive
optionsTextColor: ['#e79cfe'] # purple
selectedLineBgColor: ['#3d2454'] # bg-high
selectedRangeBgColor: ['#3d2454']
activeBorderColor: ['#ff4da6', 'bold']
inactiveBorderColor: ['#716686']
optionsTextColor: ['#c9a0ff']
selectedLineBgColor: ['#5a3875']
selectedRangeBgColor: ['#5a3875']
cherryPickedCommitBgColor: ['#3d2454']
cherryPickedCommitFgColor: ['#8be9fd'] # cyan
unstagedChangesColor: ['#f38ba8'] # danger
defaultFgColor: ['#f8f8f2'] # text
searchingActiveBorderColor: ['#8be9fd', 'bold'] # cyan
cherryPickedCommitFgColor: ['#a4b4ff']
unstagedChangesColor: ['#f25c7a']
defaultFgColor: ['#f0eaf8']
searchingActiveBorderColor: ['#a4b4ff', 'bold']
nerdFontsVersion: '3'
border: rounded
git:

View File

@@ -2,21 +2,53 @@
command_timeout = 1000
add_newline = true
# ── Format ────────────────────────────────────────────────────────────────────
# Ligne 1 : infos → durée | mémoire | heure
# Ligne 2 :
format = """
$os $username$hostname$directory$git_branch$git_status$git_state$git_commit\
$python$nodejs$rust$golang$java$docker_context$package\
$fill\
$cmd_duration$memory_usage$time
$status$character"""
# ── violet-chaton v2 — palette reference ─────────────────────────────────────
# magenta #ff4da6 accent primaire
# lilac #c9a0ff accent secondaire
# mitsuri #9adba8 vert pastel (success, fresh)
# lavande #a4b4ff bleu-violet (info, fonctions)
# champagne #e8c87a or chaud (warning, langages)
# danger #f25c7a rouge vif
# text #f0eaf8 texte principal
# subtext1 #c4b8d4 texte secondaire
# subtext0 #9a8fad labels
# muted #716686 desactive
# surface2 #5a3875 selection
# ── Système ───────────────────────────────────────────────────────────────────
# ── Format — 3 lignes ───────────────────────────────────────────────────────
# Ligne 1 : separateur
# Ligne 2 : os | dir | git | langages | ... fill ... | duree | batterie | heure
# Ligne 3 : prompt caractere
format = """
[┌──](bold #5a3875) $os$sudo$username$hostname\
$directory$git_branch$git_status$git_state$git_commit\
$python$nodejs$rust$golang$java$docker_context$package$env_var\
$fill\
$cmd_duration$battery$time
[└─](bold #5a3875) $status$character"""
# ── Palette Starship ─────────────────────────────────────────────────────────
palette = "violet-chaton"
[palettes.violet-chaton]
magenta = "#ff4da6"
lilac = "#c9a0ff"
mitsuri = "#9adba8"
lavande = "#a4b4ff"
champagne = "#e8c87a"
danger = "#f25c7a"
text = "#f0eaf8"
subtext1 = "#c4b8d4"
subtext0 = "#9a8fad"
muted = "#716686"
surface2 = "#5a3875"
crust = "#1a0e27"
# ── Systeme ──────────────────────────────────────────────────────────────────
[os]
disabled = false
style = "bold #ff79c6"
style = "bold magenta"
format = "[$symbol]($style)"
[os.symbols]
@@ -43,38 +75,44 @@ Macos = " "
Windows = "󰍲 "
Unknown = " "
[sudo]
disabled = false
style = "bold danger"
symbol = "󰞀 "
format = "[$symbol]($style)"
[username]
style_user = "#9399b2"
style_root = "bold #f38ba8"
format = "[$user]($style)"
show_always = true
style_user = "subtext0"
style_root = "bold danger"
format = "[$user]($style)"
show_always = false
[hostname]
style = "#7f849c"
format = "[@$hostname]($style) "
ssh_only = false
style = "muted"
format = "[@$hostname ]($style)"
ssh_only = true
ssh_symbol = "󰣀 "
# ── Navigation ───────────────────────────────────────────────────────────────
# ── Navigation ───────────────────────────────────────────────────────────────
[directory]
style = "bold #e79cfe"
style = "bold lilac"
read_only = " 󰌾"
read_only_style = "#f38ba8"
read_only_style = "danger"
truncate_to_repo = false
truncation_length = 4
truncation_symbol = "…/"
format = "[ $path]($style)[$read_only]($read_only_style) "
# ── Git ──────────────────────────────────────────────────────────────────────
# ── Git ──────────────────────────────────────────────────────────────────────
[git_branch]
symbol = " "
style = "bold #ff79c6"
style = "bold magenta"
format = "[$symbol$branch]($style) "
[git_status]
style = "#8be9fd"
style = "mitsuri"
format = "([$all_status$ahead_behind]($style) )"
ahead = "⇡$count"
behind = "⇣$count"
@@ -88,85 +126,98 @@ deleted = "✘$count"
conflicted = "=$count"
[git_state]
style = "#f9e2af"
style = "champagne"
format = '\([$state( $progress_current/$progress_total)]($style)\) '
[git_commit]
style = "#6c7086"
style = "muted"
format = '[\($hash$tag\)]($style) '
tag_symbol = " 󰓼 "
only_detached = true
# ── Langages ─────────────────────────────────────────────────────────────────
# ── Langages ─────────────────────────────────────────────────────────────────
[python]
symbol = " "
style = "#f9e2af"
style = "champagne"
format = "[$symbol$version]($style) "
[nodejs]
symbol = " "
style = "#a6e3a1"
style = "mitsuri"
format = "[$symbol$version]($style) "
[rust]
symbol = " "
style = "#ff79c6"
style = "magenta"
format = "[$symbol$version]($style) "
[golang]
symbol = " "
style = "#8be9fd"
style = "lavande"
format = "[$symbol$version]($style) "
[java]
symbol = " "
style = "#f38ba8"
style = "danger"
format = "[$symbol$version]($style) "
[docker_context]
symbol = " "
style = "#8be9fd"
style = "lavande"
format = "[$symbol$context]($style) "
only_with_files = true
[package]
symbol = "󰏗 "
style = "#e79cfe"
style = "lilac"
format = "[$symbol$version]($style) "
display_private = false
# ── Droite (après $fill) ─────────────────────────────────────────────────────
# ── Env var custom — brain_name ──────────────────────────────────────────────
[env_var.brain_name]
variable = "brain_name"
style = "italic muted"
symbol = "󰧑 "
format = "[$symbol$env_value]($style) "
# ── Droite (apres $fill) ────────────────────────────────────────────────────
[fill]
symbol = " "
symbol = ""
style = "#3d2454"
[cmd_duration]
format = "[󱎫 $duration]($style) "
style = "#7f849c"
style = "subtext0"
min_time = 2000
[memory_usage]
disabled = false
threshold = 0
symbol = "󰑭 "
style = "#9399b2"
format = "[$symbol$ram]($style) "
[battery]
disabled = false
format = "[$symbol$percentage]($style) "
[[battery.display]]
threshold = 30
style = "bold danger"
[[battery.display]]
threshold = 70
style = "champagne"
[time]
disabled = false
style = "bold #6c7086"
style = "bold muted"
format = "[ $time]($style)"
time_format = "%H:%M"
# ── Ligne 2 ───────────────────────────────────────────────────────────────────
# ── Ligne 3 — le prompt ─────────────────────────────────────────────────────
[status]
disabled = false
style = "#ff79c6"
style = "danger"
format = "[$symbol$status ]($style)"
symbol = "✘ "
[character]
success_symbol = "[](bold #8be9fd)"
error_symbol = "[](bold #ff79c6)"
success_symbol = "[](bold mitsuri)"
error_symbol = "[](bold magenta)"

View File

@@ -12,10 +12,35 @@ max_width = 600
max_height = 900
[opener]
edit = [{ run = 'nano "$@"', block = true }]
edit = [
{ run = '${EDITOR:-nano} "$@"', block = true },
]
open = [
{ run = 'xdg-open "$@"', orphan = true },
]
reveal = [
{ run = 'xdg-open "$(dirname "$1")"', orphan = true },
]
[open]
rules = [
{ mime = "text/*", use = "edit" },
{ mime = "image/*", use = "open" },
{ mime = "text/*", use = "edit" },
{ mime = "image/*", use = "open" },
{ mime = "video/*", use = "open" },
{ mime = "audio/*", use = "open" },
{ mime = "application/pdf", use = "open" },
{ mime = "application/json", use = "edit" },
{ mime = "*/xml", use = "edit" },
{ name = "*.md", use = "edit" },
{ name = "*.yml", use = "edit" },
{ name = "*.yaml", use = "edit" },
{ name = "*.toml", use = "edit" },
{ name = "*.conf", use = "edit" },
{ name = "*.sh", use = "edit" },
]
[plugin]
prepend_previewers = [
# Image preview via kitty protocol (native dans kitty)
{ mime = "image/*", run = "image" },
]

View File

@@ -17,19 +17,22 @@ zinit light zsh-users/zsh-completions
export PATH="/usr/local/bin:$HOME/.local/bin:/usr/bin:$HOME/.atuin/bin:$PATH"
# ── Historique ────────────────────────────────────────────────────────────────
HISTSIZE=10000
HISTFILESIZE=20000
HISTSIZE=50000
HISTFILESIZE=100000
HISTFILE=~/.zsh_history
setopt HIST_IGNORE_DUPS
setopt HIST_IGNORE_SPACE
setopt HIST_FIND_NO_DUPS
setopt SHARE_HISTORY
setopt APPEND_HISTORY
setopt EXTENDED_HISTORY
# ── Options zsh ───────────────────────────────────────────────────────────────
setopt AUTO_CD # cd en tapant juste le nom du dossier
setopt CORRECT # correction de typos
setopt GLOB_DOTS # inclure fichiers cachés dans les globs
setopt GLOB_DOTS # inclure fichiers caches dans les globs
setopt NO_BEEP # silence
setopt INTERACTIVE_COMMENTS # commentaires en mode interactif
# ── Completion ────────────────────────────────────────────────────────────────
autoload -Uz compinit && compinit
@@ -37,44 +40,46 @@ zstyle ':completion:*' menu select
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}'
zstyle ':completion:*' group-name ''
zstyle ':completion:*:descriptions' format '%F{#e79cfe}── %d ──%f'
zstyle ':completion:*:descriptions' format '%F{#c9a0ff}── %d ──%f'
# ── Couleurs grep ─────────────────────────────────────────────────────────────
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
# ── eza (remplace ls) ────────────────────────────────────────────────────────
# ── eza (remplace ls) ────────────────────────────────────────────────────────
alias ls='eza --icons --color=always --group-directories-first'
alias ll='eza -l --icons --git --group-directories-first'
alias lt='eza --tree --icons'
alias la='eza -la --icons --git --group-directories-first'
alias lt='eza --tree --icons --level=3'
export LS_COLORS="$(bash ~/.local/share/violet-chaton/violet-chaton-ls-colors.sh)"
# ── bat (remplace cat) ───────────────────────────────────────────────────────
# ── bat (remplace cat) ───────────────────────────────────────────────────────
alias bat='batcat'
alias cat='batcat --paging=never'
export MANPAGER="sh -c 'col -bx | batcat -l man -p'"
# ── fd (remplace find) ───────────────────────────────────────────────────────
# ── fd (remplace find) ───────────────────────────────────────────────────────
alias fd='fdfind'
# ── Nouveaux outils ───────────────────────────────────────────────────────────
alias lg='lazygit' # git TUI
alias rg='rg --color=always' # ripgrep avec couleurs
alias disk='ncdu' # analyse disque
alias man='tldr' # man pages simplifiées
alias pipes='pipes.sh' # animation pipes
fuck() { eval "$(thefuck --alias 2>/dev/null)"; fuck "$@"; } # init paresseux
# ── Outils modernes ──────────────────────────────────────────────────────────
alias lg='lazygit'
alias rg='rg --color=always'
alias disk='dust' # analyse disque (remplace ncdu)
alias tl='tldr' # man pages simplifiees (man reste intact)
alias pipes='pipes.sh'
alias top='btop'
fuck() { eval "$(thefuck --alias 2>/dev/null)"; fuck "$@"; }
# ── fzf ──────────────────────────────────────────────────────────────────────
# ── fzf ──────────────────────────────────────────────────────────────────────
[ -f /usr/share/doc/fzf/examples/key-bindings.zsh ] && source /usr/share/doc/fzf/examples/key-bindings.zsh
[ -f /usr/share/doc/fzf/examples/completion.zsh ] && source /usr/share/doc/fzf/examples/completion.zsh
# Raccourcis fzf personnalisés
bindkey -r '^T' # libère Ctrl+T
bindkey -r '\ec' # libère Alt+C
bindkey '^G' fzf-file-widget # Ctrl+G → chercher un fichier
bindkey '^F' fzf-cd-widget # Ctrl+F → chercher un dossier
# Raccourcis fzf
bindkey -r '^T'
bindkey -r '\ec'
bindkey '^G' fzf-file-widget
bindkey '^F' fzf-cd-widget
export FZF_DEFAULT_COMMAND='fdfind --type f --hidden --follow --exclude .git --exclude .cache --search-path $HOME'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_ALT_C_COMMAND='fdfind --type d --hidden --follow --exclude .git --exclude .cache --search-path $HOME'
@@ -82,39 +87,188 @@ export FZF_DEFAULT_OPTS="
--height 40% --layout=reverse --border rounded --info=hidden
--preview 'batcat --color=always --style=plain --line-range=:80 {}'
--preview-window 'right:50%:wrap'
--color=bg+:#3d2454,bg:#341c4a,spinner:#ff79c6,hl:#8be9fd
--color=fg:#f8f8f2,header:#ff79c6,info:#e79cfe,pointer:#ff79c6
--color=marker:#a6e3a1,fg+:#f8f8f2,prompt:#e79cfe,hl+:#8be9fd"
--color=bg+:#5a3875,bg:#261537,spinner:#ff4da6,hl:#a4b4ff
--color=fg:#f0eaf8,header:#ff4da6,info:#c9a0ff,pointer:#ff4da6
--color=marker:#9adba8,fg+:#f0eaf8,prompt:#c9a0ff,hl+:#a4b4ff"
# ── zoxide (remplace cd) ──────────────────────────────────────────────────────
# ── zoxide (remplace cd) ────────────────────────────────────────────────────
eval "$(zoxide init zsh --cmd cd)"
# ── Fastfetch ─────────────────────────────────────────────────────────────────
alias fetch='fastfetch --config ~/.config/fastfetch/config.jsonc --raw <(chafa --size 44x22 --symbols vhalf --color-space rgb "$HOME/.config/fastfetch/violet-chaton-logo.png") --logo-width 52'
fetch
# ── direnv (charge .envrc automatiquement) ───────────────────────────────────
command -v direnv &>/dev/null && eval "$(direnv hook zsh)"
# ── zsh-autosuggestions ───────────────────────────────────────────────────────
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#6c7086"
# ── fnm (Node.js version manager — lazy load) ───────────────────────────────
if [ -d "$HOME/.local/share/fnm" ]; then
export PATH="$HOME/.local/share/fnm:$PATH"
eval "$(fnm env --use-on-cd --shell zsh)"
fi
# ── Fastfetch ────────────────────────────────────────────────────────────────
alias fetch='fastfetch --config ~/.config/fastfetch/config.jsonc --raw <(chafa --size 44x22 --symbols vhalf --color-space rgb "$HOME/.config/fastfetch/violet-chaton-logo.png") --logo-width 52'
[[ -z "$TMUX" && -z "$INSIDE_EMACS" && -z "$VSCODE_INJECTION" ]] && fetch
# ── zsh-autosuggestions ──────────────────────────────────────────────────────
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#716686"
ZSH_AUTOSUGGEST_STRATEGY=(history completion)
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=20
bindkey '^ ' autosuggest-accept # Ctrl+Space pour accepter la suggestion
bindkey '^ ' autosuggest-accept
# ── zsh-syntax-highlighting (couleurs violet-chaton) ─────────────────────────
ZSH_HIGHLIGHT_STYLES[command]='fg=#8be9fd'
ZSH_HIGHLIGHT_STYLES[builtin]='fg=#ff79c6'
ZSH_HIGHLIGHT_STYLES[alias]='fg=#e79cfe'
ZSH_HIGHLIGHT_STYLES[function]='fg=#8be9fd'
ZSH_HIGHLIGHT_STYLES[string]='fg=#e79cfe'
ZSH_HIGHLIGHT_STYLES[path]='fg=#f8f8f2,underline'
ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=#f38ba8,bold'
ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=#ff79c6'
ZSH_HIGHLIGHT_STYLES[comment]='fg=#6c7086,italic'
ZSH_HIGHLIGHT_STYLES[globbing]='fg=#f9e2af'
ZSH_HIGHLIGHT_STYLES[history-expansion]='fg=#f9e2af'
# ── zsh-syntax-highlighting (couleurs violet-chaton v2) ──────────────────────
ZSH_HIGHLIGHT_STYLES[command]='fg=#a4b4ff'
ZSH_HIGHLIGHT_STYLES[builtin]='fg=#ff4da6'
ZSH_HIGHLIGHT_STYLES[alias]='fg=#c9a0ff'
ZSH_HIGHLIGHT_STYLES[function]='fg=#a4b4ff'
ZSH_HIGHLIGHT_STYLES[string]='fg=#9adba8'
ZSH_HIGHLIGHT_STYLES[path]='fg=#f0eaf8,underline'
ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=#f25c7a,bold,standout'
ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=#ff4da6'
ZSH_HIGHLIGHT_STYLES[single-hyphen-option]='fg=#e8c87a'
ZSH_HIGHLIGHT_STYLES[double-hyphen-option]='fg=#e8c87a'
ZSH_HIGHLIGHT_STYLES[back-quoted-argument]='fg=#c9a0ff'
ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]='fg=#9adba8'
ZSH_HIGHLIGHT_STYLES[assign]='fg=#f0eaf8'
ZSH_HIGHLIGHT_STYLES[redirection]='fg=#ff4da6,bold'
ZSH_HIGHLIGHT_STYLES[commandseparator]='fg=#ff4da6'
# ── atuin (remplace Ctrl+R) ───────────────────────────────────────────────────
# ── Vi-mode — cursor shape adaptatif ────────────────────────────────────────
bindkey -v
export KEYTIMEOUT=1
# Beam en insert, block en normal
zle-keymap-select() {
case $KEYMAP in
vicmd) echo -ne '\e[1 q' ;; # block clignotant
viins|main) echo -ne '\e[5 q' ;; # beam clignotant
esac
}
zle -N zle-keymap-select
# Reset beam au demarrage de chaque prompt
zle-line-init() { echo -ne '\e[5 q' }
zle -N zle-line-init
# Garder les keybindings essentiels en mode insert
bindkey '^A' beginning-of-line
bindkey '^E' end-of-line
bindkey '^K' kill-line
bindkey '^U' backward-kill-line
bindkey '^W' backward-kill-word
bindkey '^Y' yank
bindkey '^R' history-incremental-search-backward
bindkey '^P' up-line-or-history
bindkey '^N' down-line-or-history
bindkey '^?' backward-delete-char
bindkey '^H' backward-delete-char
ZSH_HIGHLIGHT_STYLES[comment]='fg=#716686,italic'
ZSH_HIGHLIGHT_STYLES[globbing]='fg=#e8c87a'
ZSH_HIGHLIGHT_STYLES[history-expansion]='fg=#e8c87a'
# ── fzf pimped — git log picker, process killer ─────────────────────────────
# Git log browser — Ctrl+L en mode normal
fzf-git-log() {
git log --oneline --color=always --decorate --graph 2>/dev/null |
fzf --ansi --no-sort --reverse --preview \
'git show --color=always $(echo {} | grep -oP "[a-f0-9]{7,}" | head -1)' \
--preview-window='right:60%:wrap' \
--bind='enter:execute(echo {} | grep -oP "[a-f0-9]{7,}" | head -1 | tr -d "\n" | xclip -selection clipboard)+abort'
}
alias glog='fzf-git-log'
# Process killer — fzf powered
fkill() {
local pid
pid=$(procs --color=always 2>/dev/null || ps aux) |
fzf --ansi --header="Select process to kill" \
--preview-window='hidden' |
awk '{print $1}'
[ -n "$pid" ] && kill -9 "$pid" && echo "Killed $pid"
}
# ── Shell functions — violet-chaton toolkit ──────────────────────────────────
# mkcd — creer un dossier et y aller
mkcd() { mkdir -p "$1" && cd "$1" }
# Project switcher — fzf dans ~/Dev
proj() {
local dir
dir=$(find ~/Dev -maxdepth 3 -name ".git" -type d 2>/dev/null | sed 's|/.git$||' |
fzf --preview 'eza -la --icons --color=always --group-directories-first {}' \
--preview-window='right:50%')
[ -n "$dir" ] && cd "$dir"
}
# Palette preview — affiche violet-chaton v2 dans le terminal
colors() {
echo ""
echo -e " \033[1mviolet-chaton v2\033[0m"
echo ""
echo -e " \033[38;2;255;77;166m████\033[0m magenta #ff4da6"
echo -e " \033[38;2;201;160;255m████\033[0m lilac #c9a0ff"
echo -e " \033[38;2;154;219;168m████\033[0m mitsuri #9adba8"
echo -e " \033[38;2;164;180;255m████\033[0m lavande #a4b4ff"
echo -e " \033[38;2;232;200;122m████\033[0m champagne #e8c87a"
echo ""
echo -e " \033[38;2;242;92;122m████\033[0m danger #f25c7a"
echo -e " \033[38;2;232;200;122m████\033[0m warning #e8c87a"
echo -e " \033[38;2;154;219;168m████\033[0m success #9adba8"
echo -e " \033[38;2;164;180;255m████\033[0m info #a4b4ff"
echo ""
echo -e " \033[38;2;240;234;248m████\033[0m text #f0eaf8"
echo -e " \033[38;2;196;184;212m████\033[0m subtext1 #c4b8d4"
echo -e " \033[38;2;154;143;173m████\033[0m subtext0 #9a8fad"
echo -e " \033[38;2;113;102;134m████\033[0m muted #716686"
echo ""
echo -e " Gradient: \033[38;2;255;77;166m██\033[38;2;226;118;212m██\033[38;2;201;160;255m██\033[38;2;182;168;255m██\033[38;2;164;180;255m██\033[38;2;159;200;212m██\033[38;2;154;219;168m██\033[38;2;130;232;160m██\033[0m"
echo ""
}
# Yazi — wrapper qui cd dans le dernier dossier visite
y() {
local tmp="$(mktemp -t "yazi-cwd.XXXXXX")"
yazi "$@" --cwd-file="$tmp"
if cwd="$(cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then
cd "$cwd"
fi
rm -f "$tmp"
}
# Weather — meteo rapide
weather() { curl -s "wttr.in/${1:-Paris}?format=3" }
# Cheatsheet — raccourcis violet-chaton
hotkeys() {
echo ""
echo -e " \033[38;2;255;77;166m\033[1m── kitty ──\033[0m"
echo -e " \033[38;2;201;160;255mCtrl+Shift+\\\033[0m split vertical"
echo -e " \033[38;2;201;160;255mCtrl+Shift+-\033[0m split horizontal"
echo -e " \033[38;2;201;160;255mCtrl+Shift+Z\033[0m zoom (stack toggle)"
echo -e " \033[38;2;201;160;255mCtrl+Shift+←→↑↓\033[0m naviguer splits"
echo -e " \033[38;2;201;160;255mCtrl+Shift+1-5\033[0m layouts (tall/fat/grid/h/v)"
echo -e " \033[38;2;201;160;255mCtrl+Shift+T\033[0m nouvel onglet"
echo ""
echo -e " \033[38;2;255;77;166m\033[1m── zsh ──\033[0m"
echo -e " \033[38;2;154;219;168mEsc\033[0m vi normal mode (hjkl, w, b)"
echo -e " \033[38;2;154;219;168mi\033[0m retour insert"
echo -e " \033[38;2;154;219;168mCtrl+G\033[0m fzf fichier"
echo -e " \033[38;2;154;219;168mCtrl+F\033[0m fzf dossier"
echo -e " \033[38;2;154;219;168mCtrl+Space\033[0m accepter suggestion"
echo ""
echo -e " \033[38;2;255;77;166m\033[1m── commandes ──\033[0m"
echo -e " \033[38;2;164;180;255mproj\033[0m project switcher fzf"
echo -e " \033[38;2;164;180;255mglog\033[0m git log fzf"
echo -e " \033[38;2;164;180;255mfkill\033[0m process killer fzf"
echo -e " \033[38;2;164;180;255my\033[0m yazi (cd au dossier visite)"
echo -e " \033[38;2;164;180;255mcolors\033[0m palette violet-chaton v2"
echo -e " \033[38;2;164;180;255mweather [ville]\033[0m meteo rapide"
echo -e " \033[38;2;164;180;255mhotkeys\033[0m cette aide"
echo ""
}
# ── atuin (remplace Ctrl+R) ──────────────────────────────────────────────────
[[ -f ~/.atuin/bin/env ]] && source ~/.atuin/bin/env
command -v atuin &>/dev/null && eval "$(atuin init zsh --disable-up-arrow)"
# ── starship ─────────────────────────────────────────────────────────────────
# ── starship ─────────────────────────────────────────────────────────────────
command -v starship &>/dev/null && eval "$(starship init zsh)"