kerravonsen: Eighth Doctor's legs sticking out from underneath TARDIS console: "tea, tools, Tinkering" (tinkering)
[personal profile] kerravonsen
Here is a geeky post which will interest only two of you, or possibly three. But I'm posting it anyway.

I have rediscovered an old friend, the zsh shell. I used to use zsh when the main other alternative was ksh, and Linux wasn't as common as it is now. Then I switched to bash because it was the default in Linux, and so it Just Worked. But while I was websurfing the other day (I think it was when I was looking for info on dvtm) I stumbled across a page praising zsh over bash, and since the article had been written in 2008, I knew this wasn't ancient history.

So I installed zsh and tried it out again. And this time I read user guides and tips and man pages, doing a fuller immersion than just getting by. I didn't go the "copy someone else's zshrc" route, because I wanted to understand what these options and suchlike were for.

To share the joy, below I go through my .zshrc (well, highlights of it) and point out the features that I am using that I feel are cool. Yes, bash probably does some of these too, but it doesn't do all of them.

typeset -U fpath
fpath=(~kat/.zsh_func $fpath)
autoload -U ${fpath[1]}/*(:t)

This is the function path. This is cool because one can define shell functions in separate files, and only load them when you need them (with the "autoload" command). This is more nifty than doing a "source" on the file, because you don't need to know where the file is, it just has to be somewhere on your function path. In addition, this means you can redefine default functions, because the first-found file is what is used. The third line in that set actually autoloads all the functions in my .zsh_func directory, on the reasonable assumption that if I wrote it myself, then I want to use it.

Also, I didn't know that zsh had arrays.

if [[ -d ${HOME}/Mail/Incoming/ ]]
then
	MAIL=${HOME}/Mail/Incoming/Inbox
	mailpref=${HOME}/Mail/Incoming
	mailpath=($mailpref/Inbox
          $mailpref/amazon'?New amazon mail' 
          $mailpref/bible'?New bible post'
          $mailpref/bulk'?New bulk mail'
          $mailpref/ffnet'?New ffnet mail'
          $mailpref/katspace_updates'?New katspace_updates mail'
          $mailpref/lj'?New LJ mail'
          $mailpref/perlkat'?New perlkat mail'
          ${HOME}/Mail/Saved/teaspoon'?New teaspoon mail')
fi


I knew that zsh could notify you of incoming mail, but the nifty thing here is that the '?string' defines the string being used for the notification, which means that zsh will tell me when I get LJ mail and when I get bulk mail with a different message (I use a mail filter to put incoming mail into different mail folders).

# colourized grep
export GREP_COLOR="1;33"
alias grep='grep --color=auto'

Not a zsh feature, but I hadn't known that one could have colourized grep output as well as colourized ls output.

my_chpwd() {
    [[ -t 1 ]] || return
    case $TERM in
      sun-cmd) print -Pn "\e]l%~\e\\"
        ;;
      *xterm*|*rxvt*|(dt|k|E)term) print -Pn "\e]2;%2~\a"
        ;;
    esac
}
[[ $chpwd_functions = *my_chpwd* ]] || chpwd_functions=(my_chpwd $chpwd_functions)

This is the old "make your xterm show your current directory" thing; however, the nifty thing here is the $chpwd_functions array, which means that, if it so happens that some other script or function also wants to do things with the change-working-directory hook, that they don't clobber each other.

autoload -U promptinit; promptinit
prompt kat1

This is an example of autoloading external functions; there's an add-on for prompt themes; I just plonked my own prompt-theme file into my .zsh_func directory, and there you are.

source ~/.zkbd/$TERM
[[ -n ${key[F1]} ]] && bindkey "${key[F1]}" run-help
bindkey '^T' which-command
bindkey '^K' push-line-or-edit
bindkey -M viins '^S' spell-word

This has a few things that are cool. First, the files in .zkbd are made by the zkbd function, which prompts you to press various keys so that it can record what the actual escape sequence for them is; things like the function keys and the arrow keys. It saves it to a file .zkbd/$TERM-$DISPLAY but I moved it to just $TERM (that is, I have one for rxvt and another for xterm) because I didn't see the point of having separate files for each display, since I don't always use the same display (depending on what machine I'm on). The second cool thing about this is that zsh has associative arrays; that is what the keybindings are saved in.

The third cool thing is what the four bindings above actually do.

When I press F1 (the traditional "help" key) I get help on what I'm typing, that is, help on the command on the current line. So, say I type "rsync" and then want to check what the options are, I hit F1, and it brings up the rsync man page. Then when I quit that, I get back to the command line just as I left it.

When I press ^T, the shell tells me "whence" the command is; so with "rsync", it prints "/usr/bin/rsync" and then I'm back at my command-line again. Not quite as useful as help, but sometimes one needs to know this. Also, a feature similar is that if one puts "=" in front of a command name, that expands out to the full path of that command; handy when one is editing shell scripts.

The "push-line-or-edit" which is bound to ^K is useful when one is entering a multi-line command (such as a "for" loop); if I go ^K, then it puts the command-so-far into an editing buffer, so I can go back and correct things before I actually run the command. Nifty for those typos.

The "spell-word" does what you think it does; it corrects your spelling. So if I type mall, and go ^S, it will correct it to the nearest command, "mail". More typo-bashing!

setopt auto_cd

I often wished that I could just change directories by typing the name of the directory; well, now I can. Want to go to the directory above this one? Just type '..' and you're there.

setopt noflowcontrol

How many times have you cursed when your terminal locks for no apparent reason, and then you find that you've accidentally typed ^S, and have to type ^Q to unlock the terminal again? This option disables that behaviour, so one can use ^S for nifty things like checking spelling.

setopt hist_ignore_dups
setopt inc_append_history
setopt share_history

These enable one to share history between all zsh sessions, and share it as you go, (and have it not add duplicate commands to the history). No more frustration because that complicated command you did was done in another terminal, and you're in this one.

setopt menu_complete
autoload -U compinit; compinit
zmodload zsh/complist
zstyle ':completion:*:default' list-colors ''
zstyle ':completion:*' menu select=6

And here we have the auto-completion stuff. There are lots and lots of options; I've set mine up to suit me. This gives me auto-completion cycling when there are less than 6 options to pick from, and when there are 6 or more, it gives me a menu that I can use the arrow keys to select from. Plus, the menu is in colour, for different types of files.

autoload -U predict-on
zle -N predict-on
zle -N predict-off
bindkey '^E' predict-on
bindkey '^F' predict-off
zstyle ':predict:*' toggle=true

The "prediction" add-on is sooooo cool. It's like super-auto-auto-completion. When predict is turned on, it tracks every keystroke and finds the line in your history that most closely matches what you are typing. I don't have it turned on all the time, because it would get annoying when one wanted to enter a new command instead of repeating (or slightly altering) an old one. But when you have favourite commands that you keep on doing, this is very helpful.

autoload -U zsh-mime-setup; zsh-mime-setup

You know how you double-click on a file in a file-manager, and it opens that file with the application that matches that file? This extension adds that behaviour to zsh, using the existing mime and mailcap definitions. You just type the name of the file in the command line, and hit return, and it launches the application on that file. You can also add your own associations, by writing mailcap entries in a ~/.mailcap file. I added one to associate .xcf files with gimp, for example.

I'm not sure I'll remember that I can do this, though.

mirror=/files/mirror
: ~mirror

This is a nifty extension of the ~ notation. The normal expectation is that ~ by itself stands for your home directory, and ~user stands for user's home directory. This feature enables you to set a tilde shortcut for any directory you like. What makes this nicer than just going "cd $mirror" is that if you are showing the current directory in your prompt, it will show the shortcut rather than the full path; for example, "~mirror" rather than "/files/mirror".

Date: 2009-03-20 05:16 am (UTC)
From: [identity profile] japester.livejournal.com
been using zsh for, ohmigod, long time now.
Discovered it by one of my friends hacking at it and he passed over his .zshrc. and then another friend added to it. and then I RTFM'd the man pages ...

still love it. still love just how configurable it is. Still use bash as the default root shell (cause extensibility is not required for the automaton running my system) but for human use, zsh rocks worlds.

and you've pointed me in the direction of some new stuff in zsh. well, new since I last read about it. I'll have to see if I can remember the additions to the config files now!

Profile

kerravonsen: (Default)
Kathryn A.

Most Popular Tags

January 2026

S M T W T F S
    1 23
45678910
11121314151617
18192021222324
25262728293031

Expand Cut Tags

No cut tags

Style Credit

Page generated Mar. 22nd, 2026 12:39 am
Powered by Dreamwidth Studios