Можно ли сохранить вырванную историю в пронумерованном регистре? (без плагина) - PullRequest
0 голосов
/ 30 октября 2019

В Vim, насколько я знаю, пронумерованный регистр сохраняет только удаленную историю.

Можно ли сделать так, чтобы это спасло и выдернутого? (без плагина)

Спасибо

1 Ответ

2 голосов
/ 30 октября 2019

Можно ли сделать так, чтобы он сохранял также и выдернутый?

На самом деле регистры 2-9 редко бывают полезны, так как мы можем сохранить все важные части в "букве""регистрируется по мере необходимости. И все равно есть «отменить» что-либо потерянное.

без плагина

Плагин - всего лишь кусок кода. Вы можете обойтись без плагина, но вы не можете обойтись без кода.

" Shift previously yanked text through the numbered registers 0, 2-9
" note:
"   the register 1 is reserved for deletion
"   there's no "small yank" register
"   can break :h redo-register
"   $-blocks are broken
nnoremap <silent>y :set opfunc=YankeeDoodle<CR>g@
nnoremap <silent>Y :k] \| k[ \| call YankeeDoodle("line")<CR>
nnoremap <silent>yy :k] \| k[ \| call YankeeDoodle("line")<CR>
vnoremap <silent>y :<C-U>call YankeeDoodle(visualmode())<CR>
vnoremap <silent>Y :<C-U>call YankeeDoodle("V")<CR>

let s:ydict = #{char: "v", line: "V", block: "\<C-V>"}

function! YankeeDoodle(type)
    if has_key(s:ydict, a:type)
        let l:type = s:ydict[a:type]
        let l:mark = ['[', ']']
    else
        let l:type = a:type
        let l:mark = ['<', '>']
    endif
    if v:register is '"'
        for l:regno in range(8, 2, -1)
            call setreg(l:regno + 1, getreg(l:regno), getregtype(l:regno))
        endfor
        call setreg(2, getreg(0), getregtype(0))
    endif
    " go to start mark; register override; yank; forced-motion; move to end mark
    call execute(printf('normal! g`%s"%sy%sg`%s', l:mark[0], v:register, l:type, l:mark[1]), '')
endfunction

UPD. Как предполагает @PeterRincker, мы можем вместо этого использовать TextYankPost. Следующий код должен быть более надежным, но все же не на 100%, так как мы должны отслеживать регистр 0 вручную (TextYankPre будет намного лучше здесь, но, увы, у нас его нет).

" 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)]
    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 == '"')
        for l:regno in range(8, 2, -1)
            call setreg(l:regno + 1, getreg(l:regno), getregtype(l:regno))
        endfor
        call setreg(2, s:regzero[0], s:regzero[1])
        let s:regzero = [a:event.regcontents, a:event.regtype]
    elseif a:event.regname == '0'
        let s:regzero = [a:event.regcontents, a:event.regtype]
    endif
endfunction
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...