Prompt: use colors to show terminal context
This was extracted from #231
The Desire
I'm often surrounded by identical-looking terminal windows. Even though they look the same, they all connect to different containers and remote hosts. It gets confusing.
Could Prompt automatically use color to distinguish each terminal window?
So, when entering my Fedora container, Prompt would automatically set a bluish palette:
And, after sshing to my remote host, it would automatically switch to the scary red colors I'd like:
A Minimum Viable Implementation
Here's how I'd implement this feature.
Detecting the remote
Most containers and remote hosts set their terminal names to something like user@container
or user@host
.
When Prompt changes the tab title to match (bronson@fedora
), it would use the host part of the string (fedora
) to look up a palette to use. If found, it would switch to that palette. If not, it would use the profile's palette exactly as it works now.
NOTE: Prompt currently lets the user rename tabs, but this wouldn't be an issue. The remote-supplied hostname still appears at the end of the tab's new name.
Specifying the palette
Now we know that the tab should be displayed using the fedora colors, but how does Prompt know what those colors actually are? There needs to be a mapping from the hostname to a palette name.
These could be YAML files, formatted something like this:
hosts:
fedora: 'Seafom Pastel'
ubuntu: 'Paradiso Dark'
aich: 'Alien Blood'
myst: 'Monokai Soda'
If a tab is named user@myst
, then display it in Monokai Soda.
This config file is meant to be extensible while preserving forward and backward compatibility.
Config file search pattern
OK, but were would these config files live, and where would they come from? The user? The app that assembled the container? The host's distro? Hopefully all of these.
When trying to find a match for a hostname, Prompt would start by reading the user's personal settings from ~/.config/prompt/palettes.yml
. If a match is found here, the search terminates and the palette is set.
Otherwise, Prompt continues searching in ~/.config/prompt/palettes/*.yml
, reading each file in alphabetical order. Again, first match terminates and sets the palette. Automated tools could place files in this directory while minimizing the risk of conflicting with each other.
Prompt would then search /etc/prompt/*.yml
for global mappings and, finally, /usr/share/config/prompt/*.yml
for mappings supplied by the user's Linux distribution.
If Prompt gets to the end and no match is found, then it sets the tab's palette to the default specified by the profile, exactly as it works now.
To summarize, the config file search order would be:
~/.config/prompt/palettes.yml
~/.config/prompt/palettes/*.yml
/etc/prompt/palettes.yml
/etc/prompt/palettes/*.yml
/usr/share/config/prompt/*.yml
NOTE: we probably want to have a timeout of 500ms (or something) so we don't stall for multiple seconds waiting for a balky NFS server or failing disk. If the timeout fires before a palette is found, the user just gets the profile's regular palette. Prompt is still 100% functional.
That's it
I think that's everything necessary to provide this feature.
Some decisions made to keep this implementation simple:
- No UI changes are required.
- There's no file monitoring. Each time a tab name changes, the config files are re-read in order.
- The configuration data doesn't get cached. Linux can read hundreds of config files out of the buffercache in a fraction a second.
- If config files have errors, they're silently skipped.
- If config files contain unrecognized keys, additional data, or specify unknown palettes, then this data is silently ignored.
- No regexes or "smart" matching. Just plain UTF8 string matching.
- All data is local. It would be difficult for an adversarial host to abuse this feature.
Still To Consider
Localized palette names?
How stable are palette names? Will they be localized?
If this becomes an issue, it might be enough to allow each localized name in the config file:
hosts:
aich: ['Alien Blood', 'Sangre Extraterrestre', 'інопланетна кров']
Another solution would be to expose unique palette IDs, but this would require changing existing code.
Global disable switch?
If you don't have any config files, then this feature is disabled and Prompt will work exactly as before. But, what if distros start including Prompt config files? (and I hope they do.)
It probably makes sense to put a disable switch in the config files.
For example, creating this file in ~/.config/prompt/palettes.yml
could disable automatic colors, even if lots of other config files exist.
automatic-terminal-colors: false
End Result
This feature would reduce my tendency to type into the wrong terminal and look nicer too.
Who would code
I haven't touched C in decades but, if we can find a decent implementation, I could code it.