Skip to content

QWxleA/qwZsh

Repository files navigation

QW’s zsh config

This config is originally based on slimzsh, which is nice and small. Everything that’s broken was afterwards done by me…

This file is my todo list and notes for my config.

Installation

git clone https://github.com/QWxleA/qwZsh.git ~/.config/zsh

or:

git clone git@github.com:QWxleA/qwZsh.git ~/.config/zsh

To keep home clean, put this in /etc/zsh/zshenv:

#zsh does not use $XDG
export ZDOTDIR=$HOME/.config/zsh

Switching directories for lazy people

See: zshrc

% setopt autocd

Option Setting in Zsh, AKA setopt*

% setopt $OPTION
% man zshoptions

History

Supports csh style bang history expansion.

% history  # last 16 events
% history -E 0  # all history events including date/time information
% !23      # Re-execute history command 23
% !!       # The last command.
% !$       # Last word of the last command.
% !-2      # The last but one command.
% !-2$     # The last word of the command before the last command.
% !#$      # The last word of the current command line.
% !#0      # The first word of the current command line.
% !?foo    # The last command that matches the pattern `foo'.
% !?foo?1  # The second word of the last command line that matches   `foo'.

…and that’s really just the start. History expansion is extremely versatile and powerful - but also a bit cryptic for the untrained eye. Practice, young padawan, makes perfect. .o( man zshexpn | less -p ‘\^HISTO.*ANSION$’ )

Share history file amongst all Zsh sessions, ignoring dupes

=hist_ignore_all_dups updates the timestamp (if using extended history)

See: history.plugin.zsh

% setopt append_history share_history hist_ignore_all_dups

fc

  • fc -p/fc -a/fc -P deals with the “history stack”
  • “fc -p” clears out the current history and starts with a new one, until you run fc -P, which will restore the old history again
  • You can use that to “bind” certain histories to specific directories.

Top 10 commands

Check your history for most frequently used commands and create aliases/functions for them (AKA top10):

% print -l -- ${(o)history%% *} | uniq -c | sort -nr | head -n 10

Replace spaces in filenames with a underline

% autoload -U zmv
% touch 1\ 2  3\ 4\ 5
% zmv '* *' '$f:gs/ /_'

Fast Manpage access

% autoload run-help
% echo foo | xargs <esc-h>

and then:

% git commit<esc-h>

or even ('g' being an alias for git and 'co' and git alias for commit):

% g co<esc-h>

Completion System

Enable completion

% autoload compinit && compinit
% kill c<tab>
% man z<tab>
% dpkg -L <tab>

Menu Selection

% zstyle ':completion:*' menu select

Layout is :completion:FUNCTION:COMPLETER:COMMAND-OR-MAGIC-CONTEXT:ARGUMENT:TAG

Tip: Get completion help running ‘ctrl-x h’.

Use colors in completion

zstyle ':completion:*:default'         list-colors ${(s.:.)LS_COLORS}

Pick item but stay in the menu

% bindkey -M menuselect "+" accept-and-menu-complete
% ls <tab> +

Globbing / Glob Qualifiers

Makes find(1) useless for many jobs.

% setopt extendedglob
% rm ../debianpackage(.)   # remove files only
% ls -d *(/)               # list directories only
% ls /etc/*(@)             # list symlinks only
% ls -l *.(png|jpg|gif)    # list pictures only
% ls *(*)                  # list executables only
% ls /etc/**/zsh           # which directories contain 'zsh'?
% ls **/*(-@)              # list dangling symlinks ('**' recurses down directory trees)
% ls foo*~*bar*            # match everything that starts with foo but doesn't contain bar

The e glob qualifier - e.g. to match all files of which file says that they are JPEGs:

% ls *(e:'file $REPLY | grep -q JPEG':)
  • (#s) or (#e) for what ^ and $ are in regexps (beginning of line/end of line)
  • (#b) or (#m) to enable backreferences
  • (#i) to match case insensitive
  • (#a) to match approximately (certain errors are ignored, e.g. “(#a1)foo*” matches the string “ofobar”)

Tip: run e.g. `ls *(<tab>` to get help regarding globbing.

Keybindings

See: keys.plugin.zsh

Run `bindkey` to get a listing of currently active keybindings

Notes:

  1. \^ := ctrl
  2. \^[ := esc

Get emacs-like keybindings

Zsh defaults to vi keybindings (‘bindkey -v’) if $VISUAL or $EDITOR contain string ‘vi’. Run ‘bindkey -e’ to get emacs-like keybindings then.

Tip: run “bindkey ctrl-v <keys>” to find out which action is bount to a key

Some interesting keybindings

KeybindingMeaning
ctrl-dcomplete + EOF
ctrl-lclear screen
ctrl-wdelete last word
ctrl-\_undo
tabcomplete and take first result
esc-./alt-.insert last parameter of last typed command (similar to typing !$)
ctrl-abegin of line
ctrl-eend of line
alt-’quote-line (”)
alt-?which-command
ctrl-kkill line
ctrl-ukill while line (kill-ring)
ctrl-wcopy last word (kill-ring)
ctrl-yyank (insert kill-ring)
esc-qpush line

Remove last part from directory name

#+caption slash-backward-kill-word

% slash-backward-kill-word() {
    local WORDCHARS="${WORDCHARS:s@/@}"
    zle backward-kill-word
}
% zle -N slash-backward-kill-word
% bindkey '\e^?' slash-backward-kill-word
% cd /usr/share/doc/mutt/examples/<alt+backspace>

Note: configured by default in grml-zshrc, added to functions.plugin.zsh

Keybindings {up,down}-line-or-search and history-beginning-search-{backward,forward}-end

% echo 123
% echo 234
% ls
and then:
% echo <cursor-up|down>
vs.
% echo 2<page-up|down>

Incremental search with history-incremental-pattern-search-backward:

% <ctrl-r>scp*r

Zsh Line Editor (AKA zle)

  1. It’s what readline is for bash (move, delete, copy words/lines/…)
  2. Basic layout of custom widgets, used like functions:
% foobar() { LBUFFER="foobar $LBUFFER"; } # function
% zle -N foobar         # declare function as bindable widget
% bindkey '^x^s' foobar # bind command to a keybinding
  1. ctrl-x-z provides help_zle_parse_keybindings in grml-zshrc

Edit command line in editor

% autoload edit-command-line && zle -N edit-command-line
% bindkey '\ee' edit-command-line
% $SOME_COMMAND_LINE <esc-e>

Insert last typed word

% insert-last-typed-word() { zle insert-last-word -- 0 -1 };
% zle -N insert-last-typed-word;
% bindkey "\em" insert-last-typed-word
% mv foobar <esc-m>

Loadable modules

Play tetris

% autoload -U tetris
% tetris

URL quoting

% autoload -U url-quote-magic
% zle -N self-insert url-quote-magic

Disclaimer: annoying when using e.g. http://example.org/foo{1,2,3}.tgz

Prompt

% autoload -U promptinit
% promptinit
% prompt fire
% prompt <tab>

Exit code in prompt, if it’s not exit code 0

Special functions

precmd(): executed before each prompt - e.g. for setting prompt information

preexec(): running before every command - e.g. for setting GNU screen title

RPOMPT with a smiley (note: the version in grml-zshrc is more sophisticated -> moving smiley)

precmd () { RPROMPT="%(?..:()%" }

Get VCS information into your prompt - vcs\_info

autoload -Uz vcs_info
precmd() {
  psvar=()
  vcs_info
  [[ -n $vcs_info_msg_0_ ]] && psvar[1]="$vcs_info_msg_0_"
}
PS1="%m%(1v.%F{green}%1v%f.)%# "

Hashed directories

% hash -d doc=/usr/share/doc
% cd ~doc
% hash -d deb=/var/cache/apt/archives
% sudo dpkg -i ~deb/foobar*deb

On-the-fly editing of variables

% vared PATH

Text replacing

% mkdir -p /tmp/linux-2.6.3{8,9}/demo
% cd /tmp/linux-2.6.38/demo
% cd 38 <tab>

% echo foo
% ^foo^bar

% echo foo_bar
% echo !$:s/foo/baz/

Suffix aliases

% alias -s txt=vim
% foobar.txt
% alias -s pdf=xpdf
% print.pdf

Grml-zshrc specific stuff

In-place mkdir to create directory under cursor or the selected area

% cp file /tmp/doesnotexist/<ctrl-xM>

Create a temporary directory and change cwd to it

% cdt

Directory specific shell configuration with Zsh

See http://michael-prokop.at/blog/2009/05/30/directory-specific-shell-configuration-with-zsh/ Hint: do you remember the fc section? You can combine the directory specific shell configuration with ‘fc -p $file’!

Smart cd

% which cd
cd () {
        if [[ -f ${1} ]]
        then
                [[ ! -e ${1:h} ]] && return 1
                print "Correcting ${1} to ${1:h}"
                builtin cd ${1:h}
        else
                builtin cd ${1}
        fi
}
% cd /etc/fstab

grml-zsh-fg

% vim # ... <ctrl-z>
% echo foobar
% <ctrl-z>

sudo-command-line

% which sudo-command-line
sudo-command-line () {
        [[ -z $BUFFER ]] && zle up-history
        if [[ $BUFFER != sudo\ * ]]
        then
                BUFFER="sudo $BUFFER"
                CURSOR=$(( CURSOR+5 ))
        fi
}
% gparted /dev/sda <ctrl-o s>

Speed up typing

Long versionShort version
for i in $(seq 2 9); do echo $i ; donefor i in {2..9}; echo $i
ls $(which vim)ls =vim
cat bar baz $PIPECHAR sortsort <b{ar,az}
ls /usr/share/doc/mutt/examplesls /u/s/d/m/e<tab>
gzip -cd foo.gz && less fooless <(gzip -cd foo.gz)
ls >file1; ls >file2; ls >file3ls >file1 >file2 >file3
-less <file1 <file2
-diff <(sort foo) <(sort bar)
-xpdf =(zcat ~doc/grml-docs/zsh/grml-zsh-refcard.pdf.gz)

FAQ

  1. Q: How to I get a listing of all my currently in use options?

    Answer:

      setopt ksh_option_print && setopt
    
    or:
    
      printf '%s=%s\n' "${(@kv)options}"
        
  2. Q: Why do I get “zsh: command not found:” even though I just installed the program?

    Answer: execute:

    % rehash
        

    or use completion system as provided by grml-zshrc (completion will rehash automatically).

  3. Q: What’s this strange word splitting thing?

    Answer: see http://zsh.sourceforge.net/FAQ/zshfaq03.html

    % var="foo bar"
    % args() { echo $#; }
    % args $var
    1
    % setopt shwordsplit
    % args $var
    2
        

Resources

About

QW's zsh config

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages