# Edit the command line using your usual editor. # Binding this to '!' in the vi command mode map, # autoload -Uz edit-command-line # zle -N edit-command-line # bindkey -M vicmd '!' edit-command-line # will give ksh-like behaviour for that key, # except that it will handle multi-line buffers properly. emulate -L zsh local left right prebuffer buffer=$BUFFER lbuffer=$LBUFFER local TMPSUFFIX=.zsh # set up parameters depending on which context we are called from, # see below comment for more details if (( REGION_ACTIVE == 1 )); then if (( CURSOR < MARK )); then left=$CURSOR right=$MARK lbuffer= else left=$MARK right=$CURSOR lbuffer[right-left,-1]= fi (( left++ )) buffer=$BUFFER[left,right] elif (( REGION_ACTIVE == 2 )); then local mark_left mark_right offset_right if (( CURSOR < MARK )); then mark_left=$CURSOR mark_right=$MARK else mark_left=$MARK mark_right=$CURSOR fi left=${(SB)${BUFFER[1,mark_left]}%$'\n'} (( left != 1 )) && (( left++ )) offset_right=${(SB)${BUFFER[mark_right+1,-1]}#$'\n'} if (( offset_right == 1 )); then right=$#BUFFER else (( right = mark_right + offset_right - 1 )) fi lbuffer=${lbuffer[left,CURSOR]} buffer=$BUFFER[left,right] elif (( ! ZLE_RECURSIVE )); then prebuffer=$PREBUFFER fi () { exec CURSOR )); then (( MARK += $#BUFFER - prelen )) else (( CURSOR += $#BUFFER - prelen )) fi elif [[ $CONTEXT != cont ]] || (( ZLE_RECURSIVE )); then BUFFER="$(<$1)" else print -Rz - "$(<$1)" zle send-break fi } =(<<<"$prebuffer$buffer")