I like the path completion in zsh, being able to type '~/.c/x/x', hit tab and have it autocomplete to '~/.config/xsettingsd/xsettingsd.conf' is a lot nicer than `~/.c', tab, tab, add an 'o', tab again, 'x', tab, tab, 's', tab, tab.
I find that feature also interacts very nicely when editing parallel paths. E.g.:
prog/libs/foo┃/src/CMakeList.txt Start with one path
prog/libs/some┃/src/CMakeList.txt Edit the middle part
prog/libs/somelongname/src/CMakeList.txt┃ Press tab, completes middle and jumps to end
I was also thrilled when I noticed zsh contextually skipping some potential completions that I'd already had on my command line. E.g., if I have files `aaa` and `aab` in a directory, then hitting tab on
git add aaa a┃
will do the right thing and immediately complete to `aab` without further prompting. (Better yet, it also does that if I'd added `aaa` with a previous command!)
Emacs' standard find-file function also does it, and I've since gotten so used to it that it's very irritating when I have to use a piece of software that doesn't complete like that.
There have been decades of work on file name completion put into Emacs, nothing I’ve seen comes close. Currently I’m using add on packages vertigo, orderless, marginalia, consult, embark, and corfu to handle completion. These packages all work together to produce a crazy good setup, but in the past I’ve used helm, ivy, icicle, and vanilla Emacs. Every one of these open source completion frameworks works great.
Of course, I’ll never get back the time spent fiddling with my 1600 line Emacs configuration file.
Oh man, I've tried using Ivy, but it's terrible. I tried typing '~/.c/r/r' to quickly get to my RetroArch config file, and I immediately got stuck in '~/.cache'. With Vertico it Just Works (R). Icomplete (whose vertical mode is part of Emacs now) can also do it, but I prefer Vertico's UX as the way Return and 'C-j' work in Icomplete is opposite to what I naturally expect and rebinding them doesn't work that well.
I also use zsh for years and did not know that. What I like this: Actually having completions shown in the screen and being able to navigate them with tabs. I think that is not a default behavior, but that is what oh-my-zsh does for you in its default setup. Does someone have more insight on that?
I did not know about this, but I use https://github.com/wting/autojump, so I am not super sad that I missed something that hold me back severely. But good to know.
Somewhat related is "Oh My ZSH!" which is basically zsh on steroids, it's always one of the first things I install on a new computer. It gives things like new colors, themes, plugins, and more. Highly recommend you check it out.
I used OhMyZsh! for a long time and really liked it, but now I moved to Starship [1]. However I noticed I still missed some of the "steroids" that OhMyZsh brought so I keep it installed in my system and I only source the plugins I need in the .zshrc:
Needs a (1990) tag. It always amuses me when people, to this day, say "eh, not going to use that newfangled zsh, bash was good enough for my forefathers and is good enough for me" - not realizing zsh was released less than a year after bash.
I tried to give zsh a shot as a bash replacement but ultimately returned to bash.
My main pain point was that zsh was really difficult to configure out of the box and a lot of the completions were much slower (cpu/wall time) than the equivalent completion in bash.
I'm sure some of that was simply ignorance on my part.
Bash improved a lot since the early 2000s, when I first assessed my options for shells and settled on zsh. As an interactive shell, zsh did more, and better, than any other shell I tried. Maybe it was slow, but not enough to matter at the time I used it.
I guess that bash being the default practically everywhere nowadays made it so that it got a lot of love. For example, it is common to see command line tool come with bash completion files, less so with zsh.
Also, while bash got better support where it matters, zsh mostly got bloat in the form of oh-my-zsh and the likes. You don't have to use it, but if you do, you tend to have all kinds of fancy stuff that affects performance. Also, if you want something fancy, you have fish now.
I still use zsh (without oh-my-zsh) out of habit, but if I had to start over now, I would probably stay with bash, or maybe use fish, but not zsh.
zsh has better completion, command line editing capabilities, and language features. It's not even close. I can port my bash configuration to zsh in mere minutes, but it's impossible to port my zsh configuration to bash. The reason is simple. Bash just lacks so many features.
> For example, it is common to see command line tool come with bash completion files, less so with zsh.
It's rare for bash to complete anything but filenames. zsh gives me subcommands and flags with descriptions.
> Also, while bash got better support where it matters, zsh mostly got bloat in the form of oh-my-zsh and the likes.
zsh is a well-maintained project. It makes no sense to ignore that and instead fault them for oh-my-zsh's shortcomings, as if it has anything to do with upstream zsh. zsh doesn't rely on oh-my-zsh for any of its features.
This. Plus it's not even slow. My zsh config does x5 as much as bash while being faster.
If you want it fast keep away from plugin managers like oh-my-zsh and async load as much as you can.
> It's rare for bash to complete anything but filenames. zsh gives me subcommands and flags with descriptions.
I think that hasn't been true for a very long time, although it might be that I'm biased because I've been installing the "bash completion" package alongside bash on all my systems. (In my case "apt-get install bash-completion".)
bash typically completes commands, sub-commands, flags, and file/directory names for me. It is also common for new tools to ship with bash-completion support, often missing support for other shells.
I have tried bash-completion and it doesn't make much of a difference. It's already underwhelming that bash requires third party completion frameworks to get completion working beyond command names, variable names, and filenames. But even with bash-completion, completion for the most common commands are either missing or incomplete.
Take grep, for example. I only get --binary-files, --context, and --null. That's only three out of a few dozen options. Or tar, which only shows c, t, and x. For ls, probably the most frequently used command, only --color and --help. Git requires another third party completion framework. Unfortunately, those are the best case examples. For other commands like vim or emacs, option completion is missing. The same even goes for bash builtins. And don't get me started on completion behavior. Though I will say the lack of descriptions for each option takes away half the usefulness of shell completion.
zsh can actually use completion functions written for bash. But I never felt the need.
Your reply suprises me, when I run "grep --[TAB]" I go a whole bunch of flags.
I'd probably suggest that bash-completion being a "third party" package is a good thing, it's entirely external to the bash project and that's good. It means we're not pinned to releases alongside the shell. After all it has support for ssh, grep, and many more tools they should be able to contribute to one location and the shell-project itself would be thee wrong one.
bash completion provides a framework for adding completion to "stuff", and the git-package on Debian uses that to drop a file into `/usr/share/bash-completion/completions/` so there's no need for any other third party framework:
1. Install git
2. Install bash completion package
3. Everything should just work.
Anyway I guess a lot of this will depend on the system you're using, and how their packages are configured, but I don't personally believe that bash completion is in a terrible state.
I have had someone sing the praises of zsh, tried it, was like "that isn't so much better than bash" and went back. Then I heard about oh-my-zsh, tried zsh with oh-my-zsh, and stayed. I still think it's not a big deal, but it is an improvement.
I'm pretty much in the same boat. Heck, once I learned that BSD's /bin/sh gives you history (and I think filename completion?) I switched to that when I'm on BSD (I don't feel strongly enough about it on Lnux, which often uses dash and is more of a headache).
Then again, I don't do much with the shell per se (not writing scripts or any thing like that).
Personally, I don’t have a reason to move from bash. Bash, zsh, fish looks very similar to me. But they do have subtle differences that require learning. And I don’t see a point.
The only reason I moved to zsh is because I'm lazy, and macOS ships with it by default.
Easier to change my other systems to zsh than fight it, but I've not really done anything different except some minor notices that it seems to autocomplete a tiny bit better (but that may be due to oh my zsh).
I don't think zsh requires any learning as it's mostly adding to bash and is compatible, no?!
In any case, fish offers all the conveniences out-of-the-box, which makes it superior to zsh, to me. It's just a nice and ready drop-in, no configuration required. Like, I can't live without alt-H to pop open the man page for command at cursor, and alt-S to toggle sudo, anymore. Otherwise, for 95% of my use, the differences are unnoticeable, and if I need the arcane bash hacks, well, I drop into a bash shell. Tho, I do miss the <<< and still use bash for scripts. Also, I don't have fish set as default shell outside of the GUI terminal.
With bash and all of it's improvements over its' predecessors and rivals (csh), I'm not sure what need there is to throw resources at new shells such as zsh and fish etc?
[pulling my tongue out of my cheek, I honestly never have found a reason to use anything other than bash -but that's just me]
Bash and Zsh are both just about as old as one another. Zsh came out less than a year after Bash.
Both derive most of their improvements from ksh, which is why they look superficially similar and many scripts are cross-compatible. Zsh arguably took the language improvements much further than Bash, ie look at [1] and [2] in https://news.ycombinator.com/item?id=39642678.
Bash made the understandable but very regrettable decision of being only a superset of POSIX sh, which means it carries along all the footguns, like word splitting by default.
Zsh is also eminently flexible and scriptable, with many core features (like most line editor functionality) exposed as hooks that custom scripts can extend or change.
Zsh is also notably faster than Bash.
It's one of the great disappointments of open source history that Bash largely took off as the default shell everywhere and the default shell scripting language, despite Zsh being superior in just about every way.
Zsh is quite a bit nicer than Bash for scripting. For one, parameter expansion doesn't word-split by default, so you don't have to haphazardly quote everything. There's also some really powerful features, like the parameter expansion flags [1] and filename generation (globbing) flags [2] that can be combined to do very flexible things. [3]
Zsh also bundles a ton of useful modules that can be used to do things pretty outside the box. Eg, there's a module for creating and controlling a hidden PTY. [4]
Zsh also has some quite nice shorthands for basic grammar, like compact loops and conditionals. Eg, you can do:
for foo in bar*;
do_stuff # you don't need the do..done here for single-line for-loops
Also, while Zsh diverges from POSIX sh in some areas (like word splitting), Zsh has sh- and Bash-compatible emulation modes, which can even be mixed together within single scripts (eg functions can set their emulation mode and shell options locally, or files can be sourced or commands run with different emulation modes prefixed). [5]
Lastly, Zsh has this weird reputation for being slow, because the configuration frameworks like oh-my-zsh are absolute dogs. But it's actually among the faster shells, with very respectable script performance that's squarely ahead of Bash. [6] Interactive performance can also be fantastic if you use a less hungry framework or write your own config, and Zsh has many tools to improve speed further, like support for pre-compiling source files [7] and pretty good support for async workers. [8]
Zsh has also been around about as long as Bash, and runs on every major platform and is available in just about every platform's package manager. So the cliche about Bash being available everywhere is just as true for Zsh. Zsh is honestly a much better replacement for scripting, but Bash benefits from already established traction and by being the default shell on most Linux distros.