X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=etc%2Fzsh%2Fzshrc;h=aecbabfe293782006968f294c62f5000142041b5;hb=a5468f8195489f6c662d08c88dee8a9f6657acbf;hp=8e1ec13e8f7c75a489695903b6988f317b7f5af0;hpb=dbd02d77939c414b67b808fab0d5624fb836421b;p=grml-etc-core.git diff --git a/etc/zsh/zshrc b/etc/zsh/zshrc index 8e1ec13..aecbabf 100644 --- a/etc/zsh/zshrc +++ b/etc/zsh/zshrc @@ -274,6 +274,83 @@ function zrcautoload() { return 0 } +# The following is the ‘add-zsh-hook’ function from zsh upstream. It is +# included here to make the setup work with older versions of zsh (prior to +# 4.3.7) in which this function had a bug that triggers annoying errors during +# shell startup. This is exactly upstreams code from f0068edb4888a4d8fe94def, +# with just a few adjustments in coding style to make the function look more +# compact. This definition can be removed as soon as we raise the minimum +# version requirement to 4.3.7 or newer. +function add-zsh-hook() { + # Add to HOOK the given FUNCTION. + # HOOK is one of chpwd, precmd, preexec, periodic, zshaddhistory, + # zshexit, zsh_directory_name (the _functions subscript is not required). + # + # With -d, remove the function from the hook instead; delete the hook + # variable if it is empty. + # + # -D behaves like -d, but pattern characters are active in the function + # name, so any matching function will be deleted from the hook. + # + # Without -d, the FUNCTION is marked for autoload; -U is passed down to + # autoload if that is given, as are -z and -k. (This is harmless if the + # function is actually defined inline.) + emulate -L zsh + local -a hooktypes + hooktypes=( + chpwd precmd preexec periodic zshaddhistory zshexit + zsh_directory_name + ) + local usage="Usage: $0 hook function\nValid hooks are:\n $hooktypes" + local opt + local -a autoopts + integer del list help + while getopts "dDhLUzk" opt; do + case $opt in + (d) del=1 ;; + (D) del=2 ;; + (h) help=1 ;; + (L) list=1 ;; + ([Uzk]) autoopts+=(-$opt) ;; + (*) return 1 ;; + esac + done + shift $(( OPTIND - 1 )) + if (( list )); then + typeset -mp "(${1:-${(@j:|:)hooktypes}})_functions" + return $? + elif (( help || $# != 2 || ${hooktypes[(I)$1]} == 0 )); then + print -u$(( 2 - help )) $usage + return $(( 1 - help )) + fi + local hook="${1}_functions" + local fn="$2" + if (( del )); then + # delete, if hook is set + if (( ${(P)+hook} )); then + if (( del == 2 )); then + set -A $hook ${(P)hook:#${~fn}} + else + set -A $hook ${(P)hook:#$fn} + fi + # unset if no remaining entries --- this can give better + # performance in some cases + if (( ! ${(P)#hook} )); then + unset $hook + fi + fi + else + if (( ${(P)+hook} )); then + if (( ${${(P)hook}[(I)$fn]} == 0 )); then + set -A $hook ${(P)hook} $fn + fi + else + set -A $hook $fn + fi + autoload $autoopts -- $fn + fi +} + # Load is-at-least() for more precise version checks Note that this test will # *always* fail, if the is-at-least function could not be marked for # autoloading. @@ -547,14 +624,6 @@ export PAGER=${PAGER:-less} #v# export MAIL=${MAIL:-/var/mail/$USER} -# if we don't set $SHELL then aterm, rxvt,.. will use /bin/sh or /bin/bash :-/ -if [[ -z "$SHELL" ]] ; then - SHELL="$(which zsh)" - if [[ -x "$SHELL" ]] ; then - export SHELL - fi -fi - # color setup for ls: check_com -c dircolors && eval $(dircolors -b) # color setup for ls on OS X / FreeBSD: @@ -1969,7 +2038,10 @@ __EOF0__ function grml_prompt_setup () { emulate -L zsh autoload -Uz vcs_info - autoload -Uz add-zsh-hook + # The following autoload is disabled for now, since this setup includes a + # static version of the ‘add-zsh-hook’ function above. It needs to be + # reenabled as soon as that static definition is removed again. + #autoload -Uz add-zsh-hook add-zsh-hook precmd prompt_$1_precmd } @@ -2401,7 +2473,10 @@ function grml_control_xterm_title () { esac } -zrcautoload add-zsh-hook || add-zsh-hook () { :; } +# The following autoload is disabled for now, since this setup includes a +# static version of the ‘add-zsh-hook’ function above. It needs to be +# reenabled as soon as that static definition is removed again. +#zrcautoload add-zsh-hook || add-zsh-hook () { :; } if [[ $NOPRECMD -eq 0 ]]; then add-zsh-hook precmd grml_reset_screen_title add-zsh-hook precmd grml_vcs_to_screen_title @@ -2682,16 +2757,98 @@ is4 && nt() { freload() { while (( $# )); do; unfunction $1; autoload -U $1; shift; done } compdef _functions freload -#f1# List symlinks in detail (more detailed version of 'readlink -f' and 'whence -s') +# +# Usage: +# +# e.g.: a -> b -> c -> d .... +# +# sll a +# +# +# if parameter is given with leading '=', lookup $PATH for parameter and resolve that +# +# sll =java +# +# Note: limit for recursive symlinks on linux: +# http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/namei.c?id=refs/heads/master#l808 +# This limits recursive symlink follows to 8, +# while limiting consecutive symlinks to 40. +# +# When resolving and displaying information about symlinks, no check is made +# that the displayed information does make any sense on your OS. +# We leave that decission to the user. +# +# The zstat module is used to detect symlink loops. zstat is available since zsh4. +# With an older zsh you will need to abort with in that case. +# When a symlink loop is detected, a warning ist printed and further processing is stopped. +# +# Module zstat is loaded by default in grml zshrc, no extra action needed for that. +# +# Known bugs: +# If you happen to come accross a symlink that points to a destination on an other partition +# with the same inode number, that will be marked as symlink loop though it is not. +# Two hints for this situation: +# I) Play lottery the same day, as you seem to be rather lucky right now. +# II) Send patches. +# +# return status: +# 0 upon success +# 1 file/dir not accesible +# 2 symlink loop detected +# +#f1# List symlinks in detail (more detailed version of 'readlink -f', 'whence -s' and 'namei -l') sll() { - [[ -z "$1" ]] && printf 'Usage: %s \n' "$0" && return 1 - local file - for file in "$@" ; do + if [[ -z ${1} ]] ; then + printf 'Usage: %s \n' "${0}" + return 1 + fi + + local file jumpd curdir + local -i RTN LINODE i + local -a SEENINODES + curdir="${PWD}" + RTN=0 + + for file in "${@}" ; do + SEENINODES=() + ls -l "${file:a}" || RTN=1 + while [[ -h "$file" ]] ; do - ls -l $file + if is4 ; then + LINODE=$(zstat -L +inode "${file}") + for i in ${SEENINODES} ; do + if (( ${i} == ${LINODE} )) ; then + builtin cd "${curdir}" + print "link loop detected, aborting!" + return 2 + fi + done + SEENINODES+=${LINODE} + fi + jumpd="${file:h}" + file="${file:t}" + + if [[ -d ${jumpd} ]] ; then + builtin cd "${jumpd}" || RTN=1 + fi file=$(readlink "$file") + + jumpd="${file:h}" + file="${file:t}" + + if [[ -d ${jumpd} ]] ; then + builtin cd "${jumpd}" || RTN=1 + fi + + ls -l "${PWD}/${file}" || RTN=1 done + shift 1 + if (( ${#} >= 1 )) ; then + print "" + fi + builtin cd "${curdir}" done + return ${RTN} } # TODO: Is it supported to use pager settings like this? @@ -2773,7 +2930,7 @@ fi # zsh profiling profile() { - ZSH_PROFILE_RC=1 $SHELL "$@" + ZSH_PROFILE_RC=1 zsh "$@" } #f1# Edit an alias via zle @@ -3137,10 +3294,8 @@ mkcd() { #f5# Create temporary directory and \kbd{cd} to it cdt() { - local t - t=$(mktemp -d) - echo "$t" - builtin cd "$t" + builtin cd "$(mktemp -d)" + builtin pwd } #f5# List files which have been accessed within the last {\it n} days, {\it n} defaults to 1