mc, yazi: two mouse-driven TUI file managers, themed by the terminal

Neither gets per-wallpaper files. Both draw with the 16 ANSI colours, so
they follow ghostty's palette the moment theme-apply reloads it — no
restart and none of the reflow a GTK theme switch causes.

mc uses a -defbg skin (paints on the terminal's own background); yazi gets
an ANSI-named theme and stylix's hex-writing yazi target is disabled.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-08-19 19:48:09 +01:00
parent d83b830c1c
commit 90db91f178
2 changed files with 119 additions and 0 deletions

View file

@ -30,6 +30,119 @@ in
};
};
# ── File managers: two TUIs, both mouse-driven ────────────────────────
# Neither is themed per wallpaper, on purpose. Both draw with the
# terminal's 16 ANSI colours, so they inherit ghostty's palette the
# instant theme-apply reloads it — no per-wallpaper files, no restart,
# and none of the full-reflow jank a GTK theme switch causes.
#
# Neither can drag a file into a browser: a TUI has no wayland surface,
# so it can never start a drag. Nemo stays installed for that.
# Midnight Commander — the stronger mouse: double-click opens (do_enter),
# the menu bar and F-key bar are clickable, the panel divider drags.
programs.mc = lib.mkIf isDesktop {
enable = true;
settings.Midnight-Commander = {
# The -defbg skins paint on `default` — the terminal's own background
# — and take foregrounds from the 16-colour palette. That is what
# makes this follow the wallpaper for free. The plain skins hardcode
# a blue background and would sit there unchanged.
skin = "modarcon16-defbg";
};
};
# Yazi — lighter mouse (click, scroll), nicer layout, image previews.
programs.yazi = lib.mkIf isDesktop {
enable = true;
enableFishIntegration = true;
# Off by default; yazi is keyboard-first.
settings.mgr.mouse_events = [ "click" "scroll" ];
# Colour NAMES, not hex — the whole point. "reset" means the terminal's
# own fg/bg, and the eight names map onto ghostty's palette, which our
# ghostty.conf fills from the wallpaper:
# black=base00 red=base08 green=base0B yellow=base0A
# blue=base0D (accent) magenta=base0E cyan=base0C
# gray=base05 (text) darkgray=base03 (borders)
theme = let
accent = "blue";
dim = "darkgray";
text = "gray";
on = c: { fg = "black"; bg = c; };
fg = c: { fg = c; };
both = c: { fg = c; bg = c; };
in {
mgr = {
cwd = fg accent;
find_keyword = { fg = "green"; bold = true; };
find_position = fg "magenta";
marker_selected = both "yellow";
marker_copied = both "green";
marker_cut = both "red";
border_style = fg dim;
count_copied = on "green";
count_cut = on "red";
count_selected = on "yellow";
};
indicator.current = { bg = dim; bold = true; };
tabs = {
active = (on accent) // { bold = true; };
inactive = { fg = accent; bg = "black"; };
};
mode = {
normal_main = (on accent) // { bold = true; };
normal_alt = { fg = accent; bg = "black"; };
select_main = (on "green") // { bold = true; };
select_alt = { fg = "green"; bg = "black"; };
unset_main = (on "yellow") // { bold = true; };
unset_alt = { fg = "yellow"; bg = "black"; };
};
status = {
progress_label = fg text;
progress_normal = fg text;
progress_error = fg "red";
perm_type = fg accent;
perm_read = fg "yellow";
perm_write = fg "red";
perm_exec = fg "green";
perm_sep = fg "cyan";
};
pick = { border = fg accent; active = fg "magenta"; inactive = fg text; };
input = { border = fg accent; title = fg text; value = fg text; selected.bg = dim; };
completion = {
border = fg accent;
active = { fg = "magenta"; bg = dim; };
inactive = fg text;
};
tasks = { border = fg accent; title = fg text; hovered = { fg = text; bg = dim; }; };
which = {
mask.bg = "black";
cand = fg "cyan";
rest = fg "yellow";
desc = fg text;
separator_style = fg dim;
};
help = {
on = fg "magenta";
run = fg "cyan";
desc = fg text;
hovered = { fg = text; bg = dim; };
footer = fg text;
};
filetype.rules = [
{ mime = "image/*"; fg = "cyan"; }
{ mime = "video/*"; fg = "yellow"; }
{ mime = "audio/*"; fg = "yellow"; }
{ mime = "application/zip"; fg = "magenta"; }
{ mime = "application/gzip"; fg = "magenta"; }
{ mime = "inode/directory"; fg = accent; bold = true; }
{ name = "*"; fg = "reset"; }
];
};
};
# Ghostty — stylix's ghostty target writes the colour theme.
programs.ghostty = lib.mkIf isDesktop {
enable = true;