Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: CTRL-O in vi mode



Reply to message «CTRL-O in vi mode», 
sent 23:32:05 16 November 2010, Tuesday
by Bernd Strohhaecker:

> I'm using vi mode. Is it possible in viins mode to realize Vim's CTRL-O
> command, e.g. execute one vicmd command and then return to viins mode?
Of course, it is. I do use emacs mode but have lots of custom mappings and <C-o>
is one of them:

    function _-vi-digit-arg
    {
        emulate -LR zsh
        [[ -z "${NUMERIC}" ]] && NUMERIC=0
        [[ -z "$1" ]] && num=0 || num=$(( $1 ))
        shift
        (( NUMERIC=NUMERIC*10+num )) && $@
    }
    function _-repeat-for-key
    {
        emulate -LR zsh
        local key
        read -k key
        local -i OLDLLEN=${#LBUFFER} OLDRLEN=${#RBUFFER}
        local OLDLBUFFER="$LBUFFER" OLDRBUFFER="$RBUFFER"
        (( NUMERIC )) || NUMERIC=1
        if ! [[ -z $2 ]] ; then
            eval $2
            (( NUMERIC-- ))
        fi
        while (( NUMERIC )) ; do
            eval $1
            (( NUMERIC-- ))
        done
        local -i LLEN=${#LBUFFER} RLEN=${#RBUFFER}
        if (( LLEN<OLDLLEN || RLEN<OLDRLEN )) ; then
            local KILLTEXT="${OLDLBUFFER[LLEN+1,-1]}${OLDRBUFFER[1,OLDRLEN-RLEN]}"
            zle copy-region-as-kill "$KILLTEXT"
        fi
    }
    function _-vi-delete
    {
        emulate -LR zsh
        local key
        read -k key
        key=$(( #key ))
        if   (( key==##t )) ; then
            _-repeat-for-key 'RBUFFER=${(S)RBUFFER/#$key*$key/$key}' \
                             'RBUFFER=${(S)RBUFFER/#*$key/$key}'
        elif (( key==##T )) ; then
            _-repeat-for-key 'LBUFFER=${(S)LBUFFER/%$key*$key/$key}' \
                             'LBUFFER=${(S)LBUFFER/%$key*/$key}'
        elif (( key==##f )) ; then _-repeat-for-key 'RBUFFER=${RBUFFER#*$key}'
        elif (( key==##F )) ; then _-repeat-for-key 'LBUFFER=${LBUFFER%$key*}'
        elif (( key==##d )) ; then zle kill-whole-line
        elif (( key==##$ )) ; then zle kill-line
        elif (( key==##\^ )); then zle backward-kill-line
        elif (( key==##0 )) && [[ -z $NUMERIC ]] ;
                              then zle backward-kill-line
        elif (( key>=##0 && key<=##9 ))
                              then _-vi-digit-arg $(( key - ##0 )) _-vi-delete
        fi
    }
    function _-vi-ctrl-o
    {
        emulate -LR zsh
        local keystr
        read -k keystr
        local -r keystr
        local -ri key=$(( #keystr ))
          if (( key==##A )) ; then zle end-of-line
        elif (( key==##$ )) ; then zle end-of-line
        elif (( key==##I )) ; then zle vi-first-non-blank
        elif (( key==##d )) ; then _-vi-delete
        elif (( key==##0 )) && [[ -z $NUMERIC ]] ;
                              then zle beginning-of-line
        elif (( key>=##0 && key<=##9 ))
                              then _-vi-digit-arg $(( key - ##0 )) _-vi-ctrl-o
        #elif (( key==##s )) ; then zle sedsubstitute
        #elif (( key==##= )) ; then zle tailfor
        else
            zle ${${(z)$(bindkey -M vicmd $keystr)}[2]}
        fi
    }

    zle -N vi-ctrl-o                         _-vi-ctrl-o
    bindkey  -N evi    emacs
    bindkey  -A evi     main
    bindkey -rM evi    "\C-o"
    bindkey  -M evi    "\C-o"         "vi-ctrl-o"

Attachment: signature.asc
Description: This is a digitally signed message part.



Messages sorted by: Reverse Date, Date, Thread, Author