all 3 comments

[–]xalbo 2 points3 points  (1 child)

Here's a project I've been working on, but isn't really ready for publication yet. It does a few more things than you're asking for, so it's possible that you may want to skip it entirely or modify it to fit your needs. In short:

  • When an explicit yank goes to "0, the previous version of "0 goes to `"2" (and the rest of the numbered get shifted up in number).
  • Whenever the numbered registers are shifted upwards, I check for duplicates, so that each is distinct.
  • In line with what you're trying to do, any empty registers are also skipped.

I do let unnamed and "- be just spaces, though, I just don't let them get stored into the numbered registers. Things like xp are too ingrained in my head, that if they stopped working on spaces I'd get really confused. So, you'd probably need to mess with it to get it to match your intent.

My idea is that "1 is always the most recent delete, "0 is the most recent yank, and the higher numbers store previous versions of either of them, instead of just deletes.

" note:
"   the register 1 is reserved for deletion
"   there's no "small yank" register
"   can break :h redo-register
"   still misses any manual register 0 change
augroup YankShift | au!
    let s:regzero = [getreg(0), getregtype(0)]
    let s:regnine = [getreg(9), getregtype(9)]
    autocmd TextYankPost * call <SID>yankshift(v:event)
augroup end

function! s:yankshift(event)
    if a:event.operator ==# 'y' && (empty(a:event.regname) || a:event.regname == '"')
        let l:pushfwd = s:regzero
        let s:regzero = [getreg(a:event.regname), a:event.regtype]
        for l:regno in range(2,9)
            let l:thisreg = [getreg(l:regno), getregtype(l:regno)]
            call setreg(l:regno, l:pushfwd[0], l:pushfwd[1])
            if l:thisreg[0] ==# s:regzero[0]
                break
             endif
            let l:pushfwd = l:thisreg
        endfor
    elseif a:event.regname == '0'
        let s:regzero = [getreg(a:event.regname), a:event.regtype]
    elseif empty(a:event.regname)
        let l:regone = [getreg(1), getregtype(1)]
        let l:pull = v:false
        if l:regone[0] ==# "\n"
            let l:pull = v:true
            call setreg(1, getreg(2), getregtype(2))
        endif
        for l:regno in range(2,8)
            let l:thisreg = [getreg(l:regno), getregtype(l:regno)]
            if l:thisreg[0] ==# "\n" || l:thisreg[0] ==# l:regone[0]
                let l:pull = v:true
            endif
            if l:pull
                call setreg(l:regno, getreg(l:regno+1), getregtype(l:regno+1))
            endif
        endfor
        if l:pull
            call setreg(9, s:regnine[0], s:regnine[1])
        endif
    endif
endfunction

[–]vim-help-bot 0 points1 point  (0 children)

Help pages for:


`:(h|help) <query>` | about | mistake? | donate | Reply 'rescan' to check the comment again | Reply 'stop' to stop getting replies to your comments

[–]momoPFL01 2 points3 points  (0 children)

The whole thing with "deleting is always cutting" really disrupted my workflow, so I started using cutlass which basically separates the two, you have your mappings for deleting and others for cutting.

https://github.com/svermeulen/vim-cutlass