# Midnight Commander: TUI file manager. Its config (ini, panels, F2 user menu, # mc.ext.ini file associations) is opinionated but generic, so it lives in the # public baseline alongside the other desktop tooling. The only personal value # is the right-panel start dir, exposed as an option defaulting to the # consumer's own home. mc.ext.ini keeps archive browsing but routes every other # type to xdg-open, so the app choices live in xdg.mimeApps (baseline: mime.nix). # # ouch backs the F2 pack/unpack entries (one tool, archive format inferred from # the extension), so it ships with mc to keep the menu self-contained. # # mc honours XDG natively: config in $XDG_CONFIG_HOME/mc (the files below), # mutable runtime state (history, cursor positions) in $XDG_DATA_HOME/mc — no # env vars needed. `ini` sets auto_save_setup=false so mc never rewrites these # read-only store symlinks on exit. # # The F2 menu is a `types.lines` option, not a baked source file, so consumers # can extend or replace it. The shipped menu is a `mkBefore` definition (stays # first, ahead of appended entries), NOT a `default` — a `default` is dropped # the moment a consumer adds a definition, which would lose the base. As a real # definition it merges: `local.mc.menu = "…";` appends after the base entries; # `lib.mkForce "…"` replaces it wholesale. { config, lib, pkgs, ... }: { options.local.mc = { otherDir = lib.mkOption { type = lib.types.str; default = config.home.homeDirectory; defaultText = lib.literalExpression "config.home.homeDirectory"; description = "Startup directory for mc's other (right) panel."; }; menu = lib.mkOption { type = lib.types.lines; description = '' Contents of mc's F2 user menu. The shipped baseline is a mkBefore definition, so a plain assignment appends entries after it; use lib.mkForce to replace it entirely. ''; }; extIni = lib.mkOption { type = lib.types.lines; description = '' Contents of mc's mc.ext.ini (file-type associations driving Enter/F3/F4). The shipped baseline keeps mc's archive browsing and delegates every other type to xdg-open, so the actual app is the XDG mimeapps default. Like `menu`, it is a mkBefore definition: append a same-named section to override one key (mc merges same-named sections, last key wins), or use lib.mkForce to replace it entirely. ''; }; }; config = { home.packages = [ pkgs.mc pkgs.ouch ]; local.mc.menu = lib.mkBefore (builtins.readFile ./assets/mc/menu); local.mc.extIni = lib.mkBefore (builtins.readFile ./assets/mc/mc.ext.ini); xdg.configFile = { "mc/ini".source = ./assets/mc/ini; "mc/menu".text = config.local.mc.menu; "mc/mc.ext.ini".text = config.local.mc.extIni; # Generated (not a static asset) so other_dir tracks the option instead of # baking in a personal path. "mc/panels.ini".text = '' [New Left Panel] display=listing reverse=false case_sensitive=true exec_first=false sort_order=name list_mode=full brief_cols=2 user_format=half type name | size | perm | mtime user_status0=half type name | size | perm user_status1=half type name | size | perm user_status2=half type name | size | perm user_status3=half type name | owner | group | ctime user_mini_status=true list_format=user [New Right Panel] display=listing reverse=false case_sensitive=true exec_first=false sort_order=name list_mode=full brief_cols=2 user_format=half type name | size | perm | mtime user_status0=half type name | size | perm user_status1=half type name | size | perm user_status2=half type name | size | perm user_status3=half type name | owner | group | ctime user_mini_status=true list_format=user [Dirs] current_is_left=true other_dir=${config.local.mc.otherDir} ''; }; }; }