Posso fazer com que o Vim também salve “pequenas exclusões” no registro "1?

14

Eu recentemente removi o plugin YankRing da minha configuração, em parte porque estava causando alguns problemas com macros, mas principalmente porque decidi que seria melhor me treinar para usar os registros do Vim - em particular, a maneira como o texto excluído é armazenado inicialmente no registro "1e, em seguida, passou por "2, "3etc., à medida que outras exclusões são feitas, é muito útil.

No entanto, quando uma exclusão / alteração remove menos de uma linha de texto, ela é armazenada no "-pequeno registro de exclusão (com algumas exceções para determinados comandos de movimento). Se pequenas exclusões subseqüentes forem feitas, esse pedaço de texto será perdido.

É possível fazer com que o Vim armazene todas as exclusões no registro "1?

nnoremap d "1d quase funciona, mas você acaba com o texto nos registros "1 e "2 .

Não me importo se a funcionalidade do pequeno registro de exclusão é afetada ou não. Sugerir que eu mude meu comportamento para salvar pequenas exclusões em um registro nomeado definitivamente não seria uma resposta útil - é o que estou fazendo atualmente.

Rico
fonte

Respostas:

10

Isso costumava funcionar nas versões mais antigas do Vim 7.3 quando você :set clipboard=unnamed(consulte esta discussão do Reddit , como resultado de um bug, que relatei aqui .

Esse tópico contém um patch de Aryeh Leib Taurog, que apresenta uma 'regone'opção. Isso foi incluído na lista de tarefas (excessivamente longa), mas é improvável que seja incorporado em breve. Portanto, atualmente você só tem a opção de fazer o downgrade para um Vim desatualizado ou criar o Vim você mesmo com esse patch (e empurre para adoção na lista de discussão vim_dev ).

Ingo Karkat
fonte
1
Interessante! (Especialmente sua idéia sobre o limite.) Obrigado pela informação. Por enquanto, vou adiar o voto positivo / aceitar, na tentativa de incentivar alguém a criar algum VimScript louco para fazer isso nesse ínterim.
Rich
5

Eu tenho uma solução de prova de conceito que funciona para o dcomando com movimentos e no modo visual. Ainda não é uma solução totalmente robusta (por exemplo, d[count]dnão funciona e nem funciona [count]D), mas abrange quase todos os meus casos de uso reais.

Funciona configurando uma função de operador do cliente que:

  1. armazena o conteúdo dos registros 1–8 em um dicionário,
  2. executa a exclusão no registro 1,
  3. define os registros 2 a 9 para o conteúdo salvo anteriormente dos registros 1 a 8.

Veja :help map-operatoruma explicação de como as funções do operador funcionam.

function! ShiftingDeleteOperator(type)
  let reg_dict = {}
  for k in range(1, 8)
    execute printf("let reg_dict[%d]=getreg('%d', 1)", k, k)
  endfor

  if a:type ==# 'v'
    execute 'normal! `<v`>d'
  elseif a:type ==# 'V'
    execute 'normal! `<V`>d'
  elseif a:type ==# "\<C-V>"
    execute "normal! `<\<C-V>`>d"
  elseif a:type ==# 'char'
    execute 'normal! `[v`]d'
  elseif a:type ==# 'line'
    execute "normal! '[V']d"
  else
    return
  endif

  let deleted = getreg('"', 1)
  call setreg(1, deleted)

  for [k, v] in items(reg_dict)
    execute printf("call setreg(%d, v)", k + 1)
  endfor
endfunction

" Call the function for d{motion} via operatorfunc
nnoremap <silent> d :set operatorfunc=ShiftingDeleteOperator<CR>g@
" Call the function when d or x are hit in visual mode
vnoremap d :<C-U>call ShiftingDeleteOperator(visualmode())<CR>
vnoremap x :<C-U>call ShiftingDeleteOperator(visualmode())<CR>
" Use the d{motion} as defined above to add limited support for `D` command
nmap D d$
" Use the standard dd command
nnoremap dd dd 
Rico
fonte
Desculpe por comentar uma resposta antiga. Eu adotei esta solução para ye, cmas para o cmeu nvim não entra no modo de inserção após a ação ... Atualmente eu preciso execute le o startinsertque não é uma correção adequada (como c$colocaria o cursor na posição errada). Alguma ideia?
ensolarado Pun