Closed TatriX closed 4 years ago
Good point.
On the face of it, this should be a very easy addition. There is already a crush namespace containing things related to this partcular shell instance, adding a crush:prompt member that is expected to be a closure that accepts no arguments and returns a string is easy.
The question is how to save this between invocations.
Crush currently has no init files, no config files, nothing.
Making the prompt configurable without making it possible to make that configuration stick between sessions seems... pointless. So I guess now is the time to figure out what crush should do when it comes to configuration and resource loading.
The "classical" approach would be that IF the shell is started in interactive mode, AND the file $XDG_CONFIG/crush/config.crush exists, run that file during startup.
A conflicting option would be to serialize and share some global state between processes in real time.
Well, I sometimes find myself in a situation where I have several old shell sessions with one environment/config and several new ones, and that's quite frustrating. On the other hand my Emacs session is always consistent regardless of number of open frames. Perhaps shared global state isn't the most robust idea though?
Indeed. When I wrote the fish shell, I opted to put many types of configuration into so called "universal variables", which were environment variables that were transparently shared across all your running shells as well as serialized to disk to so they were preserved across reboots. There were some performance and reliability issues with this feature, but for a shell with a heavy focus on interactivity, I feel it was a worthwhile trade off.
Crush aims to offer a lot more value to shell scripting, so I feel like that trade off makes less sense.
But ideally, it would be nice if one could have the cake and eat it.
Then maybe ability to dump/restore/merge state somehow?
OK, you can now configure the prompt by calling the crush:prompt
command:
crush:prompt {"{user}@{host} {wd}# ":format wd=(pwd) user=(user:me:name) host=(host:name) }
You can put the above into ~/.config/crush/config.crush
.
Works like a charm! If I want to color parts of that string, how would I do that?
Right now, there are no crush builtins for that.
You'd have to use an external command. The fish shell comes with a command called "set_color" that does exactly that.
There should be a term namespace with constants for all these things, but that doesn't exist yet.
I've added a term namespace containing a handfull of common ansi escapes. So now you can write something like
crush:prompt {
"{green}{user}{normal}@{host} {green}{wd}{normal}# ":format wd=(pwd) user=(user:me:name) host=(host:name) green=term:green normal=term:normal
}
Very nice! Now I'm trying to replace /home/$USER
with ~
. So I tried something like the following, but:
$ re"home":replace (pwd) "-"
Error: Expected argument "text" to be of type String, was of type file
The problem is that your current directory (as returned by pwd) and your home directory (as returned by user:me:home) are both files, not strings. You can convert a file to a string using e.g. convert (pwd) string
.
So the full command then becomes:
(re:new (convert user:me:home string)):replace (convert (pwd) string) "~"
Perfect that you!
Currently prompt is hardcoded. It would be nice if one could at least have current working directory in it.