NixOSmimeAppsUI is a terminal UI for managing MIME associations declaratively in a NixOS/Home Manager repository.
This v1 is intentionally opinionated:
- It is designed around a NixOS repo shaped like
/home/jajpater/Develop/nixos-config. - It uses a tool-managed Nix file as its source of truth.
- It focuses on MIME-first editing: choose a MIME type, set a default app, block noisy handlers, and optionally strip specific MIME claims from desktop entries.
- Discovers
.desktopfiles from common XDG application directories. - Builds a MIME-to-handler index from
MimeType=...entries. - Stores declarative state in
home/modules/generated-mimeapps.nixby default. - Shows a Textual TUI with vim-style navigation and a live Nix preview.
This tool does not generate your full MIME setup.
It writes a file called generated-mimeapps.nix that contains only the
changes you made in the TUI.
That means:
- if a MIME type is not listed in
generated-mimeapps.nix, the tool did not change it - your normal hand-written Nix/Home Manager config is still the main setup
- the generated file is a delta, not a full replacement
In your NixOS repo this is meant to work together with your existing
home/modules/xdg.nix:
xdg.nixstays your hand-written base configgenerated-mimeapps.nixadds tool-managed changes on top- if both files mention the same MIME type, the generated file becomes the tool-managed version for that MIME type
So if you only see this:
mimeDefaults = {
"text/markdown" = [ "LazyVim-neovide.desktop" ];
};that does not mean this is your whole MIME configuration.
It only means:
- you changed
text/markdownin the TUI - the tool has not written changes for other MIME types
- all other MIME types still come from your normal config unless you edit them
This sets the default app for a MIME type.
Example:
"application/pdf" = [ "org.gnome.Evince.desktop" ];This means PDFs should open by default in Evince.
This adds apps as valid choices for a MIME type.
Use this when you want an app to appear in "Open With", even if it is not currently offered there.
This removes apps from the association list for that MIME type.
Use this when an app keeps showing up for a file type and you do not want it there.
This is for a different problem.
Sometimes an app advertises the wrong MIME types in its own .desktop file.
For example, a browser may claim it can open PDFs.
In that case, changing only mimeapps.list is not always enough. A desktop
override lets the tool generate a local replacement .desktop file that keeps
the app but rewrites the MimeType= line.
Use this only when you want to change what the app itself claims to support.
This is helper data used to build those rewritten .desktop files.
If desktopOverrides is empty, then desktopMetadata will usually also be
empty and nothing special happens.
There are two layers:
-
XDG association rules This is
mimeDefaults,mimeAdded, andmimeRemoved. This controls defaults and choices. -
Desktop entry rewriting This is
desktopOverrides. This changes what an app itself claims to handle.
Most of the time you only need layer 1. Use layer 2 only for noisy or wrong app registrations.
python -m nixosmimeappsui.cliOr with Nix:
nix runWeb UI:
nix run -- --webThen open:
http://127.0.0.1:8787
j/k: move in the focused listh/l: switch between MIME list and handler list/: search the currently focused panea: toggle explicit added association for selected appr: remove explicit handler from the selected MIME typed: set selected handler as defaultx: toggle blocked handler for selected MIME/handler pairo: toggle MIME stripping override for selected MIME/handler pairs: refresh Nix previeww: write generated Nix fileq: quit
The generated Nix file contains three sections:
mimeDefaultsmimeAddedmimeRemoveddesktopOverrides
It may also contain desktopMetadata, which is support data for generated
desktop-entry overrides.
The web UI is intentionally small.
It gives you:
- a MIME type list with search
- a handler list with search
- buttons for default / added / removed / override actions
- a live preview of the generated Nix file
- a save button
It uses the same backend logic as the TUI, so both interfaces write the same kind of output.
The file is intended to be imported by a hand-written Home Manager module later.
