0

I have this following function

" copy yanked text to tmux pane
function! Send_to_tmux(count) range
    if (a:firstline == a:lastline)
        execute "normal! \"zyip"
    else
        execute "normal! \"zy"
    endif
    let text = @z
    let text = substitute(text, ';', '\\;', 'g')
    let text = substitute(text, '"', '\\"', 'g')
    let text = substitute(text, '\n', '" Enter "', 'g')
    let text = substitute(text, '!', '\\!', 'g')
    let text = substitute(text, '%', '\\"', 'g')
    let text = substitute(text, '#', '\\#', 'g')
    silent execute "!tmux send-keys -t " . a:count . " \"" . text . "\""
    silent execute "!tmux send-keys -t " . a:count . "Enter"
endfunction
nnoremap <leader>cc :<C-u>call Send_to_tmux(v:count1)<cr>
xnoremap <leader>cc :<C-u>call Send_to_tmux(v:count1)<cr>

Originally, I didn't use the range attribute in the function and mapped it like this

nnoremap <leader>cc "zyip:<C-u>call Send_to_tmux(v:count1)<cr>
xnoremap <leader>cc "zy:<C-u>call Send_to_tmux(v:count1)<cr>

But this didn't work with the count, that's why I put the if else check for checking if the function was called for visual selection mode.

It does the work, but seems counter intuitive. Is it alright? Is there any other way to call functions with count but do some yanking etc. before calling the function?

1

I've ran into this exact issue many times. The same problem comes up with v:reg as well. In general, there's two main solutions.

  1. Do what you did. Like you said, this isn't always the most convenient solution. Thankfully, there's...

  2. Use an <expr> mapping. In general, this means that your mapping is an expression that evaluates to a string, rather than some static string. This can be really useful when your mapping isn't identical every time you use it (for example, if the v:count1 varies). In your case, this would look like:

    nnoremap <expr> <leader>cc '"zyip:\<C-u>call Send_to_tmux('.v:count1.')\<cr>'
    xnoremap <expr> <leader>cc '"zy:\<C-u>call Send_to_tmux('.v:count1.')\<cr>'
    

Some general notes on this approach... Even though this is more convenient, building the string can be a bit of a pain. Especially if the mapping you want has weird characters, quotes or backslashes. Note that in vimscript, "\<C-u>" evaluates to the unprintable ^u (0x15, ctrl-u). But '\<C-u>' evaluates to the literal text \<C-u>. So you'll have to be careful about which quotes you use.

  • Are you sure youve got the quotes the right way ‘round? I thought double quotes allowed interpretation of <Key> sequences, not single quotes. Perhaps the backslash is affecting things? – D. Ben Knoble Feb 11 at 19:41
  • I think he is wrong, and the backslash is not affecting things. He is just mistaken, everyone gets confused about these things. I just looked it up. String-literal and strings. – klaus Feb 12 at 2:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.