I want vim to ignore whitespace copy

Default cut x will work same but
When i cut one whitespace character or a visual block of whitespaces with x, vim register won't copy

like this thread, Vim Clever Whitespace Deletion
d or dd will cut but won't copy whitespace if it's only whitespaces
otherwise it will copy as usual
won't harm whitespaces like this situation: abc<space><space>

I only could do the first one
with this, vim won't copy single whitespaces when cut with x

function! Smart_Delete_x()
    let temp = getreg('"', 1)
    execute 'normal!' 'x'
    if matchstr(@", '\_s*') == @"    " if just whitespace
        call setreg('"', temp)
        call setreg('*', temp)
        call setreg('+', temp)
        call setreg('0', temp)
nnoremap <silent> x :call Smart_Delete_x()<CR>

I couldn't do the visual block one.
vim won't copy blocks of whitespaces when cut with x

but if the blocks has single or multiple character like


only then vim will copy

  • what if i delete blocks of whitespaces with x ? it still copies that. And i don't want this to happen.
    – Mega Bang
    Jul 18 at 9:01
  • That whole answer is about overriding dd and v_d. You'll need a new mapping and possibly a new function or modification of the existing function to override v_x. I highly recommend you read the book or parts thereof that statox recommended in another of your questions (Learning Vimscript the Hard Way.) It'll take some effort but you'll learn so much useful stuff.
    – B Layer
    Jul 18 at 9:24
  • @MegaBang people here write code all the time—when we do it for people other than ourselves, it is an act of kindness and helping. It’s not free (in the sense that it has a cost for the writer), and that cost may not be worth paying to some when, with a little effort, the asker could port a very similar thing to their situation. Asking nicely and clearly is a good way to incline people towards being more helpful, however. I think the only relevant comments left here are a clarification and a recommendation to use a visual mapping. I’ll leave those and delete the rest.
    – D. Ben Knoble
    Jul 18 at 11:57
  • No one seems to write 5/6 lines of code nowadays That's part of stackexchange culture. Most people here have an unfavorable view of questions that could be interpreted as "please write this code for me". Conversely, the more effort the poster appears to have put into solving a problem themselves the more likely they are to receive help. vi.stackexchange.com/help/no-one-answers
    – B Layer
    Jul 18 at 12:00
  • 1
    @BLayer thank you for putting that more succinctly, your explanation seems correct to me.
    – D. Ben Knoble
    Jul 18 at 12:01

To make something work in visual mode, you need a visual-mode mapping (usually :x[nore]map). In this case, we need to do these steps

  1. Save the register
  2. Restore the selection and do the cut (x or d or whatever)
  3. Restore the register if whitespace

This is reminiscent of your original function, so let's modify it to take a visual arg: if truthy, do gv before cut. (Prior to this modification, I would have just written normal! x without the :execute cruft. But now we're adding some conditional command interpolation, so we can get a bit fancier.)

Note that I'm also using the more correct getreginfo().

function! Smart_Delete_x(visual)
    let saved = getreginfo('"')
    execute printf('normal! %sx', a:visual ? 'gv' : '')
    if @" =~# '^\_s*$'
        call setreg('"', saved)
nnoremap <silent> x :call Smart_Delete_x(v:false)<CR>
xnoremap x :<C-u>call Smart_Delete_x(v:true)<CR>

I removed restoring the clipboard and yank register. The yank register ("0) is for yanks. The clipboard should only be synchronized that way depending on 'clipboard', and I think setreg() with getreginfo() may handle some of those cases?


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.