Repetidamente colar / colocar um bloco vertical no vim

1

No vim, quando eu tenho um bloco vertical selecionado (como uma única coluna de texto), eu gostaria de ser capaz de colocar repetidamente (colar) o que quer que esteja no registro atual. Por exemplo, se eu tivesse algo como:

username0 password0 personal_info0
username1 password1 personal_info1
...
username9 password9 personal_info9

e seleciono a coluna de texto entre o nome de usuário. e senha. (ou seja, a coluna de espaços entre os dois), gostaria de poder colocar (colar) lá. Isso funciona bem em um sentido: eu posso colocar algo, mas se a seleção for maior que o registrador, o resto da seleção é apenas substituído por nada. Em vez disso, gostaria que fosse feito algo como repetir o registro na seleção. Existe alguma maneira de fazer isso com um regex?

    
por G Gordon Worley III 23.02.2010 / 20:30

1 resposta

3

Se a nova coluna tiver o mesmo valor em cada linha (ou seja, seu yank inicial estava em uma única linha), provavelmente será mais fácil bloquear visualmente o espaço entre a coluna username e password e digitar A (ou I ) para iniciar o acréscimo (inserção). Quando você retornar ao modo normal ( Esc ), o Vim também anexará o texto ao restante da seleção original.

Se você realmente precisa fazer um padrão de repetição, então você poderia usar uma função e mapeamento como este:

:function! PutRegFilledToRange() range
:  let l:fill = ''
:  let l:lines = getreg()
:  let l:lineStart = 0
:  let l:linesLen = strlen(l:lines)
:  let l:lineIndex = 0
:  let l:linesNeeded = a:lastline - a:firstline + 1
:  while l:lineIndex < l:linesNeeded 
:    let l:lineEnd = matchend(l:lines, "\n\|$", l:lineStart)
:    let l:line = strpart(l:lines, l:lineStart, l:lineEnd - l:lineStart)
:    if l:lines[l:lineEnd - 1] != "\n" 
:      let l:line = l:line . "\n"
:    endif
:    let l:fill = l:fill . l:line
:    let l:lineStart = l:lineEnd < l:linesLen ? l:lineEnd : 0
:    let l:lineIndex = l:lineIndex + 1
:  endwhile
:
:  normal gv
:  " This probably does not make much sense in any mode
:  " other than block modes, but we will try to cope.
:  if mode() == "\<C-V>" || mode() == "\<C-S>"
:    let l:newMode = "\<C-V>"
:  elseif mode() == 'v' || mode() == 's'
:    let l:newMode = 'v'
:  else
:    let l:newMode = 'V'
:  endif
:  let l:origReg = getreg('')
:  let l:origRegType = getregtype('')
:  try
:    call setreg('', l:fill, l:newMode)
:    execute 'normal ' . v:count1 . 'p'
:  finally
:    call setreg('', l:origReg, l:origRegType)
:  endtry
:endfunction
:vmap _f :call PutRegFilledToRange()<CR>

Coloque no seu arquivo .vimrc ou algum outro arquivo (e execute: source / path / to / file). Ou cole-o diretamente em uma sessão do Vim.

Para usá-lo:

  • C-V{motion}y : bloqueia visualmente a seleção e arranca o texto que você deseja usar para colocar repetidamente
  • {motion}C-V{motion} : selecione o bloco que você deseja substituir
  • _f : preenche o bloco selecionado com linhas repetidas do registro atual ( "a_f preenche o bloco com linhas do registrador a)
por 24.02.2010 / 02:40