Como o texto pode ser movido de um registro para um número arbitrário de registros?


10

Existe uma maneira de canalizar o texto de um registro para outro registro ou conjunto de registros? Por exemplo, vá "qpara registradores "1através de "5.

Muitas vezes, desejo criar versões ligeiramente diferentes da mesma macro, portanto, é útil poder copiar uma macro 'modelo' para vários registros e depois modificar cada um deles no lugar.

Para dar um exemplo prático, aqui está o problema que levou essa pergunta para mim.

Preciso transformar a seguinte linha de uma linguagem de descrição de hardware em muitos blocos repetidos,

RAM64(in=in, load=load0, address=address[0..5], out=out1);

para

RAM64(in=in, load=load1, address=address[0..5], out=out2);
RAM64(in=in, load=load2, address=address[0..5], out=out3);
RAM64(in=in, load=load3, address=address[0..5], out=out4);
RAM64(in=in, load=load4, address=address[0..5], out=out5);

Eu tenho uma macro que executa isso, usando a função de incremento, yypW^At)^Aque eu armazenei no registro "a.

Às vezes, preciso que o padrão de incremento seja ligeiramente diferente, como

RAM512(in=in, load=load1, address=address[0..8], out=out2);
RAM512(in=in, load=load2, address=address[0..8], out=out4);
RAM512(in=in, load=load3, address=address[0..8], out=out6);
RAM512(in=in, load=load4, address=address[0..8], out=out8);

onde "bestaria a macro no registro yypW^At)^A^A.

Quero um registro para fazer isso, mas para cada incremento de 1 a 5. O registro "apode (de alguma forma) ser copiado nos registros b a e. Em seguida, colava cada registro no buffer, fazia a modificação necessária (adicionava mais termos, alterava o caractere que segue o tmovimento etc.) e puxava a expressão modificada de volta para o registro. Idealmente, esse último passo pode ser incluído no (s) comando (s) para copiar os registradores

Isso evita que eu repita todos os caracteres na macro que NÃO exigem alteração. Para meu exemplo, pode ser trivial, mas posso prever momentos em que pode ser muito útil fazer o que estou pedindo.


5
Como um aparte, eu não recomendaria o uso dos registros numerados. Os únicos registros "seguros" são os registros alfabéticos. Todos os outros registradores são definidos automaticamente pelo Vim.
21415 jamessan

Respostas:


7

Macros são apenas texto.

Abra um novo buffer vazio e coloque sua macro lá. Você pode duplicar as linhas, alterar uma coisa aqui e outra em outro lugar, depois puxar uma linha e usá-la imediatamente @".

Não há necessidade de poluir seus registros, especialmente os registros numéricos que servem a um propósito totalmente diferente.

- editar -

Sua pergunta é mais fácil de entender agora que você adicionou alguma explicação.

Como se vê, você só precisa alterar sua gravação inicial para atingir seu objetivo, sem brincar com os registradores como se fossem variáveis:

:let i = 1                     " define variable i
qa                             " start recording in register a
yy                             " yank the line
p                              " paste it
W                              " move to next WORD
<C-v><C-a>                     " increment number
t)                             " jump to the other number to increment
:norm <C-r>=i<CR><C-v><C-a>    " increment the number by i
q                              " stop recording

Para criar 5 cópias da linha atual com o último número incrementado por 2:

:let i = 2|norm 5@a

ou 12 cópias, com o último número incrementado em 23:

:let i = 23|norm 12@a

Concordou com os registros numéricos - mas e se você quiser usar isso em um comando e precisar de registros que iniciem o mesmo, mas que se tornem diferentes?
wchargin

@WChargin, por favor, explique.
romainl

Como em, talvez, eu quero fazer algo com cópias giradas de um texto, por isso, se abcdeestá em @q, então eu quero @x="bcdea", @y="abcde"e @z="eabcd". Eu poderia começar por deixar @x, @ye @ztudo igual @qe, em seguida, modificá-los conforme necessário. Obviamente, acabei de inventar isso, mas parece que pode haver alguns casos em que algo semelhante pode ser útil.
Wchargin # 03/02

2
@Kit, estou um pouco preocupado com a falta de exemplo prático em sua pergunta, que imediatamente faz com que cheire a XY. Estou quase certo de que você está usando incorretamente os registros, então eu adoraria ler uma explicação do que você está tentando fazer.
precisa saber é o seguinte

11
@Kit, esse é um dos muitos problemas com as questões XY. A resposta mais votada é uma resposta direta de alta qualidade à sua pergunta, mas, no final das contas, inútil no contexto do seu problema real, enquanto minha resposta menos votada é uma solução real para o seu problema subjacente. Ambas as respostas estão corretas, mas respondem a perguntas diferentes, o que dificulta sua decisão. Se fosse eu, aceitaria a resposta que trata do meu principal problema ... mas isso sou apenas eu.
Romainl

6

Usando getregesetreg

Para copiar de qpara registros 1- 5:

let src=getreg('q', 1)
for i in range(1, 5)
    call setreg(i, src)
endfor

Para copiar para uma lista mais geral:

let src=getreg('q', 1)
for i in ['a', 'c', 'e']
    call setreg(i, src)
endfor

Usando execute

Para copiar de qpara registros 1- 5:

for i in range(1, 5)
   execute 'let @' . i . '=@a'
endfor

Para copiar para uma lista mais geral:

for i in ['a', 'c', 'e']
    execute 'let @' . i . '=@a'
endfor

Explicação. O comando letpode ser usado como let @x=@y, que copia o registro ypara registrar x. Basicamente, estamos apenas construindo esses comandos em um loop (alterando o valor xno formulário acima) e os executeingando.


11
Não há necessidade de usar :exeaqui. As funções getreg()e setreg()seriam mais limpas.
21415 jamessan

@jamessan Boa sugestão, obrigado - estou usando esses corretamente?
wchargin

Eu o editei para adicionar o segundo argumento opcional ao getreg (), pois ele retorna o conteúdo do registro em vez de uma possível avaliação dele.
jamessan

1

Para responder diretamente à pergunta, se você deseja copiar rápida e facilmente o conteúdo de um registro para outro, você pode colocar o seguinte em seu arquivo .vimrc. Você pode então executar <leader>rcabpara copiar o conteúdo do registro apara registrar b. Como exemplo, eu escolhi <leader>rca opção "registrar cópia"

function! s:CopyRegister()
    let sourceReg = nr2char(getchar())

    if sourceReg !~# '\v^[a-z0-9]'
        echo "Invalid register given: " . sourceReg
        return
    endif

    let destinationReg = nr2char(getchar())

    if destinationReg !~# '\v^[a-z0-9]'
        echo "Invalid register given: " . destinationReg
        return
    endif

    call setreg(destinationReg, getreg(sourceReg, 1))
    echo "Replaced register '". destinationReg ."' with contents of register '". sourceReg ."'"
endfunction

" rc = register copy
nnoremap <leader>rc :call <sid>CopyRegister()<cr>

11
Eu recomendo getreg(sourceReg, 1).
21415 jamessan

Ah sim, é verdade. Fixo.
Steve Vermeulen
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.