Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: zsh tips for "UNIX Power Tools"

On Thu, Mar 02, 2000 at 05:18:27PM +0100,
Jerry Peek <jpeek@xxxxxxxxx> wrote:
> Hi.  I'm an occasional (*too* occasional, I'm afraid!) zsh user.

Hi, I'm an all-day zsh user. :-)

> I'm also the first author of O'Reilly's "UNIX Power Tools" book
> (http://www.oreilly.com/catalog/upt2/).  I'm just starting to work
> on a third edition, due out (if all goes okay) sometime this fall.
> I'd like to include basic coverage of zsh and cool zsh tips.

I know about that book, but I don't have a copy of my own.
It's a cool book :)
(I already had in mind to buy a copy of my own, but there's always been
someone around who had it handy so I didn't buy it yet ;-)

> Before I get you all too excited ;-) here, I should say that UPT
> probably won't be able to cover all zsh features: there are just too
> many, and zsh still isn't as "mainstream" a shell as, say, bash.
> We've gotta cover what readers are using!  And the book can't grow
> too much; it's already pretty big.  But I do want to expose people
> to other great tools, and zsh is sure one of those!  No idea yet how
> many tips I can squeeze in, either: the outline isn't done.  Still,
> I'm working zsh features into articles that describe other shells.

A chapter of its own would be best, if that's possible. A short chapter
"zsh" would be better than lots of zsh tricks mangled into a bash

> I don't know how active this list is, and I'm sorry if I jumped into
> the wrong place.

Well, it's surely the right place :-)

> But I'm actively working on the outline now, and I
> just realized that you folks might be a great resource.  If you haven't
> seen "UNIX Power Tools," it's basically a big collection of user tips.
> I'm hoping that any of you who have some favorite zsh tips might have a
> minute or two to send me a quick email with a description of the tip.

OK, I'm adding a few (very few) tips at the end of this mail.

> I just joined the zsh-users list now -- but if it's too active, I may
> have to unsubscribe because I get such a flood of email already.  So,
> if you send a reply to the list, I'd appreciate a cc: jpeek@xxxxxxxxxx

I cc'ed you. But this list is usually not too busy, so I don't think you
have to unsubscribe again :-)

> official answers.  One more bit of administrivia: if you contribute
> something that *you* wrote (vs. a pointer to tips elsewhere) we'll
> need you to fill in a short permission/tracking form; please see
> http://www.oreilly.com/oreilly/author/permission/source.html .

I'm sitting behind UUCP, not having direct access to the internet now -
what's on that page? Would you mind sending me a copy?

> Jerry


As for my zsh usage: I'm using zsh version 3.1.6-dev-19, and one of my
coolest things is beyond all basics and needs that version, but I
mention it anyways - perhaps someone on the list is interested, I don't
think that ones will make it into a book :)

My favorite zsh tricks (some of which are not too tricky, but perhaps
worth to be mentioned anyways):
- I like the globbing features of zsh, especially this one:
  for i in **/*.gif ; do convert $i ${i:r}.png ; done
  equivalent in bash:
  for i in `find . -name "*.gif"` ;
     do convert $i `basename $i .gif`.png
  Howdy - we don't need basename, nor do we need find!
  And this one:
  chmod 755 **/*(/)
  chmod 644 **/*(.)
  Hey, all directories are mode 755, while all plain files are mode 644!
  Again, no find is necessary, as would be for bash:
  find . -type d -exec chmod 755 {} \;
  find . -type f -exec chmod 644 {} \;
- setopt rmstarsilent
  (I don't like this
   "sure you want to delete all the files in /home/jean-luc/foooooooo [yn]?"
- bindkey "^X^H" run-help
  (this starts run-help on the command on the command-line. Pretty cool:
  it also works in pipes on the current command. See this example:
  ls -l | wc _
             ^- cursor here, now hit ^X^H (ctrl-x, followed by ctrl-h)
                -> the manpage for "wc" pops up
                Now exit man (by hitting 'q'), we're back to this:
  ls -l | wc _
  Ah, and I have
  alias run-help=man
- Why not simply use ^Xh instead of ^X^H? Now, I have a feature of
  zsh-3.1.6-dev-xx on ^Xh:
  bindkey "^Xh" _complete_help
  Cooool! Help on completion! Sorry, only works for
  zsh-3.1.6-dev-something (don't remember the number) with the new-style
  completion, but I like it too much not to mention it here.
- emulate vim's g~ command - oops, it's already there, so it's easy:
  ###       vi-oper-swap-case
  ###              Read a movement command from the keyboard, and swap
  ###              the case of all characters from the cursor position
  ###              to the endpoint of the movement.  If  the  movement
  ###              command  is vi-oper-swap-case, swap the case of all
  ###              characters on the current line.
  bindkey -M vicmd "g~" vi-oper-swap-case
- precmd is the right place to do cool things like setting psvar - ready
  to be used in the right prompt:
  function precmd {
     # OK, I set the prompt here in my original precmd, but that's not the
     # issue here :)
     if jobs % >& /dev/null; then
        psvar=("There are jobs.")
     # OK, what comes here? see next trick :)
     # SEE THERE
  Now this is cool! Whenever I have jobs, my right prompt indicates
- OK, now this one is long and only works with programmable widgets (so,
  only in zsh-3.1.6-dev-something), but there might be other people out
  there using this combination together with "bindkey -v". This is my
  last trick for now (and it contains some escape characters, so be sure
  to copy them as such if you want to try this):
  I have an indicator whether zle is in insert mode or command mode. It
  works like this:
  The last line in my precmd (marked "SEE THERE" above") reads like
     (sleep 1 ; show_mode "INSERT") &!
  [I need the sleep because I have a multiline prompt, so the show_mode
  would set the indication to the wrong place otherwise]
  I use this function for the indication:
  show_mode() {
     echo -n "7[$COL;G"
     echo -n "--$1--"
     echo -n "8"

  Now here's the rewritten widgets:

  ###       vi-add-eol (unbound) (A) (unbound)
  ###              Move  to the end of the line and enter insert mode.
  vi-add-eol() {
     show_mode "INSERT"
     builtin zle .vi-add-eol
  zle -N vi-add-eol
  bindkey -M vicmd "A" vi-add-eol

  ###       vi-add-next (unbound) (a) (unbound)
  ###              Enter insert mode after the  current  cursor  posi­
  ###              tion, without changing lines.
  vi-add-next() {
     show_mode "INSERT"
     builtin zle .vi-add-next
  zle -N vi-add-next
  bindkey -M vicmd "a" vi-add-next

  ###       vi-change (unbound) (c) (unbound)
  ###              Read a movement command from the keyboard, and kill
  ###              from  the  cursor  position  to the endpoint of the
  ###              movement.  Then enter insert mode.  If the  command
  ###              is vi-change, change the current line.
  vi-change() {
     show_mode "INSERT"
     builtin zle .vi-change
  zle -N vi-change
  bindkey -M vicmd "c" vi-change

  ###       vi-change-eol (unbound) (C) (unbound)
  ###              Kill  to the end of the line and enter insert mode.
  vi-change-eol() {
     show_mode "INSERT"
     builtin zle .vi-change-eol
  zle -N vi-change-eol
  bindkey -M vicmd "C" vi-change-eol

  ###       vi-change-whole-line (unbound) (S) (unbound)
  ###              Kill the current line and enter insert mode.
  vi-change-whole-line() {
     show_mode "INSERT"
     builtin zle .vi-change-whole-line
  zle -N vi-change-whole-line
  bindkey -M vicmd "S" vi-change-whole-line

  ###       vi-insert (unbound) (i) (unbound)
  ###              Enter insert mode.
  vi-insert() {
     show_mode "INSERT"
     builtin zle .vi-insert
  zle -N vi-insert
  bindkey -M vicmd "i" vi-insert

  ###       vi-insert-bol (unbound) (I) (unbound)
  ###              Move to the first non-blank character on  the  line
  ###              and enter insert mode.
  vi-insert-bol() {
     show_mode "INSERT"
     builtin zle .vi-insert-bol
  zle -N vi-insert-bol
  bindkey -M vicmd "I" vi-insert-bol

  ###       vi-open-line-above (unbound) (O) (unbound)
  ###              Open a line above the cursor and enter insert mode.
  vi-open-line-above() {
     show_mode "INSERT"
     builtin zle .vi-open-line-above
  zle -N vi-open-line-above
  bindkey -M vicmd "O" vi-open-line-above

  ###       vi-open-line-below (unbound) (o) (unbound)
  ###              Open a line below the cursor and enter insert mode.
  vi-open-line-below() {
     show_mode "INSERT"
     builtin zle .vi-open-line-below
  zle -N vi-open-line-below
  bindkey -M vicmd "o" vi-open-line-below

  ###       vi-substitute (unbound) (s) (unbound)
  ###              Substitute the next character(s).
  vi-substitute() {
     show_mode "INSERT"
     builtin zle .vi-substitute
  zle -N vi-substitute
  bindkey -M vicmd "s" vi-substitute

  ###       vi-replace (unbound) (R) (unbound)
  ###              Enter overwrite mode.
  vi-replace() {
     show_mode "REPLACE"
     builtin zle .vi-replace
  zle -N vi-replace
  bindkey -M vicmd "R" vi-replace

  ###       vi-cmd-mode (^X^V) (unbound) (^[)
  ###              Enter  command  mode;  that  is, select the `vicmd'
  ###              keymap.  Yes, this is bound  by  default  in  emacs
  ###              mode.
  vi-cmd-mode() {
     show_mode "NORMAL"
     builtin zle .vi-cmd-mode
  zle -N vi-cmd-mode
  bindkey -M viins "" vi-cmd-mode

 Thomas Köhler Email:   jean-luc@xxxxxxxxxxxxxxxxx     | LCARS - Linux
     <><        WWW:     http://jeanluc-picard.de      | for Computers
                IRC:             jeanluc               | on All Real
               PGP public key available from Homepage! | Starships

Messages sorted by: Reverse Date, Date, Thread, Author