Live data from Hacker News

Zsh Tricks to Blow Your Mind

twilio.com

181–190 of 218 posts

Re: Zsh Tricks to Blow Your Mind

#181
post #32

Do people... actually use this font in their terminal? I would go absolutely nuts looking at the spacing and color scheme.

> Do people... actually use this font in their terminal? seems so. recently discussed: https://news.ycombinator.com/item?id=25520510 https://dtinth.github.io/comic-mono-font/ http://www.comicneue.com/

see, the kerning is fine on that though. its not my taste, but it works. This article looks like either something is just wrong with the font, or letterspace needs to be adjusted in the terminal's config.

Re: Zsh Tricks to Blow Your Mind

#182
post #124

Earlier quoted context omitted.

This is always my complaint about posts like this. I read them looking for the killer feature to make me consider switching from bash and it's always stuff bash does natively or with a one line alias.

As many others here have noted, terse syntax for things like `repeat` loops or normal `for`/`while` loops or shell var expansion can all be addictive, but some specific things I miss in Bash that are easy in Zsh are: 1) auto cd to any evar just from its name e.g. lb=/usr/local/bin; lb ($lb works in bash, but I always forget the $. I know I could do aliases...Yuck.) 2) auto cd does not seem to use $CDPATH this is a re…

What's Yuck about using aliases? I use those extensively. Is that a bad practice?

Re: Zsh Tricks to Blow Your Mind

#183
post #16
post #3

https://github.com/natethinks/jog/ I'm not sure why this isn't a part of zsh already, but if you want to see the last few commands you ran in the current directory, that little utility will do that for you. Great for reminding yourself what you did last time you were in a directory.

Wow jog is tiny: grep -a "${PWD} " ~/.zsh_history_ext | cat | cut -f1 -d"|" | tail

When I was exploring projects that did this I found an alternative that spun up a database and was literally thousands of lines of code. This seemed to fit exactly what I was looking for without insane levels of overhead.

Re: Zsh Tricks to Blow Your Mind

#184
post #11

A lot of these can be easily done in Bash, too! 1. `mkcdir () { mkdir -- "$1" && cd -- "$1"; }` 2a. `bind '"\e[A":history-search-backward'; bind '"\e[B":history-search-forward'` 2b. Default behavior for Bash. 3. `shopt -s autocd` 4. `mmv`, `perl-rename` 5. `qalc` from libqalculate: https://github.com/Qalculate/libqalculate 8. Default behavior for Bash. 9. Default behavior for Bash.

Thank goodness, I can close this tab with no fomo.

Re: Zsh Tricks to Blow Your Mind

#185
post #151

Earlier quoted context omitted.

It's a feature of the zsh line editor called "push-line". http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html

Thank you, I love it. This is so great for a quick ls or cd in between. Turns out it wasn't the terminal that was eating my Ctrl-q, but the key wasn't bound in my zsh. The page you linked says push-line (^Q ESC-Q ESC-q) (unbound)(unbound) Does that mean that in a standard config push-line is bound to Ctrl-q?

From the man page:

> The following is a list of all the standard widgets, and their default bindings in emacs mode, vi command mode and vi insert mode (the `emacs', `vicmd' and `viins' keymaps, respectively).

What that means is that if you issue 'bindkey -e' from a bare .zshrc it will enable the emacs bindings and C-q will work. The other two unbound entries state that it isn't enabled by default if you want to use vi-style editing.

The KEYMAPS section in the man page has a full explanation. The easy way to play with it is to start an extra zsh with "zsh -f" so it ignores your configs, call "bindkey" to see what the default bindings are like, then "bindkey -e; bindkey" to see all the goodies that are enabled in emacs mode for example.

Re: Zsh Tricks to Blow Your Mind

#186
post #182
post #124

Earlier quoted context omitted.

As many others here have noted, terse syntax for things like `repeat` loops or normal `for`/`while` loops or shell var expansion can all be addictive, but some specific things I miss in Bash that are easy in Zsh are: 1) auto cd to any evar just from its name e.g. lb=/usr/local/bin; lb ($lb works in bash, but I always forget the $. I know I could do aliases...Yuck.) 2) auto cd does not seem to use $CDPATH this is a re…

What's Yuck about using aliases? I use those extensively. Is that a bad practice?

I use aliases, too. But an alias for every possible "bookmarked" directory seems excessive. Like this guy [1] in the current thread, I tend to just say x=`pwd` (no need to always `export`). Agreed there is probably a way to set up a shell function `a() {...}` that establishes an alias (or even a shell function) almost as simply, but another problem that remains is that aliases and variables are separate namespaces. So, if you do it the variable way like Zsh then you don't have to worry about clobbering some existing alias or shell function. You do have to keep these separated namespaces in your head, but the updating of the prompt to the variable name is a pretty good reinforcement cue (at least for me, in practice). Also, the variable lets you use it in composed paths like `$x/bin/foo` while an alias/function would only change your directory.

TL;DR - Yuck = namespace squishing in this application only, but then again one man's "collapse of namespaces being yucky" is another's "yay, I do not have to remember 3..4 namespaces!".

EDIT: for what it's worth, I never intended my 9..11 items to be "in order of importance or persuasiveness". Mostly in order of personally driving me batty when I use Bash and just meant to actually be things Zsh could do that (present)Bash could not, to my knowledge due to @deadbunny's complaint. I do try to keep a side Bash config that is as close as possible to my Zsh config, because it's not always worth my time to compile/install Zsh on a system. But when I do that and start using Bash, I notice all these missing things. { That's why I would genuinely appreciate anyone who knows how to replicate them in Bash saying how. I'm not just "daring the Bash apologists to a challenge" or whatever. :-) }

[1] https://news.ycombinator.com/item?id=26177537

Re: Zsh Tricks to Blow Your Mind

#188
post #59

Earlier quoted context omitted.

This is always my complaint about posts like this. I read them looking for the killer feature to make me consider switching from bash and it's always stuff bash does natively or with a one line alias.

Honestly you probably can do these with bash as well with some tweaking. But on a daily basis these are most used by me auto_pushd Replaces internally cd with pushd (plus a few more: to ignore dups, be silent about it). Global aliases (interpolated anywhere in the commandline) alias -g G='| grep -i' cat file G something Replace on the fly long directory names with short paths /some/long/path $ export X=`pwd` ~X $ All…

Short form loops are also great. Someone mentioned short for loops already, but I don't think anyone has mentioned these beauties:

    repeat 10 echo hi
    while {sleep 1} echo hi

Re: Zsh Tricks to Blow Your Mind

#189
post #11

A lot of these can be easily done in Bash, too! 1. `mkcdir () { mkdir -- "$1" && cd -- "$1"; }` 2a. `bind '"\e[A":history-search-backward'; bind '"\e[B":history-search-forward'` 2b. Default behavior for Bash. 3. `shopt -s autocd` 4. `mmv`, `perl-rename` 5. `qalc` from libqalculate: https://github.com/Qalculate/libqalculate 8. Default behavior for Bash. 9. Default behavior for Bash.

The one thing I really don’t want to live without is “intellisense” that changes the default input to a prefix-search that ghosts the top result ahead of your typing.

The feature was stolen from fish it’s 100% worth it to me.

Re: Zsh Tricks to Blow Your Mind

#190
post #124

Earlier quoted context omitted.

This is always my complaint about posts like this. I read them looking for the killer feature to make me consider switching from bash and it's always stuff bash does natively or with a one line alias.

As many others here have noted, terse syntax for things like `repeat` loops or normal `for`/`while` loops or shell var expansion can all be addictive, but some specific things I miss in Bash that are easy in Zsh are: 1) auto cd to any evar just from its name e.g. lb=/usr/local/bin; lb ($lb works in bash, but I always forget the $. I know I could do aliases...Yuck.) 2) auto cd does not seem to use $CDPATH this is a re…

9 goes quite far. My most common uses are downloads/*(oc[1]) for the latest downloaded file (order by time of inode change and return just first result), or downloads/*(c0) for all the files downloaded today (created 0 days ago in downloads directory).

10) =() expansion. It's like 11) short syntax for control structures. For example, you can do `for x in $(xs); foo $x` without bothering with `do` and `done`.

12) variable expansion in brace expansion. In bash, `x=5; echo {3..$x}` outputs `{3..5}`. zsh outputs `3 4 5`.

13) Command can be just redirection without any executable. ` foo.txt` is equivalent to `cat > foo.txt`.

14) Able to convert numbers between any bases. To convert base-5 10 to base-4: `15) Named directories. I have my project files organized under deep directories like ~/work-for/.../.../.../foo/, and have configured all those as named directories to be able to access them as `~foo`, for instance. Different from using simple variables for this, named directories are compacted when presented by the shell. So in my prompt, I see my current directory is e.g. `~foo/bar` instead of the whole thing from the home dir. Named directories come in 2 forms, static and dynamic. Static named dirs are when you set them up in a hash of name => directory. Dynamic named dirs are when you define a function that expands arbitrary names to paths and compacts arbitrary paths to names.

16) `=foo` expands to the full path of executable foo. So you can, e.g. see the source of `pass` with `less =pass`.

17) Variable expansion syntax, glob qualifiers, and history modifiers can be combined/nested quite nicely. For example, this outputs all the commands available from $PATH: `echo ${~${path/%/\/*(*N:t)}}`. `${~foo}` is to enable glob expansion on the result of foo. `${foo/%/bar}` substitutes the end of the result of foo to "bar" (i.e. it appends it); when foo is an array, it does it for each element. In `/*(*N:t)`, we're adding the slash and star to the paths from `$path`, then the parentheses are glob qualifiers. `*` inside means only match the executables, `N` is to activate NULL_GLOB for the match so that we don't get errors for globs that didn't match anything, `:t` is a history mod used for globs that returns just the "tail" of the result, i.e. the basename. IIRC, bash can't even nest multiple parameter expansions; you need to save each step separately.

18) Suffix aliases can be used to define how to open arbitrary files. `./foo.mp4` opens it up in with `mpv`, because I have `alias -s mp4=mpv`.

19) Global aliases are useful for expanding stuff anywhere. For example, I have `alias -g %LD='~/downloads/*(oc[1])'` so that `%LD` expands to the latest download as part of any argument to a command.

20) Globbing flags. There are various flags for globbing, that enable e.g. backreferences in globs, allow n-number of errors while matching (approximate matching), etc. The only one I've really used though is `i` which enables a glob to be case-insensitive. So `(#i)*.pdf` matches `foo.pdf` as well as `bar.PDF`.

21) Multios. You can use multiple files in individual redirections. For example, `foo > bar | baz` is equivalent to `foo | tee bar | baz`. That accepts globbing and brace expansion too: `foo > *.{c,h}` is the same as `foo | tee *.{c,h}`. Also works for reading: `foo < *.txt` is practically the same as `cat *.txt | foo`. I must admit that I haven't really used this, though.

Post reply on HN