X-Git-Url: http://git.grml.org/?p=grml-etc-core.git;a=blobdiff_plain;f=etc%2Fzsh%2Fzshrc;h=68acd4eb49a90f33fdc54d23dffcf67fbce55e45;hp=d975fbda630faedf4ffb6171bb1f8ca1d55529ae;hb=53771baf11d825d6a31cbac333f2bbb3e4277c55;hpb=d9c3851ad99948d96e6faf12142dfcbfd4e0ee61 diff --git a/etc/zsh/zshrc b/etc/zsh/zshrc index d975fbd..68acd4e 100644 --- a/etc/zsh/zshrc +++ b/etc/zsh/zshrc @@ -495,8 +495,11 @@ xcat() { xunfunction() { emulate -L zsh local -a funcs - funcs=(salias xcat xsource xunfunction zrcautoload) - + funcs=(salias xcat xsource xunfunction zrcautoload + zrcautozle + zrcbindkey + zrcgotkeymap + zrcgotwidget) for func in $funcs ; do [[ -n ${functions[$func]} ]] \ && unfunction $func @@ -591,52 +594,213 @@ 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 - [[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line - [[ -z "$terminfo[kend]" ]] || bindkey -M emacs "$terminfo[kend]" end-of-line - [[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char - [[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line - [[ -z "$terminfo[kend]" ]] || bindkey -M vicmd "$terminfo[kend]" vi-end-of-line - [[ -z "$terminfo[cuu1]" ]] || bindkey -M viins "$terminfo[cuu1]" vi-up-line-or-history - [[ -z "$terminfo[cuf1]" ]] || bindkey -M viins "$terminfo[cuf1]" vi-forward-char - [[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history - [[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history - [[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char - [[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char - # ncurses stuff: - [[ "$terminfo[kcuu1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history - [[ "$terminfo[kcud1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history - [[ "$terminfo[kcuf1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char - [[ "$terminfo[kcub1]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char - [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line - [[ "$terminfo[kend]" == $'\eO'* ]] && bindkey -M viins "${terminfo[kend]/O/[}" end-of-line - [[ "$terminfo[khome]" == $'\eO'* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line - [[ "$terminfo[kend]" == $'\eO'* ]] && bindkey -M emacs "${terminfo[kend]/O/[}" end-of-line +# Load a few modules +is4 && \ +for mod in complist deltochar mathfunc ; do + zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :(" +done + +# autoload zsh modules when they are referenced +if is4 ; then + zmodload -a zsh/stat zstat + zmodload -a zsh/zpty zpty + zmodload -ap zsh/mapfile mapfile +fi + +# completion system +if zrcautoload compinit ; then + compinit || print 'Notice: no compinit available :(' +else + print 'Notice: no compinit available :(' + function compdef { } fi -## keybindings (run 'bindkeys' for details, more details via man zshzle) -# use emacs style per default: +# completion system + +# called later (via is4 && grmlcomp) +# note: use 'zstyle' for getting current settings +# press ^xh (control-x h) for getting tags in context; ^x? (control-x ?) to run complete_debug with trace output +grmlcomp() { + # TODO: This could use some additional information + + # Make sure the completion system is initialised + (( ${+_comps} )) || return 1 + + # allow one error for every three characters typed in approximate completer + zstyle ':completion:*:approximate:' max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )' + + # don't complete backup files as executables + zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)' + + # start menu completion only if it could find no unambiguous initial string + zstyle ':completion:*:correct:*' insert-unambiguous true + zstyle ':completion:*:corrections' format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}' + zstyle ':completion:*:correct:*' original true + + # activate color-completion + zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS} + + # format on completion + zstyle ':completion:*:descriptions' format $'%{\e[0;31m%}completing %B%d%b%{\e[0m%}' + + # automatically complete 'cd -' and 'cd -' with menu + # zstyle ':completion:*:*:cd:*:directory-stack' menu yes select + + # insert all expansions for expand completer + zstyle ':completion:*:expand:*' tag-order all-expansions + zstyle ':completion:*:history-words' list false + + # activate menu + zstyle ':completion:*:history-words' menu yes + + # ignore duplicate entries + zstyle ':completion:*:history-words' remove-all-dups yes + zstyle ':completion:*:history-words' stop yes + + # match uppercase from lowercase + zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' + + # separate matches into groups + zstyle ':completion:*:matches' group 'yes' + zstyle ':completion:*' group-name '' + + if [[ "$NOMENU" -eq 0 ]] ; then + # if there are more than 5 options allow selecting from a menu + zstyle ':completion:*' menu select=5 + else + # don't use any menus at all + setopt no_auto_menu + fi + + zstyle ':completion:*:messages' format '%d' + zstyle ':completion:*:options' auto-description '%d' + + # describe options in full + zstyle ':completion:*:options' description 'yes' + + # on processes completion complete all user processes + zstyle ':completion:*:processes' command 'ps -au$USER' + + # offer indexes before parameters in subscripts + zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters + + # provide verbose completion information + zstyle ':completion:*' verbose true + + # recent (as of Dec 2007) zsh versions are able to provide descriptions + # for commands (read: 1st word in the line) that it will list for the user + # to choose from. The following disables that, because it's not exactly fast. + zstyle ':completion:*:-command-:*:' verbose false + + # set format for warnings + zstyle ':completion:*:warnings' format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' + + # define files to ignore for zcompile + zstyle ':completion:*:*:zcompile:*' ignored-patterns '(*~|*.zwc)' + zstyle ':completion:correct:' prompt 'correct to: %e' + + # Ignore completion functions for commands you don't have: + zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*' + + # Provide more processes in completion of programs like killall: + zstyle ':completion:*:processes-names' command 'ps c -u ${USER} -o command | uniq' + + # complete manual by their section + zstyle ':completion:*:manuals' separate-sections true + 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 .. + + # run rehash on completion so new installed program are found automatically: + _force_rehash() { + (( CURRENT == 1 )) && rehash + return 1 + } + + ## correction + # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it + if [[ "$NOCOR" -gt 0 ]] ; then + zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored + setopt nocorrect + else + # try to be smart about when to use what completer... + setopt correct + zstyle -e ':completion:*' completer ' + if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then + _last_try="$HISTNO$BUFFER$CURSOR" + reply=(_complete _match _ignored _prefix _files) + else + if [[ $words[1] == (rm|mv) ]] ; then + reply=(_complete _files) + else + reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files) + fi + fi' + fi + + # command for process lists, the local web server details and host completion + zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html' + + # caching + [[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \ + zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/ + + # host completion + if is42 ; then + [[ -r ~/.ssh/known_hosts ]] && _ssh_hosts=(${${${${(f)"$(<$HOME/.ssh/known_hosts)"}:#[\|]*}%%\ *}%%,*}) || _ssh_hosts=() + [[ -r /etc/hosts ]] && : ${(A)_etc_hosts:=${(s: :)${(ps:\t:)${${(f)~~"$(, Bernhard Tittelbach @@ -655,69 +819,6 @@ beginning-or-end-of-somewhere() { zle -N beginning-of-somewhere beginning-or-end-of-somewhere zle -N end-of-somewhere beginning-or-end-of-somewhere - -#if [[ "$TERM" == screen ]] ; then - -## with HOME/END, move to beginning/end of line (on multiline) on first keypress -## to beginning/end of buffer on second keypress -## and to beginning/end of history on (at most) the third keypress -# terminator & non-debian xterm -bindkey '\eOH' beginning-of-somewhere # home -bindkey '\eOF' end-of-somewhere # end -# freebsd console -bindkey '\e[H' beginning-of-somewhere # home -bindkey '\e[F' end-of-somewhere # end -# xterm,gnome-terminal,quake,etc -bindkey '^[[1~' beginning-of-somewhere # home -bindkey '^[[4~' end-of-somewhere # end -# if terminal type is set to 'rxvt': -bindkey '\e[7~' beginning-of-somewhere # home -bindkey '\e[8~' end-of-somewhere # end -#fi - -bindkey '\e[A' up-line-or-search # cursor up -bindkey '\e[B' down-line-or-search # - - -## use Ctrl-left-arrow and Ctrl-right-arrow for jumping to word-beginnings on the CL -bindkey "\e[5C" forward-word -bindkey "\e[5D" backward-word -bindkey "\e[1;5C" forward-word -bindkey "\e[1;5D" backward-word -## the same for alt-left-arrow and alt-right-arrow -bindkey '^[[1;3C' forward-word -bindkey '^[[1;3D' backward-word - -# Search backward in the history for a line beginning with the current -# line up to the cursor and move the cursor to the end of the line then -zle -N history-beginning-search-backward-end history-search-end -zle -N history-beginning-search-forward-end history-search-end -#k# search history backward for entry beginning with typed text -bindkey '^xp' history-beginning-search-backward-end -#k# search history forward for entry beginning with typed text -bindkey '^xP' history-beginning-search-forward-end -#k# search history backward for entry beginning with typed text -bindkey "\e[5~" history-beginning-search-backward-end # PageUp -#k# search history forward for entry beginning with typed text -bindkey "\e[6~" history-beginning-search-forward-end # PageDown - -# bindkey -s '^l' "|less\n" # ctrl-L pipes to less -# bindkey -s '^b' " &\n" # ctrl-B runs it in the background - -# insert unicode character -# usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an § -# See for example http://unicode.org/charts/ for unicode characters code -zrcautoload insert-unicode-char -zle -N insert-unicode-char -#k# Insert Unicode character -bindkey '^xi' insert-unicode-char - -#m# k Shift-tab Perform backwards menu completion -if [[ -n "$terminfo[kcbt]" ]]; then - bindkey "$terminfo[kcbt]" reverse-menu-complete -elif [[ -n "$terminfo[cbt]" ]]; then # required for GNU screen - bindkey "$terminfo[cbt]" reverse-menu-complete -fi - ## toggle the ,. abbreviation feature on/off # NOABBREVIATION: default abbreviation-state # 0 - enabled (default) @@ -731,9 +832,6 @@ grml_toggle_abbrev() { NOABBREVIATION=1 fi } - -#k# Toggle abbreviation expansion on/off -bindkey '^xA' grml_toggle_abbrev zle -N grml_toggle_abbrev # add a command line to the shells history without executing it @@ -742,7 +840,6 @@ commit-to-history() { zle send-break } zle -N commit-to-history -bindkey "^x^h" commit-to-history # only slash should be considered as a word separator: slash-backward-kill-word() { @@ -752,19 +849,6 @@ slash-backward-kill-word() { } zle -N slash-backward-kill-word -#k# Kill left-side word or everything up to next slash -bindkey '\ev' slash-backward-kill-word -#k# Kill left-side word or everything up to next slash -bindkey '\e^h' slash-backward-kill-word -#k# Kill left-side word or everything up to next slash -bindkey '\e^?' slash-backward-kill-word - -# use the new *-pattern-* widgets for incremental history search -if is439 ; then - bindkey '^r' history-incremental-pattern-search-backward - bindkey '^s' history-incremental-pattern-search-forward -fi - # a generic accept-line wrapper # This widget can prevent unwanted autocorrections from command-name @@ -956,189 +1040,475 @@ zleiab() { LBUFFER+=${abk[$MATCH]:-$MATCH} } -zle -N zleiab && bindkey ",." zleiab +zle -N zleiab && bindkey ",." zleiab ## KEYB! -#f# display contents of assoc array $abk help-show-abk() { zle -M "$(print "Type ,. after these abbreviations to expand them:"; print -a -C 2 ${(kv)abk})" } -#k# Display list of abbreviations that expand when followed by ,. -zle -N help-show-abk && bindkey '^xb' help-show-abk -# autoloading -zrcautoload zmv # who needs mmv or rename? -zrcautoload history-search-end +#k# Display list of abbreviations that expand when followed by ,. +zle -N help-show-abk && bindkey '^xb' help-show-abk ## KEYB! -# we don't want to quote/espace URLs on our own... -# if autoload -U url-quote-magic ; then -# zle -N self-insert url-quote-magic -# zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}=' -# else -# print 'Notice: no url-quote-magic available :(' -# fi -alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic' +# press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd +insert-datestamp() { LBUFFER+=${(%):-'%D{%Y-%m-%d}'}; } +zle -N insert-datestamp -#m# k ESC-h Call \kbd{run-help} for the 1st word on the command line -alias run-help >&/dev/null && unalias run-help -for rh in run-help{,-git,-svk,-svn}; do - zrcautoload $rh -done; unset rh +# press esc-m for inserting last typed word again (thanks to caphuso!) +insert-last-typed-word() { zle insert-last-word -- 0 -1 }; +zle -N insert-last-typed-word; -# command not found handling +function grml-zsh-fg() { + if (( ${#jobstates} )); then + zle .push-input + [[ -o hist_ignore_space ]] && BUFFER=' ' || BUFFER='' + BUFFER="${BUFFER}fg" + zle .accept-line + else + zle -M 'No background jobs. Doing nothing.' + fi +} +zle -N grml-zsh-fg -(( ${COMMAND_NOT_FOUND} == 1 )) && -function command_not_found_handler() { +# run command line as user root via sudo: +sudo-command-line() { + [[ -z $BUFFER ]] && zle up-history + if [[ $BUFFER != sudo\ * ]]; then + BUFFER="sudo $BUFFER" + CURSOR=$(( CURSOR+5 )) + fi +} +zle -N sudo-command-line + +### jump behind the first word on the cmdline. +### useful to add options. +function jump_after_first_word() { + local words + words=(${(z)BUFFER}) + + if (( ${#words} <= 1 )) ; then + CURSOR=${#BUFFER} + else + CURSOR=${#${words[1]}} + fi +} +zle -N jump_after_first_word + +#f5# Create directory under cursor or the selected area +inplaceMkDirs() { + # Press ctrl-xM to create the directory under the cursor or the selected area. + # To select an area press ctrl-@ or ctrl-space and use the cursor. + # Use case: you type "mv abc ~/testa/testb/testc/" and remember that the + # directory does not exist yet -> press ctrl-XM and problem solved + local PATHTOMKDIR + if ((REGION_ACTIVE==1)); then + local F=$MARK T=$CURSOR + if [[ $F -gt $T ]]; then + F=${CURSOR} + T=${MARK} + fi + # get marked area from buffer and eliminate whitespace + PATHTOMKDIR=${BUFFER[F+1,T]%%[[:space:]]##} + PATHTOMKDIR=${PATHTOMKDIR##[[:space:]]##} + else + local bufwords iword + bufwords=(${(z)LBUFFER}) + iword=${#bufwords} + bufwords=(${(z)BUFFER}) + PATHTOMKDIR="${(Q)bufwords[iword]}" + fi + [[ -z "${PATHTOMKDIR}" ]] && return 1 + PATHTOMKDIR=${~PATHTOMKDIR} + if [[ -e "${PATHTOMKDIR}" ]]; then + zle -M " path already exists, doing nothing" + else + zle -M "$(mkdir -p -v "${PATHTOMKDIR}")" + zle end-of-line + fi +} + +#k# mkdir -p from string under cursor or marked area +zle -N inplaceMkDirs && bindkey '^xM' inplaceMkDirs ## KEYB! + +#v1# set number of lines to display per page +HELP_LINES_PER_PAGE=20 +#v1# set location of help-zle cache file +HELP_ZLE_CACHE_FILE=~/.cache/zsh_help_zle_lines.zsh +# helper function for help-zle, actually generates the help text +help_zle_parse_keybindings() +{ emulate -L zsh - if [[ -x ${GRML_ZSH_CNF_HANDLER} ]] ; then - ${GRML_ZSH_CNF_HANDLER} $1 + setopt extendedglob + unsetopt ksharrays #indexing starts at 1 + + #v1# choose files that help-zle will parse for keybindings + ((${+HELPZLE_KEYBINDING_FILES})) || HELPZLE_KEYBINDING_FILES=( /etc/zsh/zshrc ~/.zshrc.pre ~/.zshrc ~/.zshrc.local ) + + if [[ -r $HELP_ZLE_CACHE_FILE ]]; then + local load_cache=0 + for f ($HELPZLE_KEYBINDING_FILES) [[ $f -nt $HELP_ZLE_CACHE_FILE ]] && load_cache=1 + [[ $load_cache -eq 0 ]] && . $HELP_ZLE_CACHE_FILE && return fi - return 1 + + #fill with default keybindings, possibly to be overwriten in a file later + #Note that due to zsh inconsistency on escaping assoc array keys, we encase the key in '' which we will remove later + local -A help_zle_keybindings + help_zle_keybindings['@']="set MARK" + help_zle_keybindings['xj']="vi-join lines" + help_zle_keybindings['xb']="jump to matching brace" + help_zle_keybindings['xu']="undo" + help_zle_keybindings['_']="undo" + help_zle_keybindings['xf']="find in cmdline" + help_zle_keybindings['a']="goto beginning of line" + help_zle_keybindings['e']="goto end of line" + help_zle_keybindings['t']="transpose charaters" + help_zle_keybindings['t']="transpose words" + help_zle_keybindings['s']="spellcheck word" + help_zle_keybindings['k']="backward kill buffer" + help_zle_keybindings['u']="forward kill buffer" + help_zle_keybindings['y']="insert previously killed word/string" + help_zle_keybindings["'"]="quote line" + help_zle_keybindings['"']="quote from mark to cursor" + help_zle_keybindings['']="repeat next cmd/char times (-10a -> -10 times 'a')" + help_zle_keybindings['u']="make next word Uppercase" + help_zle_keybindings['l']="make next word lowercase" + help_zle_keybindings['xd']="preview expansion under cursor" + help_zle_keybindings['q']="push current CL into background, freeing it. Restore on next CL" + help_zle_keybindings['.']="insert (and interate through) last word from prev CLs" + help_zle_keybindings[',']="complete word from newer history (consecutive hits)" + help_zle_keybindings['m']="repeat last typed word on current CL" + help_zle_keybindings['v']="insert next keypress symbol literally (e.g. for bindkey)" + help_zle_keybindings['!!:n*']="insert last n arguments of last command" + help_zle_keybindings['!!:n-']="insert arguments n..N-2 of last command (e.g. mv s s d)" + help_zle_keybindings['h']="show help/manpage for current command" + + #init global variables + unset help_zle_lines help_zle_sln + typeset -g -a help_zle_lines + typeset -g help_zle_sln=1 + + local k v + local lastkeybind_desc contents #last description starting with #k# that we found + local num_lines_elapsed=0 #number of lines between last description and keybinding + #search config files in the order they a called (and thus the order in which they overwrite keybindings) + for f in $HELPZLE_KEYBINDING_FILES; do + [[ -r "$f" ]] || continue #not readable ? skip it + contents="$(<$f)" + for cline in "${(f)contents}"; do + #zsh pattern: matches lines like: #k# .............. + if [[ "$cline" == (#s)[[:space:]]#\#k\#[[:space:]]##(#b)(*)[[:space:]]#(#e) ]]; then + lastkeybind_desc="$match[*]" + num_lines_elapsed=0 + #zsh pattern: matches lines that set a keybinding using bindkey or compdef -k + # ignores lines that are commentend out + # grabs first in '' or "" enclosed string with length between 1 and 6 characters + elif [[ "$cline" == [^#]#(bindkey|compdef -k)[[:space:]](*)(#b)(\"((?)(#c1,6))\"|\'((?)(#c1,6))\')(#B)(*) ]]; then + #description prevously found ? description not more than 2 lines away ? keybinding not empty ? + if [[ -n $lastkeybind_desc && $num_lines_elapsed -lt 2 && -n $match[1] ]]; then + #substitute keybinding string with something readable + k=${${${${${${${match[1]/\\e\^h/}/\\e\^\?/}/\\e\[5~/}/\\e\[6~/}//(\\e|\^\[)/}//\^/}/3~/} + #put keybinding in assoc array, possibly overwriting defaults or stuff found in earlier files + #Note that we are extracting the keybinding-string including the quotes (see Note at beginning) + help_zle_keybindings[${k}]=$lastkeybind_desc + fi + lastkeybind_desc="" + else + ((num_lines_elapsed++)) + fi + done + done + unset contents + #calculate length of keybinding column + local kstrlen=0 + for k (${(k)help_zle_keybindings[@]}) ((kstrlen < ${#k})) && kstrlen=${#k} + #convert the assoc array into preformated lines, which we are able to sort + for k v in ${(kv)help_zle_keybindings[@]}; do + #pad keybinding-string to kstrlen chars and remove outermost characters (i.e. the quotes) + help_zle_lines+=("${(r:kstrlen:)k[2,-2]}${v}") + done + #sort lines alphabetically + help_zle_lines=("${(i)help_zle_lines[@]}") + [[ -d ${HELP_ZLE_CACHE_FILE:h} ]] || mkdir -p "${HELP_ZLE_CACHE_FILE:h}" + echo "help_zle_lines=(${(q)help_zle_lines[@]})" >| $HELP_ZLE_CACHE_FILE + zcompile $HELP_ZLE_CACHE_FILE } +typeset -g help_zle_sln +typeset -g -a help_zle_lines -# completion system -if zrcautoload compinit ; then - compinit || print 'Notice: no compinit available :(' -else - print 'Notice: no compinit available :(' - function compdef { } -fi +# Provides (partially autogenerated) help on keybindings and the zsh line editor +help-zle() +{ + emulate -L zsh + unsetopt ksharrays #indexing starts at 1 + #help lines already generated ? no ? then do it + [[ ${+functions[help_zle_parse_keybindings]} -eq 1 ]] && {help_zle_parse_keybindings && unfunction help_zle_parse_keybindings} + #already displayed all lines ? go back to the start + [[ $help_zle_sln -gt ${#help_zle_lines} ]] && help_zle_sln=1 + local sln=$help_zle_sln + #note that help_zle_sln is a global var, meaning we remember the last page we viewed + help_zle_sln=$((help_zle_sln + HELP_LINES_PER_PAGE)) + zle -M "${(F)help_zle_lines[sln,help_zle_sln-1]}" +} +#k# display help for keybindings and ZLE +zle -N help-zle && bindkey '^xz' help-zle # note: cycle pages with consecutive use of '^xz' ## KEYB! -is4 && zrcautoload zed # use ZLE editor to edit a file or function +## complete word from currently visible Screen or Tmux buffer. +if check_com -c screen || check_com -c tmux; then + _complete_screen_display() { + [[ "$TERM" != "screen" ]] && return 1 -is4 && \ -for mod in complist deltochar mathfunc ; do - zmodload -i zsh/${mod} 2>/dev/null || print "Notice: no ${mod} available :(" -done + local TMPFILE=$(mktemp) + local -U -a _screen_display_wordlist + trap "rm -f $TMPFILE" EXIT -# autoload zsh modules when they are referenced -if is4 ; then - zmodload -a zsh/stat zstat - zmodload -a zsh/zpty zpty - zmodload -ap zsh/mapfile mapfile + # fill array with contents from screen hardcopy + if ((${+TMUX})); then + #works, but crashes tmux below version 1.4 + #luckily tmux -V option to ask for version, was also added in 1.4 + tmux -V &>/dev/null || return + tmux -q capture-pane \; save-buffer -b 0 $TMPFILE \; delete-buffer -b 0 + else + screen -X hardcopy $TMPFILE + # screen sucks, it dumps in latin1, apparently always. so recode it + # to system charset + check_com recode && recode latin1 $TMPFILE + fi + _screen_display_wordlist=( ${(QQ)$(<$TMPFILE)} ) + # remove PREFIX to be completed from that array + _screen_display_wordlist[${_screen_display_wordlist[(i)$PREFIX]}]="" + compadd -a _screen_display_wordlist + } + #m# k CTRL-x\,\,\,S Complete word from GNU screen buffer + bindkey -r "^xS" + compdef -k _complete_screen_display complete-word '^xS' fi -if is4 && zrcautoload insert-files && zle -N insert-files ; then - #k# Insert files and test globbing - bindkey "^xf" insert-files # C-x-f +# Load a few more functions and tie them to widgets, so they can be bound: + +function zrcautozle() { + emulate -L zsh + local fnc=$1 + zrcautoload $fnc && zle -N $fnc +} + +function zrcgotwidget() { + (( ${+widgets[$i]} )) +} + +function zrcgotkeymap() { + [[ -n ${(M)keymaps:#$1} ]] +} + +zrcautozle insert-files +zrcautozle edit-command-line +zrcautozle insert-unicode-char +if zrcautoload history-search-end; then + zle -N history-beginning-search-backward-end history-search-end + zle -N history-beginning-search-forward-end history-search-end fi +zle -C hist-complete complete-word _generic +zstyle ':completion:hist-complete:*' completer _history -bindkey ' ' magic-space # also do history expansion on space -#k# Trigger menu-complete -bindkey '\ei' menu-complete # menu completion via esc-i +# The actual terminal setup hooks and bindkey-calls: + +# An array to note missing features to ease diagnosis in case of problems. +typeset -ga grml_missing_features + +function zrcbindkey() { + if (( ARGC && ${+widgets[${argv[-1]}]} )); then + bindkey "$@" + fi +} + +function bind2maps () { + local i sequence widget + local -a maps + + while [[ "$1" != "--" ]]; do + maps+=( "$1" ) + shift + done + shift + + sequence="${key[$1]}" + widget="$2" + + [[ -z "$sequence" ]] && return 1 + + for i in "${maps[@]}"; do + zrcbindkey -M "$i" "$sequence" "$widget" + done +} -# press esc-e for editing command line in $EDITOR or $VISUAL -if is4 && zrcautoload edit-command-line && zle -N edit-command-line ; then - #k# Edit the current line in \kbd{\$EDITOR} - bindkey '\ee' edit-command-line +if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then + function zle-smkx () { + printf '%s' ${terminfo[smkx]} + } + function zle-rmkx () { + printf '%s' ${terminfo[rmkx]} + } + function zle-line-init () { + zle-smkx + } + function zle-line-finish () { + zle-rmkx + } + zle -N zle-line-init + zle -N zle-line-finish +else + for i in {s,r}mkx; do + (( ${+terminfo[$i]} )) || grml_missing_features+=($i) + done + unset i fi -if is4 && [[ -n ${(k)modules[zsh/complist]} ]] ; then +typeset -A key +key=( + Home "${terminfo[khome]}" + End "${terminfo[kend]}" + Insert "${terminfo[kich1]}" + Delete "${terminfo[kdch1]}" + Up "${terminfo[kcuu1]}" + Down "${terminfo[kcud1]}" + Left "${terminfo[kcub1]}" + Right "${terminfo[kcuf1]}" + PageUp "${terminfo[kpp]}" + PageDown "${terminfo[knp]}" + BackTab "${terminfo[kcbt]}" +) + +bind2maps emacs -- Home beginning-of-somewhere +bind2maps viins vicmd -- Home vi-beginning-of-line +bind2maps emacs -- End end-of-somewhere +bind2maps viins vicmd -- End vi-end-of-line +bind2maps emacs viins -- Insert overwrite-mode +bind2maps vicmd -- Insert vi-insert +bind2maps emacs -- Delete delete-char +bind2maps viins vicmd -- Delete vi-delete-char +bind2maps emacs viins vicmd -- Up up-line-or-search +bind2maps emacs viins vicmd -- Down down-line-or-search +bind2maps emacs -- Left backward-char +bind2maps viins vicmd -- Left vi-backward-char +bind2maps emacs -- Right forward-char +bind2maps viins vicmd -- Right vi-forward-char +bind2maps viins vicmd -- Right vi-forward-char + +if zrcgotkeymap menuselect; then + bind2maps menuselect -- BackTab reverse-menu-complete + #k# menu selection: pick item but stay in the menu - bindkey -M menuselect '\e^M' accept-and-menu-complete + zrcbindkey -M menuselect '\e^M' accept-and-menu-complete # also use + and INSERT since it's easier to press repeatedly - bindkey -M menuselect "+" accept-and-menu-complete - bindkey -M menuselect "^[[2~" accept-and-menu-complete + zrcbindkey -M menuselect "+" accept-and-menu-complete + zrcbindkey -M menuselect "^[[2~" accept-and-menu-complete # accept a completion and try to complete again by using menu # completion; very useful with completing directories # by using 'undo' one's got a simple file browser - bindkey -M menuselect '^o' accept-and-infer-next-history + zrcbindkey -M menuselect '^o' accept-and-infer-next-history fi -# press "ctrl-e d" to insert the actual date in the form yyyy-mm-dd -insert-datestamp() { LBUFFER+=${(%):-'%D{%Y-%m-%d}'}; } -zle -N insert-datestamp +#k# Insert files and test globbing +zrcbindkey "^xf" insert-files # C-x-f -#k# Insert a timestamp on the command line (yyyy-mm-dd) -bindkey '^ed' insert-datestamp +#k# Edit the current line in \kbd{\$EDITOR} +zrcbindkey '\ee' edit-command-line -# press esc-m for inserting last typed word again (thanks to caphuso!) -insert-last-typed-word() { zle insert-last-word -- 0 -1 }; -zle -N insert-last-typed-word; +## use Ctrl-left-arrow and Ctrl-right-arrow for jumping to word-beginnings on the CL +zrcbindkey "\e[5C" forward-word +zrcbindkey "\e[5D" backward-word +zrcbindkey "\e[1;5C" forward-word +zrcbindkey "\e[1;5D" backward-word +## the same for alt-left-arrow and alt-right-arrow +zrcbindkey '^[[1;3C' forward-word +zrcbindkey '^[[1;3D' backward-word + +#k# search history backward for entry beginning with typed text +zrcbindkey '^xp' history-beginning-search-backward-end +#k# search history forward for entry beginning with typed text +zrcbindkey '^xP' history-beginning-search-forward-end +#k# search history backward for entry beginning with typed text +zrcbindkey "\e[5~" history-beginning-search-backward-end # PageUp +#k# search history forward for entry beginning with typed text +zrcbindkey "\e[6~" history-beginning-search-forward-end # PageDown + +# insert unicode character +# usage example: 'ctrl-x i' 00A7 'ctrl-x i' will give you an § +# See for example http://unicode.org/charts/ for unicode characters code +#k# Insert Unicode character +zrcbindkey '^xi' insert-unicode-char + +#m# k Shift-tab Perform backwards menu completion +if [[ -n "$terminfo[kcbt]" ]]; then + zrcbindkey "$terminfo[kcbt]" reverse-menu-complete +elif [[ -n "$terminfo[cbt]" ]]; then # required for GNU screen + zrcbindkey "$terminfo[cbt]" reverse-menu-complete +fi -#k# Insert last typed word -bindkey "\em" insert-last-typed-word +#k# Toggle abbreviation expansion on/off +zrcbindkey '^xA' grml_toggle_abbrev +zrcbindkey "^x^h" commit-to-history -function grml-zsh-fg() { - if (( ${#jobstates} )); then - zle .push-input - [[ -o hist_ignore_space ]] && BUFFER=' ' || BUFFER='' - BUFFER="${BUFFER}fg" - zle .accept-line - else - zle -M 'No background jobs. Doing nothing.' - fi -} -zle -N grml-zsh-fg -#k# A smart shortcut for \kbd{fg} -bindkey '^z' grml-zsh-fg +#k# Kill left-side word or everything up to next slash +zrcbindkey '\ev' slash-backward-kill-word +#k# Kill left-side word or everything up to next slash +zrcbindkey '\e^h' slash-backward-kill-word +#k# Kill left-side word or everything up to next slash +zrcbindkey '\e^?' slash-backward-kill-word -# run command line as user root via sudo: -sudo-command-line() { - [[ -z $BUFFER ]] && zle up-history - if [[ $BUFFER != sudo\ * ]]; then - BUFFER="sudo $BUFFER" - CURSOR=$(( CURSOR+5 )) - fi -} -zle -N sudo-command-line +# use the new *-pattern-* widgets for incremental history search +if zrcgotwidget history-incremental-pattern-search-backward; then + zrcbindkey '^r' history-incremental-pattern-search-backward + zrcbindkey '^s' history-incremental-pattern-search-forward +fi +# Do history expansion on space: +zrcbindkey ' ' magic-space +#k# Trigger menu-complete +zrcbindkey '\ei' menu-complete # menu completion via esc-i +#k# Insert a timestamp on the command line (yyyy-mm-dd) +zrcbindkey '^ed' insert-datestamp +#k# Insert last typed word +zrcbindkey "\em" insert-last-typed-word +#k# A smart shortcut for \kbd{fg} +zrcbindkey '^z' grml-zsh-fg #k# prepend the current command with "sudo" -bindkey "^os" sudo-command-line +zrcbindkey "^os" sudo-command-line +#k# jump to after first word (for adding options) +zrcbindkey '^x1' jump_after_first_word +#k# complete word from history with menu +zrcbindkey "^x^x" hist-complete -### jump behind the first word on the cmdline. -### useful to add options. -function jump_after_first_word() { - local words - words=(${(z)BUFFER}) +# autoloading - if (( ${#words} <= 1 )) ; then - CURSOR=${#BUFFER} - else - CURSOR=${#${words[1]}} - fi -} -zle -N jump_after_first_word -#k# jump to after first word (for adding options) -bindkey '^x1' jump_after_first_word +zrcautoload zmv +zrcautoload zed -# complete word from history with menu (from Book: ZSH, OpenSource-Press) -zle -C hist-complete complete-word _generic -zstyle ':completion:hist-complete:*' completer _history -#k# complete word from history with menu -bindkey "^x^x" hist-complete +# we don't want to quote/espace URLs on our own... +# if autoload -U url-quote-magic ; then +# zle -N self-insert url-quote-magic +# zstyle ':url-quote-magic:*' url-metas '*?[]^()~#{}=' +# else +# print 'Notice: no url-quote-magic available :(' +# fi +alias url-quote='autoload -U url-quote-magic ; zle -N self-insert url-quote-magic' -## complete word from currently visible Screen or Tmux buffer. -if check_com -c screen || check_com -c tmux; then - _complete_screen_display() { - [[ "$TERM" != "screen" ]] && return 1 +#m# k ESC-h Call \kbd{run-help} for the 1st word on the command line +alias run-help >&/dev/null && unalias run-help +for rh in run-help{,-git,-svk,-svn}; do + zrcautoload $rh +done; unset rh - local TMPFILE=$(mktemp) - local -U -a _screen_display_wordlist - trap "rm -f $TMPFILE" EXIT +# command not found handling - # fill array with contents from screen hardcopy - if ((${+TMUX})); then - #works, but crashes tmux below version 1.4 - #luckily tmux -V option to ask for version, was also added in 1.4 - tmux -V &>/dev/null || return - tmux -q capture-pane \; save-buffer -b 0 $TMPFILE \; delete-buffer -b 0 - else - screen -X hardcopy $TMPFILE - # screen sucks, it dumps in latin1, apparently always. so recode it - # to system charset - check_com recode && recode latin1 $TMPFILE - fi - _screen_display_wordlist=( ${(QQ)$(<$TMPFILE)} ) - # remove PREFIX to be completed from that array - _screen_display_wordlist[${_screen_display_wordlist[(i)$PREFIX]}]="" - compadd -a _screen_display_wordlist - } - #m# k CTRL-x\,\,\,S Complete word from GNU screen buffer - bindkey -r "^xS" - compdef -k _complete_screen_display complete-word '^xS' -fi +(( ${COMMAND_NOT_FOUND} == 1 )) && +function command_not_found_handler() { + emulate -L zsh + if [[ -x ${GRML_ZSH_CNF_HANDLER} ]] ; then + ${GRML_ZSH_CNF_HANDLER} $1 + fi + return 1 +} # history @@ -1907,224 +2277,57 @@ if [[ -r /etc/debian_version ]] ; then #a3# Execute \kbd{apt-get dist-upgrade} salias adg="apt-get dist-upgrade" #a3# Execute \kbd{apt-get install} - salias agi="apt-get install" - #a3# Execute \kbd{aptitude install} - salias ati="aptitude install" - #a3# Execute \kbd{apt-get upgrade} - salias ag="apt-get upgrade" - #a3# Execute \kbd{apt-get update} - salias au="apt-get update" - #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade} - salias -a up="aptitude update ; aptitude safe-upgrade" - #a3# Execute \kbd{dpkg-buildpackage} - alias dbp='dpkg-buildpackage' - #a3# Execute \kbd{grep-excuses} - alias ge='grep-excuses' - - # get a root shell as normal user in live-cd mode: - if isgrmlcd && [[ $UID -ne 0 ]] ; then - alias su="sudo su" - fi - - #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog} - salias llog="$PAGER /var/log/syslog" # take a look at the syslog - #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog} - salias tlog="tail -f /var/log/syslog" # follow the syslog -fi - -# sort installed Debian-packages by size -if check_com -c dpkg-query ; then - #a3# List installed Debian-packages sorted by size - alias debs-by-size="dpkg-query -Wf 'x \${Installed-Size} \${Package} \${Status}\n' | sed -ne '/^x /d' -e '/^x \(.*\) install ok installed$/s//\1/p' | sort -nr" -fi - -# if cdrecord is a symlink (to wodim) or isn't present at all warn: -if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord; then - if check_com -c wodim; then - cdrecord() { - cat <' and 'cd -' with menu - # zstyle ':completion:*:*:cd:*:directory-stack' menu yes select - - # insert all expansions for expand completer - zstyle ':completion:*:expand:*' tag-order all-expansions - zstyle ':completion:*:history-words' list false - - # activate menu - zstyle ':completion:*:history-words' menu yes - - # ignore duplicate entries - zstyle ':completion:*:history-words' remove-all-dups yes - zstyle ':completion:*:history-words' stop yes - - # match uppercase from lowercase - zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' - - # separate matches into groups - zstyle ':completion:*:matches' group 'yes' - zstyle ':completion:*' group-name '' - - if [[ "$NOMENU" -eq 0 ]] ; then - # if there are more than 5 options allow selecting from a menu - zstyle ':completion:*' menu select=5 - else - # don't use any menus at all - setopt no_auto_menu - fi - - zstyle ':completion:*:messages' format '%d' - zstyle ':completion:*:options' auto-description '%d' - - # describe options in full - zstyle ':completion:*:options' description 'yes' - - # on processes completion complete all user processes - zstyle ':completion:*:processes' command 'ps -au$USER' - - # offer indexes before parameters in subscripts - zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters - - # provide verbose completion information - zstyle ':completion:*' verbose true - - # recent (as of Dec 2007) zsh versions are able to provide descriptions - # for commands (read: 1st word in the line) that it will list for the user - # to choose from. The following disables that, because it's not exactly fast. - zstyle ':completion:*:-command-:*:' verbose false - - # set format for warnings - zstyle ':completion:*:warnings' format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d' - - # define files to ignore for zcompile - zstyle ':completion:*:*:zcompile:*' ignored-patterns '(*~|*.zwc)' - zstyle ':completion:correct:' prompt 'correct to: %e' - - # Ignore completion functions for commands you don't have: - zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*' - - # Provide more processes in completion of programs like killall: - zstyle ':completion:*:processes-names' command 'ps c -u ${USER} -o command | uniq' - - # complete manual by their section - zstyle ':completion:*:manuals' separate-sections true - 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 .. + salias agi="apt-get install" + #a3# Execute \kbd{aptitude install} + salias ati="aptitude install" + #a3# Execute \kbd{apt-get upgrade} + salias ag="apt-get upgrade" + #a3# Execute \kbd{apt-get update} + salias au="apt-get update" + #a3# Execute \kbd{aptitude update ; aptitude safe-upgrade} + salias -a up="aptitude update ; aptitude safe-upgrade" + #a3# Execute \kbd{dpkg-buildpackage} + alias dbp='dpkg-buildpackage' + #a3# Execute \kbd{grep-excuses} + alias ge='grep-excuses' - # run rehash on completion so new installed program are found automatically: - _force_rehash() { - (( CURRENT == 1 )) && rehash - return 1 - } + # get a root shell as normal user in live-cd mode: + if isgrmlcd && [[ $UID -ne 0 ]] ; then + alias su="sudo su" + fi - ## correction - # some people don't like the automatic correction - so run 'NOCOR=1 zsh' to deactivate it - if [[ "$NOCOR" -gt 0 ]] ; then - zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored - setopt nocorrect - else - # try to be smart about when to use what completer... - setopt correct - zstyle -e ':completion:*' completer ' - if [[ $_last_try != "$HISTNO$BUFFER$CURSOR" ]] ; then - _last_try="$HISTNO$BUFFER$CURSOR" - reply=(_complete _match _ignored _prefix _files) - else - if [[ $words[1] == (rm|mv) ]] ; then - reply=(_complete _files) - else - reply=(_oldlist _expand _force_rehash _complete _ignored _correct _approximate _files) - fi - fi' - fi + #a1# Take a look at the syslog: \kbd{\$PAGER /var/log/syslog} + salias llog="$PAGER /var/log/syslog" # take a look at the syslog + #a1# Take a look at the syslog: \kbd{tail -f /var/log/syslog} + salias tlog="tail -f /var/log/syslog" # follow the syslog +fi - # command for process lists, the local web server details and host completion - zstyle ':completion:*:urls' local 'www' '/var/www/' 'public_html' +# sort installed Debian-packages by size +if check_com -c dpkg-query ; then + #a3# List installed Debian-packages sorted by size + alias debs-by-size="dpkg-query -Wf 'x \${Installed-Size} \${Package} \${Status}\n' | sed -ne '/^x /d' -e '/^x \(.*\) install ok installed$/s//\1/p' | sort -nr" +fi - # caching - [[ -d $ZSHDIR/cache ]] && zstyle ':completion:*' use-cache yes && \ - zstyle ':completion::complete:*' cache-path $ZSHDIR/cache/ +# if cdrecord is a symlink (to wodim) or isn't present at all warn: +if [[ -L /usr/bin/cdrecord ]] || ! check_com -c cdrecord; then + if check_com -c wodim; then + cdrecord() { + cat <@']="set MARK" - help_zle_keybindings['xj']="vi-join lines" - help_zle_keybindings['xb']="jump to matching brace" - help_zle_keybindings['xu']="undo" - help_zle_keybindings['_']="undo" - help_zle_keybindings['xf']="find in cmdline" - help_zle_keybindings['a']="goto beginning of line" - help_zle_keybindings['e']="goto end of line" - help_zle_keybindings['t']="transpose charaters" - help_zle_keybindings['t']="transpose words" - help_zle_keybindings['s']="spellcheck word" - help_zle_keybindings['k']="backward kill buffer" - help_zle_keybindings['u']="forward kill buffer" - help_zle_keybindings['y']="insert previously killed word/string" - help_zle_keybindings["'"]="quote line" - help_zle_keybindings['"']="quote from mark to cursor" - help_zle_keybindings['']="repeat next cmd/char times (-10a -> -10 times 'a')" - help_zle_keybindings['u']="make next word Uppercase" - help_zle_keybindings['l']="make next word lowercase" - help_zle_keybindings['xd']="preview expansion under cursor" - help_zle_keybindings['q']="push current CL into background, freeing it. Restore on next CL" - help_zle_keybindings['.']="insert (and interate through) last word from prev CLs" - help_zle_keybindings[',']="complete word from newer history (consecutive hits)" - help_zle_keybindings['m']="repeat last typed word on current CL" - help_zle_keybindings['v']="insert next keypress symbol literally (e.g. for bindkey)" - help_zle_keybindings['!!:n*']="insert last n arguments of last command" - help_zle_keybindings['!!:n-']="insert arguments n..N-2 of last command (e.g. mv s s d)" - help_zle_keybindings['h']="show help/manpage for current command" - - #init global variables - unset help_zle_lines help_zle_sln - typeset -g -a help_zle_lines - typeset -g help_zle_sln=1 - - local k v - local lastkeybind_desc contents #last description starting with #k# that we found - local num_lines_elapsed=0 #number of lines between last description and keybinding - #search config files in the order they a called (and thus the order in which they overwrite keybindings) - for f in $HELPZLE_KEYBINDING_FILES; do - [[ -r "$f" ]] || continue #not readable ? skip it - contents="$(<$f)" - for cline in "${(f)contents}"; do - #zsh pattern: matches lines like: #k# .............. - if [[ "$cline" == (#s)[[:space:]]#\#k\#[[:space:]]##(#b)(*)[[:space:]]#(#e) ]]; then - lastkeybind_desc="$match[*]" - num_lines_elapsed=0 - #zsh pattern: matches lines that set a keybinding using bindkey or compdef -k - # ignores lines that are commentend out - # grabs first in '' or "" enclosed string with length between 1 and 6 characters - elif [[ "$cline" == [^#]#(bindkey|compdef -k)[[:space:]](*)(#b)(\"((?)(#c1,6))\"|\'((?)(#c1,6))\')(#B)(*) ]]; then - #description prevously found ? description not more than 2 lines away ? keybinding not empty ? - if [[ -n $lastkeybind_desc && $num_lines_elapsed -lt 2 && -n $match[1] ]]; then - #substitute keybinding string with something readable - k=${${${${${${${match[1]/\\e\^h/}/\\e\^\?/}/\\e\[5~/}/\\e\[6~/}//(\\e|\^\[)/}//\^/}/3~/} - #put keybinding in assoc array, possibly overwriting defaults or stuff found in earlier files - #Note that we are extracting the keybinding-string including the quotes (see Note at beginning) - help_zle_keybindings[${k}]=$lastkeybind_desc - fi - lastkeybind_desc="" - else - ((num_lines_elapsed++)) - fi - done - done - unset contents - #calculate length of keybinding column - local kstrlen=0 - for k (${(k)help_zle_keybindings[@]}) ((kstrlen < ${#k})) && kstrlen=${#k} - #convert the assoc array into preformated lines, which we are able to sort - for k v in ${(kv)help_zle_keybindings[@]}; do - #pad keybinding-string to kstrlen chars and remove outermost characters (i.e. the quotes) - help_zle_lines+=("${(r:kstrlen:)k[2,-2]}${v}") - done - #sort lines alphabetically - help_zle_lines=("${(i)help_zle_lines[@]}") - [[ -d ${HELP_ZLE_CACHE_FILE:h} ]] || mkdir -p "${HELP_ZLE_CACHE_FILE:h}" - echo "help_zle_lines=(${(q)help_zle_lines[@]})" >| $HELP_ZLE_CACHE_FILE - zcompile $HELP_ZLE_CACHE_FILE -} -typeset -g help_zle_sln -typeset -g -a help_zle_lines - -# Provides (partially autogenerated) help on keybindings and the zsh line editor -help-zle() -{ - emulate -L zsh - unsetopt ksharrays #indexing starts at 1 - #help lines already generated ? no ? then do it - [[ ${+functions[help_zle_parse_keybindings]} -eq 1 ]] && {help_zle_parse_keybindings && unfunction help_zle_parse_keybindings} - #already displayed all lines ? go back to the start - [[ $help_zle_sln -gt ${#help_zle_lines} ]] && help_zle_sln=1 - local sln=$help_zle_sln - #note that help_zle_sln is a global var, meaning we remember the last page we viewed - help_zle_sln=$((help_zle_sln + HELP_LINES_PER_PAGE)) - zle -M "${(F)help_zle_lines[sln,help_zle_sln-1]}" -} -#k# display help for keybindings and ZLE -zle -N help-zle && bindkey '^xz' help-zle # note: cycle pages with consecutive use of '^xz' - # grep for running process, like: 'any vim' any() { emulate -L zsh @@ -2689,42 +2770,6 @@ cdt() { builtin cd "$t" } -#f5# Create directory under cursor or the selected area -inplaceMkDirs() { - # Press ctrl-xM to create the directory under the cursor or the selected area. - # To select an area press ctrl-@ or ctrl-space and use the cursor. - # Use case: you type "mv abc ~/testa/testb/testc/" and remember that the - # directory does not exist yet -> press ctrl-XM and problem solved - local PATHTOMKDIR - if ((REGION_ACTIVE==1)); then - local F=$MARK T=$CURSOR - if [[ $F -gt $T ]]; then - F=${CURSOR} - T=${MARK} - fi - # get marked area from buffer and eliminate whitespace - PATHTOMKDIR=${BUFFER[F+1,T]%%[[:space:]]##} - PATHTOMKDIR=${PATHTOMKDIR##[[:space:]]##} - else - local bufwords iword - bufwords=(${(z)LBUFFER}) - iword=${#bufwords} - bufwords=(${(z)BUFFER}) - PATHTOMKDIR="${(Q)bufwords[iword]}" - fi - [[ -z "${PATHTOMKDIR}" ]] && return 1 - PATHTOMKDIR=${~PATHTOMKDIR} - if [[ -e "${PATHTOMKDIR}" ]]; then - zle -M " path already exists, doing nothing" - else - zle -M "$(mkdir -p -v "${PATHTOMKDIR}")" - zle end-of-line - fi -} - -#k# mkdir -p from string under cursor or marked area -zle -N inplaceMkDirs && bindkey '^xM' inplaceMkDirs - #f5# List files which have been accessed within the last {\it n} days, {\it n} defaults to 1 accessed() { emulate -L zsh