qed
qed

Reputation: 23134

A function to apply to selection in vim

I am writing a function for deleting selected text (in a special way) when vim is running in a ssh session:

python << EOF
def delSelection():
    buf = vim.current.buffer
    (lnum1, col1) = buf.mark('<')
    (lnum2, col2) = buf.mark('>')

    # get selected text
    # lines = vim.eval('getline({}, {})'.format(lnum1, lnum2))
    # lines[0] = lines[0][col1:]
    # lines[-1] = lines[-1][:col2+1]
    # selected =  "\n".join(lines) + "\n"
    # passStrNc(selected)

    # delete selected text
    lnum1 -= 1
    lnum2 -= 1
    firstSeletedLine = buf[lnum1]
    firstSeletedLineNew = buf[lnum1][:col1]
    lastSelectedLine = buf[lnum2]
    lastSelectedLineNew = buf[lnum2][(col2 + 1):]
    newBuf = ["=" for i in range(lnum2 - lnum1 + 1)]
    newBuf[0] = firstSeletedLineNew
    newBuf[-1] = lastSelectedLineNew
    print(len(newBuf))
    print(len(buf[lnum1:(lnum2 + 1)]))
    buf[lnum1:(lnum2 + 1)] = newBuf

EOF


function! DelSelection()
python << EOF
delSelection()
EOF
endfunction

python << EOF
import os
sshTty = os.getenv("SSH_TTY")
if sshTty:
    cmd6 = "vnoremap d :call DelSelection()<cr>"
    vim.command(cmd6)
EOF

Apparently vim is calling the function on every line selected, which defeats the whole purpose of the function. How should I do this properly?

Upvotes: 0

Views: 187

Answers (2)

Ingo Karkat
Ingo Karkat

Reputation: 172688

That's because the : automatically inserts the '<,'> range when issued in visual mode. The canonical way to clear that is by prepending <C-u> to the mapping:

cmd6 = "vnoremap d :<C-u>call DelSelection()<cr>"

Alternatively, you can also append the range keyword to the :function definition, cp. :help a:firstline.

Upvotes: 1

qed
qed

Reputation: 23134

ok, I got it. I just need to add an Esc key before calling the function:

python << EOF
import os
sshTty = os.getenv("SSH_TTY")
if sshTty:
    cmd6 = "vnoremap d <esc>:call DelSelection()<cr>"
    vim.command(cmd6)
EOF

Upvotes: 0

Related Questions