DEV Community

Discussion on: Zsh Tricks to Blow your Mind

Collapse
 
moopet profile image
Ben Sinclair

I use zsh these days because it comes on my work Macbook, and I've set up my own computers to roughly match the environment. I think it's a good shell.

I see a lot of posts about how it's great because it does such-and-such and maybe it's late and I've just watched some people land another robot on Mars, but I want to speak up for the other shells here. So here I go:

zsh isn't the default shell in newer MacOS releases because it's better than bash, it's there because Apple don't want to use GPL software. It seems like a massive improvement to Apple users because the version of bash that their systems was running was years and years out of date.

  1. The take command does not exist for me. It isn't built into zsh - or not on my copies of it anyway. It would seem like a pretty random thing to include. I'd never heard of it because it's literally something I never do, and if I did, I'd write take() { mkdir $1 && cd $1 } in my startup script, which will do what you want and work in most other shells too.

  2. This is neat, but I find it more annoying than useful, tbh.

  3. I never use this, partly because what happens if you've got a directory called ls? You have to remember to use cd sometimes which for me is worse. Think you won't have directories with the same names as commands? You will when you build any commands from source :)

  4. rename does this as well, and doesn't need zsh.

  5. That's what bc is for :)

  6. Ok, plugins (mostly from oh-my-zsh) are what people mostly seem to like.

  7. This does not work for me (I've just tried it on Mac and Linux) and I suspect it's because ctrl-q is already a terminal flow control command, so trying to shadow it in the shell is going to fail most of the time. My normal flow for this would be ctrl-a # enter to comment out the line but leave it in my history. That works on bash, and while it doesn't technically work that way on zah, it's effectively the same because the shell can't find an executable starting with a hash so it just reports it as command not found. As a rule of thumb I will not use a shortcut, alias or quick hack if it's not going to work consistently in all my environments. - because that way lies madness.

  8. You can do this in bash. In fact, I can't do it in zsh because my config doesn't come with the right binding out the box... but it's straightforward to add.

  9. This is a terminal code that will work in any shell.

Now, I'm not trying to make a list of points simply to rain on your parade; I think that most of these are good things to know. But you don't need zsh for most of them!

Collapse
 
lt0mm profile image
Tom • Edited

Recently was disappointed when 2 didn't work for me on another laptop, didn't know it's zsh, it's so great tbh, "take" off cause is also supper useful for developer, maybe rarer use case, generally I think would be more useful to list maybe useful things from other shells or some useful bash tips than claim that these tips are not good or not zsh specific

Collapse
 
ikirker profile image
Ian Kirker

I don't zsh for similar reasons to yours in number 7: I definitely can't use it in some of the environments I work in, so I haven't really put any effort into using it anywhere. And I think it's useful to know what comes from where.

So, as an addition to this, some notes on equivalents that work in bash:

2: You can set this up for bash using the readline initialisation file .inputrc file in your home directory, or using bind commands in your shell startup files. I use the bind method because it doesn't affect other programs using the readline library that way. (E.g. the mysql and sqlite clients.)

bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-forward'
Enter fullscreen mode Exit fullscreen mode

Ctrl-R also works in bash for expanding partial commands into history entries, though slightly differently.

3: I don't think this is a good idea either, but I thought it might be possible to set up in bash by setting the command-not-found handle:

function command_not_found_handle() {
   if test -d "$1"; then
      cd "$1"
      echo "Found directory '$1', cd-ing..." >&2
   else
      echo "$0: $1: command not found" >&2
   fi
}
Enter fullscreen mode Exit fullscreen mode

Unfortunately it turns out this is run in a separate execution context to the shell it comes from, so the cd command can't take effect as intended.

I'm not sure there's an approach that would work.

7: I do this in bash using the readline kill buffer; usually using Ctrl-A to skip to the beginning of the line, then Ctrl-K to cut the line into the buffer. Then later, I can use Ctrl-Y to paste it back.

These keyboard shortcuts also work in zsh, because although zsh doesn't use the readline library, the equivalent zle apparently implements a lot of the same features.


An extensive plugin library is probably handy, but it's worth knowing that a lot of the stuff in there can also be implemented in bash, and there's an equivalent oh-my-bash to oh-my-zsh.

Zsh's line editing and display capabilities seem somewhat more sophisticated than bash's, definitely, so I think some things just can't be ported. The display-suggestions-as-you-type thing, particularly, I don't think has a bash implementation.