¿Cómo se puede mover el texto de un registro a un número arbitrario de registros?

10

¿Hay alguna manera de 'canalizar' el texto de un registro a otro registro o conjunto de registros? Por ejemplo, pasar "qa registros a "1través "5.

A menudo deseo crear versiones ligeramente diferentes de la misma macro, por lo que es útil poder copiar una macro 'plantilla' en varios registros y luego modificar cada una de ellas en su lugar.

Para dar un ejemplo práctico, aquí está el problema que provocó esta pregunta para mí.

Necesito convertir la siguiente línea de un lenguaje de descripción de hardware en muchos bloques repetidos,

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

a

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);

Tengo una macro que realiza esto, usando la función de incremento, yypW^At)^Aque almacené en el registro "a.

A veces, necesito que el patrón de incremento sea ligeramente 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);

donde "bestaría la macro en el registro yypW^At)^A^A.

Quiero un registro para hacer esto, pero para cada incremento de 1-5. El registro "apodría (de alguna manera) copiarse a los registros b a través de e. Luego pegaría cada registro en el búfer, realizaría la modificación requerida (agregaría más términos, cambiaría el carácter que sigue al tmovimiento, etc.) y tiraría la expresión modificada nuevamente al registro. Idealmente, este último paso podría incluso incluirse en los comandos para copiar los registros

Esto me evita repetir todos los caracteres de la macro que NO requieren cambios. Para mi ejemplo, puede ser trivial, pero puedo prever momentos en que podría ser muy útil hacer lo que le pido.

Equipo
fuente
55
Como comentario aparte, no recomendaría usar los registros numerados. Los únicos registros "seguros" son los registros alfabéticos. Todos los demás registros son configurados automáticamente por Vim.
jamessan

Respuestas:

7

Las macros son solo texto.

Abra un nuevo búfer vacío y coloque su macro allí. Puede duplicar las líneas, cambiar una cosa aquí y otra en otra parte, luego tirar de una línea y usarla de inmediato @".

No es necesario contaminar sus registros, especialmente los registros de números que tienen un propósito completamente diferente.

- editar -

Su pregunta es más fácil de entender ahora que agregó alguna explicación.

Como resultado, solo necesita cambiar su grabación inicial para lograr su objetivo, sin jugar con los registros como si fueran variables:

: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 crear 5 copias de la línea actual con el último número incrementado en 2:

:let i = 2|norm 5@a

o 12 copias, con el último número incrementado en 23:

:let i = 23|norm 12@a
romainl
fuente
Está de acuerdo con los registros numéricos, pero ¿qué sucede si desea usar esto en un comando y necesita registros que comienzan igual pero se vuelven diferentes?
wchargin
@WChargin, por favor explique.
romainl
Al igual que en, tal vez lo que quiero hacer algo con copias rotadas de una cadena, por lo que si abcdeestá en @q, entonces yo quiero @x="bcdea", @y="abcde"y @z="eabcd". Podría comenzar dejando @x, @yy @ztodos iguales @qy luego modificándolos según sea necesario. Obviamente, acabo de inventar esto, pero parece que podría haber algunos casos en los que algo similar podría ser útil.
wchargin
2
@ Kit, estoy un poco preocupado por la falta de ejemplos prácticos en su pregunta que inmediatamente hace que huela a XY. Estoy casi seguro de que estás usando mal los registros, así que me encantaría leer una explicación de lo que estás tratando de hacer.
romainl
1
@ Kit, ese es uno de los muchos problemas con las preguntas de problemas XY. La respuesta más votada es una respuesta directa de alta calidad a su pregunta, pero en última instancia inútil en el contexto de su problema real, mientras que mi respuesta menos votada es una solución real a su problema subyacente. Ambas respuestas son correctas, pero responden preguntas diferentes, lo que dificulta la decisión. Si fuera yo, aceptaría la respuesta que aborda mi problema central ... pero ese soy solo yo.
romainl
6

Usando getregysetreg

Para copiar de qa los registros 1- 5:

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

Para copiar a una lista más general:

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

Utilizando execute

Para copiar de qa los registros 1- 5:

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

Para copiar a una lista más general:

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

Explicación. El comando letse puede usar como let @x=@y, qué copias se registran ypara registrarse x. Esencialmente, solo estamos construyendo estos comandos en un bucle (cambiando el valor de xen la forma anterior) y executeusándolos.

wchargin
fuente
1
No hay necesidad de usar :exeaquí. Las funciones getreg()y setreg()serían más limpias.
jamessan
@jamessan Buena sugerencia, gracias. ¿Estoy usando esto correctamente?
wchargin
Lo he editado para agregar el segundo argumento opcional a getreg () ya que eso devuelve el contenido del registro en lugar de una posible evaluación del mismo.
jamessan
1

Para responder directamente a la pregunta, si desea copiar rápida y fácilmente el contenido de un registro a otro, puede poner lo siguiente en su .vimrc. Luego puede ejecutar <leader>rcabpara copiar el contenido del registro apara registrarse b. Como ejemplo, elegí <leader>rcrepresentar 'copia de registro'

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>
Steve Vermeulen
fuente
1
Me gustaría recomendar getreg(sourceReg, 1).
jamessan
Ah si, cierto. Fijo.
Steve Vermeulen