I'm trying to write a mapping that will copy the text and automatically unwrap it at the same time. Here's what I got:

function! CopyUnwrapped(type, ...)
    if a:0
        normal! gv"ay
        normal! `[v`]"ay
    setlocal buftype=nofile bufhidden=hide noswapfile nobuflisted
    normal! "ap
    %normal! vipJ
    normal! ggvG$"+y

vnoremap <leader>y :call CopyUnwrapped(visualmode(), 1)<CR>
nnoremap <leader>y :set opfunc=CopyUnwrapped<CR>g@

It works almost perfectly… works fine in visual mode as far as I can tell. But when I try <leader>yip, for instance, the last line of the paragraph is cut off, I don't understand why. Any ideas?


If you look at example in documentation for g@, you can notice that your function is missing handling of a linewise selection. ip motion apparently acts as a linewise in this case and if you handle it as characterwise only first character of the last line is copied (because that's where `] is positioned; do vipv on a paragraph to see it for yourself).

Thus that if-statement should look like this:

if a:0
    normal! gv"ay
elseif a:type == 'line'
    normal! `[V`]"ay
    normal! `[v`]"ay

Notice that for linewise selection, V is used to select by lines (which quotes are used is irrelevant for this kind of selection).

| improve this answer | |
  • 2
    Ah, of course! Thank you. :) When I read the documentation I thought that was only necessary if you wanted to do something different when the selection is linewise, but I didn't care and I thought the `] mark would record the exact position. Anyway, now I get it, thanks. – dbmrq Oct 1 '16 at 19:06

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.