liljencrantz / crush

Crush is a command line shell that is also a powerful modern programming language.
MIT License
1.84k stars 35 forks source link

Option to setup prompt #31

Closed TatriX closed 4 years ago

TatriX commented 4 years ago

Currently prompt is hardcoded. It would be nice if one could at least have current working directory in it.

liljencrantz commented 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.

liljencrantz commented 4 years ago

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.

liljencrantz commented 4 years ago

A conflicting option would be to serialize and share some global state between processes in real time.

TatriX commented 4 years ago

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?

liljencrantz commented 4 years ago

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.

TatriX commented 4 years ago

Then maybe ability to dump/restore/merge state somehow?

liljencrantz commented 4 years ago

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.

TatriX commented 4 years ago

Works like a charm! If I want to color parts of that string, how would I do that?

liljencrantz commented 4 years ago

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.

liljencrantz commented 4 years ago

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 
}
TatriX commented 4 years ago

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
liljencrantz commented 4 years ago

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) "~"
TatriX commented 4 years ago

Perfect that you!