- Write a function called "fish_prompt" with "echo", "set_color", and whatever else you want.
- Put it in a file in fish's "functions" directory called "fish_prompt.fish"
That's it. Done. Every time fish needs to display a prompt, it does so by calling the "fish_prompt" function. Where does fish find the definition of a function called "foo"? In a file called "foo.fish".
Oh, do you want one of those very cool right-side-of-the-window prompts showing the date, maybe? Write a function called "fish_right_prompt.fish". There, you're finished.
There are a million little niceties like this that seem so obvious in retrospect. Fish is what happens when someone completely rethinks a shell from the perspective of how things should be done today after we have a few decades of experimentation under our belt.
Inside ‘function’ blocks, like the language syntax defines for any other type of function. I can then throw those functions into any file I chose.
Having special functions inside special files just creates annoying special cases I need to look up.
That's the only remotely magical thing added here: by convention, an autoload function named "foo" is defined in ~/.config/fish/functions/foo.fish.
Now I’ve got nothing against git hooks nor Fish per se, I just don’t see this particular model for defining behaviour to be convenient (eg what if you want to quickly change the prompt of a session without affecting other sessions?)
There might be more detail I’m missing and if that’s the case I apologise. But from what I’ve read thus far I’m not sold. It might appeal to others and good for them.
There's also this package, which the author admits only allows "slight" customization, to implement sessions: https://github.com/farzadghanei/fishion
https://murex.rocks/docs/commands/config.html
You can set prompt functions with that; strings, ints and Booleans too. And ‘config’ comes with descriptions for each configurable thing, choices of options in many cases, and an easy way to default back to shell defaults too. So it’s dead easy to play around configuring whatever you want (you never need to leave the shell to look up an option).
The shell has its own problems though but it’s an interesting alternative take for grouping shell config.
They don't. You have to define the function somehow, but fish doesn't care about how that happens. It's just that if it's not defined yet it'll try to load it from the file.
If you want, you can just do it all in config.fish, like you'd do it all in .bashrc for bash.
>what if you want to quickly change the prompt of a session without affecting other sessions?
Then you can redefine the function, just like you could switch the value of $PS1.
https://fishshell.com/docs/current/cmds/fish_command_not_fou...
So yeah you could make crazy stuff like Rail's routing and rendering DSLs that interpreted method names as programs.
It's meant to give you a nice error message like
"foo is missing. You can install it with 'apt install foo123'"
See:
- https://zsh.sourceforge.io/Doc/Release/Command-Execution.htm... for zsh
- https://www.gnu.org/software/bash/manual/bash.html#Command-S... for bash
You could make it run arbitrary things, but then you're quite clearly misusing it and e.g. there's no way to make it return a different status, fish will still view the command as failed.
Don’t get me wrong, I think the PS1 variable sucks. But I’m not convinced Fish’s solution is much better.
You can achieve PS1-like functionality “simply” by placing this bit of code somewhere in your startup:
function fish_prompt
set -l prompt_symbol '$'
fish_is_root_user; and set prompt_symbol '#'
echo -s $hostname (set_color blue) (prompt_pwd) \
(set_color yellow) $prompt_symbol (set_color normal)
end
It’s very verbose but it runs as fast as both bash’s PS1 and zsh’s PROMPT and is much easier for someone new to fussing with prompts to comprehend.Even as someone who doesn’t use fish day to day, I think fish’s prompt customization is much more approachable. If I had a powerline prompt I wanted to tweak, I’d know to start with `functions fish_prompt` to print out the current contents of the function and have the complete code to how the prompt is built. zsh requires a lot more reading and understanding of the prompt system before you can dig into how exactly it all works. IIRC, most dynamic bash prompts have similar issues. PS1 is just interpolated globals and color codes, creating a disconnect between the prompt variable and the shell functions that update it.
Honestly I just want a bash that saves every command entered, ever, and never deletes history. (I think I can spare the 100 kilobytes of disk space to hold command history forever.)
And fish doesn't get this right either, even though it's a complete no-brainer. Sigh.
So no, I'm not a fan of fish.
On the non-interactive scripting front, I've found fish to be a very competent language for it, but you're right, the error handling (among other things) are lacking compared to "real" languages
[0]: https://starship.rs
Is there a "killer app" for starship that you can't get from writing out your prompt in a fish shell script?
Here's mine: https://github.com/maximum-ethics/linode-caddy/blob/master/r...
It's a 3-line prompt with a timestamp on the first line, my username@host + pwd on the 2nd line, and the actual prompt with the cursor on the 3rd line. I'm now considering swapping the timestamp to the right side after that possibility was mentioned in other comments in this thread.
[0] https://github.com/olets/zsh-abbr
Alt+Up is great for recalling individual arguments, but am I missing something or is there no way to recall a whole previous line in-place, without overwriting what’s currently on the command line?
Seems to work in bash too, fwiw.
[0] https://fishshell.com/docs/current/interactive.html#copy-and...
On the other hand, you can disable all these advanced features in zsh and get something a bit closer to a bash readline shell, with a few extra features. That's what I use.
I feel torn because I really can empathize with making a clean break. But it also precludes a lot of people from making the shell a daily driver when your co-workers are shoving shell scripts your supposed to source into your env into github, lol.
I'm guessing someone probably has a plugin for it or people just get used to using autosuggest
Not sure if fish has this or not, but I use reverse search in bash exhaustively.
https://fishshell.com/docs/current/interactive.html#searchab...
I find it to be more polished and especially like the way it works with fragments (e.g. if you start typing "git log" and hit Option/Alt-ꜛ it will find commands prefixed with that whereas bash Control-R requires you to hit Control-R first and then type that, which isn't as handy when you realize you want to search halfway through).
There's no need to enter a separate mode via ctrl-r.
For scripting, I’d already set a personal policy that anything complicated use Python. For me there’s a fairly big difference between interactive shell sessions and scripts which solidly shifts the balance to a full language with a rich standard library and robust error handling. My scripts were edited using shfmt and shellcheck interactively anyway, so switching to Python wasn’t an increase in terms of tool support and the richer language means that I’m writing less code to get more functionality and especially error handling.