X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=etc%2Fzsh%2Fzshrc;h=882957882ba9c47605c94e247c9ed43e2f86456a;hb=27662940e75dc75f2f6cab2c1fe27aef26ba9753;hp=a1778a649ca9193945d042abdd833c77cd46a7e4;hpb=638c1910c6d6708c020bd068510825854410e587;p=grml-etc-core.git diff --git a/etc/zsh/zshrc b/etc/zsh/zshrc index a1778a6..8829578 100644 --- a/etc/zsh/zshrc +++ b/etc/zsh/zshrc @@ -109,7 +109,7 @@ if [[ $ZSH_PROFILE_RC -gt 0 ]] ; then fi # load .zshrc.pre to give the user the chance to overwrite the defaults -[[ -r ${HOME}/.zshrc.pre ]] && source ${HOME}/.zshrc.pre +[[ -r ${ZDOTDIR:-${HOME}}/.zshrc.pre ]] && source ${ZDOTDIR:-${HOME}}/.zshrc.pre # check for version/system # check for versions (compatibility reasons) @@ -179,6 +179,11 @@ isdarwin(){ return 1 } +isfreebsd(){ + [[ $OSTYPE == freebsd* ]] && return 0 + return 1 +} + #f1# are we running within an utf environment? isutfenv() { case "$LANG $CHARSET $LANGUAGE" in @@ -237,7 +242,7 @@ function zrcautoload() { local -i ffound ffile=$1 - (( found = 0 )) + (( ffound = 0 )) for fdir in ${fpath} ; do [[ -e ${fdir}/${ffile} ]] && (( ffound = 1 )) done @@ -497,7 +502,7 @@ xunfunction() { # modifications in ~/.zshrc.local zrclocal() { xsource "/etc/zsh/zshrc.local" - xsource "${HOME}/.zshrc.local" + xsource "${ZDOTDIR:-${HOME}}/.zshrc.local" return 0 } @@ -533,8 +538,9 @@ export SHELL='/bin/zsh' # color setup for ls: check_com -c dircolors && eval $(dircolors -b) -# color setup for ls on OS X: +# color setup for ls on OS X / FreeBSD: isdarwin && export CLICOLOR=1 +isfreebsd && export CLICOLOR=1 # do MacPorts setup on darwin if isdarwin && [[ -d /opt/local ]]; then @@ -549,7 +555,7 @@ isdarwin && xsource /sw/bin/init.sh # load our function and completion directories for fdir in /usr/share/grml/zsh/completion /usr/share/grml/zsh/functions; do fpath=( ${fdir} ${fdir}/**/*(/N) ${fpath} ) - if [[ ${fpath} == '/usr/share/grml/zsh/functions' ]] ; then + if [[ ${fdir} == '/usr/share/grml/zsh/functions' ]] ; then for func in ${fdir}/**/[^_]*[^~](N.) ; do zrcautoload ${func:t} done @@ -579,6 +585,22 @@ watch=(notme root) # automatically remove duplicates from these arrays typeset -U path cdpath fpath manpath +# Remove zle-line-{init,finish} if it looks like it turns smkx. This would be +# better fixed by working with those modes too, but we use way too many +# hardcoded bindings for now. +function remove_widget () { + local name=$1 + local cap=$2 + if (( ${+functions[$name]} )) && [[ ${functions[$name]} == *${cap}* ]]; then + local w=${widgets[$name]} + zle -D $name + [[ $w == user:* ]] && unfunction ${w#*:} + fi +} +remove_widget zle-line-init smkx +remove_widget zle-line-finish rmkx +unfunction remove_widget + # keybindings if [[ "$TERM" != emacs ]] ; then [[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char @@ -898,7 +920,7 @@ abk=( '....' '../../..' 'BG' '& exit' 'C' '| wc -l' - 'G' '|& grep '${grep_options:+"${grep_options[*]} "} + 'G' '|& grep '${grep_options:+"${grep_options[*]}"} 'H' '| head' 'Hl' ' --help |& less -r' #d (Display help in pager) 'L' '| less' @@ -924,8 +946,7 @@ zleiab() { return 0 fi - matched_chars='[.-|_a-zA-Z0-9]#' - LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#} + LBUFFER=${LBUFFER%%(#m)[.\-+:|_a-zA-Z0-9]#} LBUFFER+=${abk[$MATCH]:-$MATCH} } @@ -963,7 +984,6 @@ if zrcautoload compinit ; then compinit || print 'Notice: no compinit available :(' else print 'Notice: no compinit available :(' - function zstyle { } function compdef { } fi @@ -1105,17 +1125,17 @@ fi # history -ZSHDIR=$HOME/.zsh +ZSHDIR=${ZDOTDIR:-${HOME}/.zsh} #v# -HISTFILE=$HOME/.zsh_history +HISTFILE=${ZDOTDIR:-${HOME}}/.zsh_history isgrmlcd && HISTSIZE=500 || HISTSIZE=5000 isgrmlcd && SAVEHIST=1000 || SAVEHIST=10000 # useful for setopt append_history # dirstack handling DIRSTACKSIZE=${DIRSTACKSIZE:-20} -DIRSTACKFILE=${DIRSTACKFILE:-${HOME}/.zdirs} +DIRSTACKFILE=${DIRSTACKFILE:-${ZDOTDIR:-${HOME}}/.zdirs} if [[ -f ${DIRSTACKFILE} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then dirstack=( ${(f)"$(< $DIRSTACKFILE)"} ) @@ -1137,100 +1157,15 @@ chpwd() { if is433 ; then -# chpwd_profiles(): Directory Profiles -# -# Say you want certain settings to be active in certain directories. This is -# what you want. +# chpwd_profiles(): Directory Profiles, Quickstart: # -# To get it working you will need this function and something along the -# following lines: +# In .zshrc.local: # -# chpwd_functions+=( chpwd_profiles ) +# zstyle ':chpwd:profiles:/usr/src/grml(|/|/*)' profile grml +# zstyle ':chpwd:profiles:/usr/src/debian(|/|/*)' profile debian # chpwd_profiles # -# You will usually want to do that *after* you configured the system. That -# configuration is described below. -# -# zstyle ':chpwd:profiles:/usr/src/grml(|/|/*)' profile grml -# zstyle ':chpwd:profiles:/usr/src/debian(|/|/*)' profile debian -# -# When that's done and you enter a directory that matches the pattern in the -# third part of the context, a function called chpwd_profile_grml, for example, -# is called (if it exists). -# -# If no pattern patches (read: no profile is detected) the profile is set to -# 'default', which means chpwd_profile_default is attempted to be called. -# -# A word about the context (the ':chpwd:profiles:*' stuff in the zstyle -# command) which is used: The third part in the context is matched against -# ${PWD}. That's why using a pattern such as /foo/bar(|/|/*) makes sense. -# Because that way the profile is detected for all these values of ${PWD}: -# /foo/bar -# /foo/bar/ -# /foo/bar/baz -# So, if you want to make double damn sure a profile works in /foo/bar and -# everywhere deeper in that tree, just use (|/|/*) and be happy. -# -# The name of the detected profile will be available in a variable called -# 'profile' in your functions. You don't need to do anything, it'll just be -# there. -# -# Then there is the parameter $CHPWD_PROFILE is set to the profile, that was is -# currently active (the default value is "default"). That way you can avoid -# running code for a profile that is already active, by running code such as -# the following at the start of your function: -# -# function chpwd_profile_grml() { -# [[ ${profile} == ${CHPWD_PROFILE} ]] && return 1 -# ... -# } -# -# If you know you are going to do that all the time for each and every -# directory-profile function you are ever going to write, you may also set the -# `re-execute' style to `false' (which only defaults to `true' for backwards -# compatibility), like this: -# -# zstyle ':chpwd:profiles:*' re-execute false -# -# If you use this feature and need to know whether it is active in your current -# shell, there are several ways to do that. Here are two simple ways: -# -# a) If knowing if the profiles feature is active when zsh starts is good -# enough for you, you can use the following snippet: -# -# (( ${+functions[chpwd_profiles]} )) && print "directory profiles active" -# -# b) If that is not good enough, and you would prefer to be notified whenever a -# profile changes, you can solve that by making sure you start *every* -# profile function you create like this: -# -# function chpwd_profile_myprofilename() { -# [[ ${profile} == ${CHPWD_PROFILE} ]] && return 1 -# print "chpwd(): Switching to profile: $profile" -# ... -# } -# -# That makes sure you only get notified if a profile is *changed*, not -# everytime you change directory. (To avoid this, you may also set the newer -# `re-execute' style like described further above instead of the test on top of -# the function. -# -# If you need to do initialisations the first time `chpwd_profiles' is called -# (which should be in your configuration file), you can do that in a function -# called "chpwd_profiles_init". That function needs to be defined *before* -# `chpwd_profiles' is called for this to work. -# -# During the *first* call of `chpwd_profiles' (and therefore all its profile -# functions) the parameter `$CHPWD_PROFILES_INIT' exists and is set to `1'. In -# all other cases, the parameter does not exist at all. -# -# When the system switches from one profile to another, it executes a function -# named "chpwd_leave_profile_()" before calling the -# profile-function for the new profile. -# -# There you go. Now have fun with that. -# -# Note: This feature requires zsh 4.3.3 or newer. +# For details see the `grmlzshrc.5' manual page. function chpwd_profiles() { local profile context local -i reexecute @@ -1289,7 +1224,7 @@ if zrcautoload colors && colors 2>/dev/null ; then MAGENTA="%{${fg[magenta]}%}" YELLOW="%{${fg[yellow]}%}" WHITE="%{${fg[white]}%}" - NO_COLOUR="%{${reset_color}%}" + NO_COLOR="%{${reset_color}%}" else BLUE=$'%{\e[1;34m%}' RED=$'%{\e[1;31m%}' @@ -1298,7 +1233,7 @@ else WHITE=$'%{\e[1;37m%}' MAGENTA=$'%{\e[1;35m%}' YELLOW=$'%{\e[1;33m%}' - NO_COLOUR=$'%{\e[0m%}' + NO_COLOR=$'%{\e[0m%}' fi # gather version control information for inclusion in a prompt @@ -1330,10 +1265,10 @@ if [[ "$TERM" == dumb ]] ; then zstyle ':vcs_info:*' actionformats "(%s%)-[%b|%a] " "zsh: %r" zstyle ':vcs_info:*' formats "(%s%)-[%b] " "zsh: %r" else - # these are the same, just with a lot of colours: - zstyle ':vcs_info:*' actionformats "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOUR} " \ + # these are the same, just with a lot of colors: + zstyle ':vcs_info:*' actionformats "${MAGENTA}(${NO_COLOR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${YELLOW}|${RED}%a${MAGENTA}]${NO_COLOR} " \ "zsh: %r" - zstyle ':vcs_info:*' formats "${MAGENTA}(${NO_COLOUR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOUR}%} " \ + zstyle ':vcs_info:*' formats "${MAGENTA}(${NO_COLOR}%s${MAGENTA})${YELLOW}-${MAGENTA}[${GREEN}%b${MAGENTA}]${NO_COLOR}%} " \ "zsh: %r" zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat "%b${RED}:${YELLOW}%r" fi @@ -1349,6 +1284,70 @@ function command_not_found_handler() { return 1 } +function prompt_grml_help () { + cat <<__EOF0__ + prompt grml + + This is the prompt as used by the grml-live system . + It is a rather simple one-line prompt, that by default looks like this: + + @ [ ]% + + The prompt itself integrates with zsh's prompt themes system (as you are + witnessing right now) and is configurable to a certain degree. In + particular, these aspects are customisable: + + - The items used in the prompt (e.g. you can remove \`user' from + the list of activated items, which will cause the user name to + be omitted from the prompt string). + + - The attributes used with the items are customisable via strings + used before and after the actual item. + + The available items are: rc, rc-always, change-root, user, at, host, path, + vcs, percent, sad-smiley. + + The actual configuration is done via zsh's \`zstyle' mechanism. The + context, that is used while looking up styles is: + + ':prompt:grml:' + + Here is either 'items:' or 'setup'. The available + styles in the \`setup' context are: use-rprompt, items. For example, + default \`items' style could be configured like this: + + zstyle ':prompt:grml:setup' items user at host path \\ + vcs percent + + The styles: + + - use-rprompt (boolean): If \`true' (the default), print a sad smiley + in $RPROMPT if the last command a returned non-successful error + code. + + - items (list): The list of items used in the prompt. If \`vcs' is + present in the list, the theme's code invokes \`vcs_info' + accordingly. Default: rc user change-root at host path vcs precent + + Available styles in 'items:' are: pre, post. These are strings that + are inserted before (pre) and after (post) the item in question. Thus, the + following would cause the user name to be printed in red instead of the + default blue: + + zstyle ':prompt:grml:items:user' pre '%F{red}' + + Note, that the \`post' style may remain at its default value, because its + default value is '%f', which turns the foreground text attribute off (which + is exactly, what is still required with the new \`pre' value). +__EOF0__ +} + +function prompt_grml_setup () { +} + +function prompt_grml_precmd () { +} + # set prompt if zrcautoload promptinit && promptinit 2>/dev/null ; then promptinit # people should be able to use their favourite prompt @@ -1460,13 +1459,13 @@ else # prompt below) if [[ $GRMLPROMPT -gt 0 ]] ; then PROMPT="${RED}${EXITCODE}${CYAN}[%j running job(s)] ${GREEN}{history#%!} ${RED}%(3L.+.) ${BLUE}%* %D -${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< " +${BLUE}%n${NO_COLOR}@%m %40<...<%B%~%b%<< " else # This assembles the primary prompt string if (( EUID != 0 )); then - PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< " + PROMPT="${RED}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${BLUE}%n${NO_COLOR}@%m %40<...<%B%~%b%<< " else - PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOUR}@%m %40<...<%B%~%b%<< " + PROMPT="${BLUE}${EXITCODE}${WHITE}${debian_chroot:+($debian_chroot)}${RED}%n${NO_COLOR}@%m %40<...<%B%~%b%<< " fi fi fi @@ -1513,15 +1512,15 @@ fi # do we have GNU ls with color-support? if [[ "$TERM" != dumb ]]; then #a1# execute \kbd{@a@}:\quad ls with colors - alias ls='ls -b -CF '${ls_options:+"${ls_options[*]} "} + alias ls='ls -b -CF '${ls_options:+"${ls_options[*]}"} #a1# execute \kbd{@a@}:\quad list all files, with colors - alias la='ls -la '${ls_options:+"${ls_options[*]} "} + alias la='ls -la '${ls_options:+"${ls_options[*]}"} #a1# long colored list, without dotfiles (@a@) - alias ll='ls -l '${ls_options:+"${ls_options[*]} "} + alias ll='ls -l '${ls_options:+"${ls_options[*]}"} #a1# long colored list, human readable sizes (@a@) - alias lh='ls -hAl '${ls_options:+"${ls_options[*]} "} + alias lh='ls -hAl '${ls_options:+"${ls_options[*]}"} #a1# List files, append qualifier to filenames \\&\quad(\kbd{/} for directories, \kbd{@} for symlinks ...) - alias l='ls -lF '${ls_options:+"${ls_options[*]} "} + alias l='ls -lF '${ls_options:+"${ls_options[*]}"} else alias ls='ls -b -CF' alias la='ls -la' @@ -1790,6 +1789,15 @@ grmlcomp() { zstyle ':completion:*:manuals.*' insert-sections true zstyle ':completion:*:man:*' menu yes select + # Search path for sudo completion + zstyle ':completion:*:sudo:*' command-path /usr/local/sbin \ + /usr/local/bin \ + /usr/sbin \ + /usr/bin \ + /sbin \ + /bin \ + /usr/X11R6/bin + # provide .. as a completion zstyle ':completion:*' special-dirs .. @@ -1839,7 +1847,6 @@ grmlcomp() { $(hostname) "$_ssh_hosts[@]" "$_etc_hosts[@]" - grml.org localhost ) zstyle ':completion:*:hosts' hosts $hosts @@ -1968,6 +1975,19 @@ if check_com -c $PAGER ; then _dnews() { _files -W /usr/share/doc -/ } compdef _dnews dnews + #f1# View Debian's copyright of a given package + dcopyright() { + emulate -L zsh + if [[ -r /usr/share/doc/$1/copyright ]] ; then + $PAGER /usr/share/doc/$1/copyright + else + echo "No copyright file for package $1 found, sorry." + return 1 + fi + } + _dcopyright() { _files -W /usr/share/doc -/ } + compdef _dcopyright dcopyright + #f1# View upstream's changelog of a given package uchange() { emulate -L zsh @@ -2005,6 +2025,7 @@ compdef _functions edfunc #m# f6 Stop() \kbd{/etc/init.d/\em{process}}\quad\kbd{stop} #m# f6 Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{reload} #m# f6 Force-Reload() \kbd{/etc/init.d/\em{process}}\quad\kbd{force-reload} +#m# f6 Status() \kbd{/etc/init.d/\em{process}}\quad\kbd{status} if [[ -d /etc/init.d || -d /etc/service ]] ; then __start_stop() { local action_="${1:l}" # e.g Start/Stop/Restart @@ -2036,7 +2057,7 @@ if [[ -d /etc/init.d || -d /etc/service ]] ; then _describe "service startup script" scripts } - for i in Start Restart Stop Force-Reload Reload ; do + for i in Start Restart Stop Force-Reload Reload Status ; do eval "$i() { __start_stop $i \"\$1\" \"\$2\" ; }" compdef _grmlinitd $i done @@ -2234,9 +2255,11 @@ deswap() { # VIM_OPTIONS=( -p ) # This will cause vim to send every file given on the # commandline to be send to it's own tab (needs vim7). -vim() { - VIM_PLEASE_SET_TITLE='yes' command vim ${VIM_OPTIONS} "$@" -} +if check_com vim; then + vim() { + VIM_PLEASE_SET_TITLE='yes' command vim ${VIM_OPTIONS} "$@" + } +fi # make a backup of a file bk() { @@ -2465,7 +2488,7 @@ check_com new || alias new=modified # use colors when GNU grep with color-support #a2# Execute \kbd{grep -{}-color=auto} -(( $#grep_options > 0 )) && alias grep='grep '${grep_options:+"${grep_options[*]} "} +(( $#grep_options > 0 )) && alias grep='grep '${grep_options:+"${grep_options[*]}"} # Translate DE<=>EN # 'translate' looks up fot a word in a file with language-to-language @@ -2504,62 +2527,62 @@ simple-extract() { zparseopts -D -E "d=DELETE_ORIGINAL" for ARCHIVE in "${@}"; do case $ARCHIVE in - *.(tar.bz2|tbz2|tbz)) + *(tar.bz2|tbz2|tbz)) DECOMP_CMD="tar -xvjf -" USES_STDIN=true USES_STDOUT=false ;; - *.(tar.gz|tgz)) + *(tar.gz|tgz)) DECOMP_CMD="tar -xvzf -" USES_STDIN=true USES_STDOUT=false ;; - *.(tar.xz|txz|tar.lzma)) + *(tar.xz|txz|tar.lzma)) DECOMP_CMD="tar -xvJf -" USES_STDIN=true USES_STDOUT=false ;; - *.tar) + *tar) DECOMP_CMD="tar -xvf -" USES_STDIN=true USES_STDOUT=false ;; - *.rar) + *rar) DECOMP_CMD="unrar x" USES_STDIN=false USES_STDOUT=false ;; - *.lzh) + *lzh) DECOMP_CMD="lha x" USES_STDIN=false USES_STDOUT=false ;; - *.7z) + *7z) DECOMP_CMD="7z x" USES_STDIN=false USES_STDOUT=false ;; - *.(zip|jar)) + *(zip|jar)) DECOMP_CMD="unzip" USES_STDIN=false USES_STDOUT=false ;; - *.deb) + *deb) DECOMP_CMD="ar -x" USES_STDIN=false USES_STDOUT=false ;; - *.bz2) + *bz2) DECOMP_CMD="bzip2 -d -c -" USES_STDIN=true USES_STDOUT=true ;; - *.(gz|Z)) + *(gz|Z)) DECOMP_CMD="gzip -d -c -" USES_STDIN=true USES_STDOUT=true ;; - *.(xz|lzma)) + *(xz|lzma)) DECOMP_CMD="xz -d -c -" USES_STDIN=true USES_STDOUT=true @@ -2684,12 +2707,15 @@ xtrename() { # API reference: https://code.google.com/apis/urlshortener/ function zurl() { emulate -L zsh + setopt extended_glob + if [[ -z $1 ]]; then print "USAGE: zurl " return 1 fi - local PN url prog api json data + local PN url prog api json contenttype item + local -a data PN=$0 url=$1 @@ -2707,11 +2733,19 @@ function zurl() { api='https://www.googleapis.com/urlshortener/v1/url' contenttype="Content-Type: application/json" json="{\"longUrl\": \"${url}\"}" - data=$($prog --silent -H ${contenttype} -d ${json} $api) - # Match against a regex and print it - if [[ $data =~ '"id": "(http://goo.gl/[[:alnum:]]+)"' ]]; then - print $match; - fi + data=(${(f)"$($prog --silent -H ${contenttype} -d ${json} $api)"}) + # Parse the response + for item in "${data[@]}"; do + case "$item" in + ' '#'"id":'*) + item=${item#*: \"} + item=${item%\",*} + printf '%s\n' "$item" + return 0 + ;; + esac + done + return 1 } #f2# Find history events by search pattern and list them by date.