> > + left=${(SB)${BUFFER[1,mark_left]}%$'\n'} > > + (( left != 1 )) && (( left++ )) > > This I follow. If the (SB) is replaced with ... > > local nl=$'\n' > left=${${BUFFER[1,mark_left]}[(I)$nl]} Thank you, this is much better. > > > + offset_right=${(SB)${BUFFER[mark_right+1,-1]}#$'\n'} > > > This I'm not sure of -- why mark_right+1 ? In this direction that > seems to mean that if the mark is exactly on the newline, you're > extending to the following newline. Is that how it's meant to work? This is because CURSOR and MARK are 0-indexed, according to zshzle(1). And so a cursor at the first position in a line will have the same index as a newline of the previous line inside an array subscript. Unless I am missing something I would insist on the following. right=${${BUFFER[MARK+1,-1]}[(i)$nl]} (( right += MARK )) which also means we later on no longer need to immediately predecrement $right, since the matched index will be 1 lower. There is also the issue about supporting cursor position in emacs, since now $lbuffer is used to split the selected lines and figure out the cursor line and column. But in both the original code and in your patch improvement, $lbuffer will contain text from the beginning of $BUFFER regardless of where the visual selection actually starts. This works fine in vim since they only use byte offsets, but I would recommend changing it to the following in _both_ cases. lbuffer=$lbuffer[++left,-1] This leaves me with the attached suggestion (with the caveat that multiple empty trailing lines will be trimmed to one newline) Thank you a bunch for taking the time to help me, I understand this is not the most exciting feature :) Christoffer --- Functions/Zle/edit-command-line | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/Functions/Zle/edit-command-line b/Functions/Zle/edit-command-line index 5f7ea321f..d4b405eaf 100644 --- a/Functions/Zle/edit-command-line +++ b/Functions/Zle/edit-command-line @@ -11,15 +11,30 @@ 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 )); then +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++ )) + lbuffer=$lbuffer[++left,-1] + buffer=$BUFFER[left,++right] +elif (( REGION_ACTIVE == 2 )); then + local nl=$'\n' + if (( CURSOR < MARK )); then + left=${${BUFFER[1,CURSOR]}[(I)$nl]} + right=${${BUFFER[MARK+1,-1]}[(i)$nl]} + (( right += MARK )) + else + left=${${BUFFER[1,MARK]}[(I)$nl]} + right=${${BUFFER[CURSOR+1,-1]}[(i)$nl]} + (( right += CURSOR )) + fi + lbuffer=$lbuffer[++left,-1] + if [[ $BUFFER[right] = $nl ]]; then + # Keep the newline because "$(<$1)" below trims it + (( --right )) + fi buffer=$BUFFER[left,right] elif (( ! ZLE_RECURSIVE )); then prebuffer=$PREBUFFER -- 2.41.0