I used to use fish, and emacs. But when I switched to vim, I had to switch away from fish as well because of its lack of vi bindings. It is a little disappointing to go back to using bash, but as long as bash-completion is working, it's not really a big issue. Of course, I do miss the syntax highlighting. (I would use zsh, but it provides little benefit over bash out of the box and is slower (oh-my-zsh is unbearably slow to start, too).)
There are a few things that, while I understand why fish is missing them, I wish would be added:
- vi-mode, obviously
- Control+R. It is annoying to have to guess how much you must type before hitting the up arrow, instead of having it dynamically displayed. Same goes for zsh vi-mode's ? command.
- Well more of a removal, but the backslash in single-quoted strings. I'm used to typing '\', and that's not possible with fish. Additionally, to get one backslash in any sort of regex (sed, grep), you need four backslashes.
- Goes without saying, but bash-completion. Fish's completion is mostly history-based, which is great for repeatedly running the same command, but terrible for discoverability
- "$()" and any non-splitting command substitution. Currently, it is impossible to pass a multi-line string from a command substitution as a single argument. Which, it may be argued, should be done by piping, but sometimes it is useful to have stdin.
- More extensibility in general. I'd like to be able to customize my shell just as much as I can customize my WM. Probably more.
Honestly, it was easier to go back to using bash than I thought it would be -- it was almost a relief. fish just feels more polished and clean, especially with regard to escaping, but it misses some very important features.
Edit: I heard that there is a vi-mode now. Sounds interesting, but I don't really feel like installing it at the moment, and if I ever try another shell it'll probably be zsh.
As you said at the end, Fish does have this. I don't know if it's full-featured enough for you though.
> Control+R. It is annoying to have to guess how much you must type before hitting the up arrow, instead of having it dynamically displayed
When you start typing a command-line in Fish that matches a previously-typed command, it automatically shows the rest of the line as an available completion, and pressing ^F or the right arrow will complete it for you. The lack of this functionality actually really kills my ability to use any other shell.
> Currently, it is impossible to pass a multi-line string from a command substitution as a single argument
Not actually true. If you set IFS to '' then that disables command substitution line splitting. That said, it is not well-known and is rather awkward. This is a known pain point with Fish today.
> More extensibility in general. I'd like to be able to customize my shell just as much as I can customize my WM. Probably more.
It's really hard to know what you're asking for here. What isn't extensible enough for you? What do you wish you could do that you can't?
> When you start typing a command-line in Fish that matches a previously-typed command, it automatically shows the rest of the line as an available completion, and pressing ^F or the right arrow will complete it for you.
^R is more powerful, though; it matches at any point in previous commands, not just at the beginning.
> The lack of this functionality actually really kills my ability to use any other shell.
You can achieve that behavior in readline (which is used by bash, python shell, etc.) by changing the up/down arrows from previous-history/next-history to history-search-backward/history-search-forward. In ~/.inputrc:
In fish, you type "w" on the empty prompt and hit Up:
> echo w̲ow
Hit return to execute, or any motion keys to start editing. As long as you don't move sideways, you can repeatedly press up or down to navigate history. The underline is actually a highlight hinting at the substring match in the line.
The difference is that typing an additional character after having moved in the history will start editing, appending the character to the line, instead of appending to the criteria.
What I miss in all of them is looking for a fuzzy match instead of a substring match.
Discoverability. With fish i would have to type something that would be a good match to the command i want to re-run before pressing up. With bash i type ctrl+r and start typing and i can continue to type until it's narrowed down to the correct command.
No you can't. What I specifically described was the autocomplete of the line, not the ability to search history (which is manual complete instead of autocomplete).
Someone's gotta explain to me how and why oh-my-zsh is slow. I've never once experienced it being slow for me. In fact, I switched to prezto and it was unbelievably slow. I switched back to oh-my-zsh. Maybe I'm just not using it right...
OMZ got painfully slow for me when I used it with a lot of plugins and it was iterating over a lot of different file paths. It seems like ZSH has an issue when you're loading a mass amount of files...or maybe it's just the way OMZ is loading them?
Are you on a mac by chance? I ran into a really weird problem on OSX, still happens as of the latest Yosemite beta, where if you have a lot of system logs laying around, the shell takes an inordinately long time to start (10+ seconds) and do autocompletes.
If you clear out your logfiles by trashing /private/var/log/asl/*.asl, there's a pretty decent speedup.
Do you have any insight as to why this happens? It smells like some kind of log parsing to present messages on login, but I've never received any such messages, and a quick vgrep of the various profile/rc's never turned anything up.
ZSH only gets slow because of the customizations, which would be true in Bash as well. Both shells are relatively comparable, though there are still a few things you can do in ZSH that you can't do in Bash. If you keep your customizations relatively light-weight and don't iterate over too many files on each login session, you'll probably be OK.
I wrote a framework to help deal with the shell a little bit after getting fed up with OMZ's slowness: https://github.com/tubbo/homer
> I'm used to typing '\', and that's not possible with fish. Additionally, to get one backslash in any sort of regex (sed, grep), you need four backslashes.
This is a piece of technology we used to have and then somehow lost. Common Lisp uses ~ as the control character for format strings. C uses \ as the control charcter for raw strings, and % as the control character for format strings. HTML uses &. But regexps use \. JSON uses \. And JSON is a new format! \ was literally the worst possible choice. As soon as you have multiple formats sharing a control character, you start to need huge power-of-two runs of it in order to say what you mean.
Who thought it was a good idea to reuse control characters? \ is used in raw string definitions. It should not be used in any other format, if strings might be used to invoke that format. This is a clear case where every standard doing its own unique thing is the correct approach, but we seem to be moving in the other direction.
No, my bash is mostly the default that Debian provides (only semi-relevant option I have enabled is globstar, which is just the recursive globbing). I guess I didn't mean that zsh wasn't that much better, just that I didn't think it was that much better.
I may switch to zsh eventually, but I just switched shells and I don't really want to do it again very soon.
Debian uses dash actually, not bash. I rather prefer it that way since dash is strictly POSIX compliant. Takes some of the tediousness out of creating portable shell scripts.
> Goes without saying, but bash-completion. Fish's completion is mostly history-based, which is great for repeatedly running the same command, but terrible for discoverability
Fish has both kinds of completion. You can hit tab to get a list of possible completions (command-list based) if there is more than one, if there is only one possible command it will tab-complete. You can also customize this list.
There are a few things that, while I understand why fish is missing them, I wish would be added:
- vi-mode, obviously
- Control+R. It is annoying to have to guess how much you must type before hitting the up arrow, instead of having it dynamically displayed. Same goes for zsh vi-mode's ? command.
- Well more of a removal, but the backslash in single-quoted strings. I'm used to typing '\', and that's not possible with fish. Additionally, to get one backslash in any sort of regex (sed, grep), you need four backslashes.
- Goes without saying, but bash-completion. Fish's completion is mostly history-based, which is great for repeatedly running the same command, but terrible for discoverability
- "$()" and any non-splitting command substitution. Currently, it is impossible to pass a multi-line string from a command substitution as a single argument. Which, it may be argued, should be done by piping, but sometimes it is useful to have stdin.
- More extensibility in general. I'd like to be able to customize my shell just as much as I can customize my WM. Probably more.
Honestly, it was easier to go back to using bash than I thought it would be -- it was almost a relief. fish just feels more polished and clean, especially with regard to escaping, but it misses some very important features.
Edit: I heard that there is a vi-mode now. Sounds interesting, but I don't really feel like installing it at the moment, and if I ever try another shell it'll probably be zsh.