Zshell
zsh.org
zsh.org
Of course, I’ll never get back the time spent fiddling with my 1600 line Emacs configuration file.
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.
autoload -Uz compinit
compinit
zstyle ':completion:*' menu select 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!) source /usr/share/oh-my-zsh/lib/completion.zsh
source /usr/share/oh-my-zsh/lib/directories.zsh
source /usr/share/oh-my-zsh/lib/history.zsh
source /usr/share/oh-my-zsh/lib/spectrum.zsh
source /usr/share/oh-my-zsh/lib/key-bindings.zsh
[1]: https://starship.rs/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.
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.
> 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.
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.
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.
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.
Then again, I don't do much with the shell per se (not writing scripts or any thing like that).
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).
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.
[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]
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.
although TIL they use SourceForge for git. I'm sure there' s a story there: https://sourceforge.net/p/zsh/code/ci/master/tree/
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.
[1] https://zsh.sourceforge.io/Doc/Release/Expansion.html#Parame...
[2] https://zsh.sourceforge.io/Doc/Release/Expansion.html#Globbi...
[3] https://thevaluable.dev/zsh-expansion-guide-example/
[4] https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#Zsh-...
[5] https://zsh.sourceforge.io/Doc/Release/Shell-Builtin-Command... (see 'emulate' command)
[6] https://towardsdatascience.com/comparing-sh-bash-ksh-and-zsh...
[7] https://zsh.sourceforge.io/Doc/Release/Shell-Builtin-Command... (see 'zcompile' command)
[8] https://github.com/mafredri/zsh-async as an example, but also doable in bare Zsh