Vim: Reemplazo de una línea por otra tirada antes

112

Al menos una vez al día tengo la siguiente situación:

A: This line should also replace line X
...
X: This is line should be replaced

Creo que no realizo esa tarea de manera eficiente.

Lo que hago:

  • Vaya a la línea A: AG
  • Yank línea A: yy
  • Ir a la línea X: XG
  • Pegar línea A: P
  • Mover a la línea anterior: j
  • Eliminar línea anterior: dd

Esto tiene la desventaja adicional de que la línea X ahora está en el registro predeterminado, lo cual es molesto si encuentro otra línea que debería reemplazarse con A. Al mover y pegar desde un registro adicional ( "ayy " , aP ) hace que esta simple tarea sea uniforme menos eficiente.

Mis preguntas:

  • ¿Perdí un comando Vim incorporado para reemplazar una línea arrancada antes?
  • Si no es así, ¿cómo puedo vincular mi propio comando que deja (o restaura) la línea tirada en el registro predeterminado?
crujiente
fuente
2
Este es mi mayor problema con el modelo de edición de Vim. Me encantaría saber una solución. Un editor CUA distingue entre cortar y eliminar, por lo que solo corta un poco de texto, luego puede eliminar y pegar todo lo que desee. Con Vim, cualquier eliminación que haga destruye el texto cortado. Terminas usando muchas más pulsaciones de teclas que con otro editor.
Barro
3
YankRing
ajreal
@Mud aprender sobre :movey el agujero negro registro ( _) (o, de hecho, sólo registros)
sehe
2
@sehe Soy perfectamente consciente de los registros, pero eso agrega 4 pulsaciones de teclas por operación de cortar / pegar y requiere más previsión. Cuando estás editando mucho, eso se suma rápidamente.
Mud
Aparte de ahorrar unos pocos bytes de memoria, ¿hay alguna ventaja en utilizar el registro de agujero negro en comparación con cualquier otro registro? Yo diría que cualquier registro puede ser un registro de agujero negro si no se lee.
sleblanc

Respuestas:

91

Que haría yo :

  1. aG
  2. Y
  3. xG
  4. Vp

Usted no tiene que salir de modo normal, pero lo hace tirón de la línea. Sin embargo, puede usar V"0plo que siempre pondrá la línea tirada en el paso 2.

hielo
fuente
11
@duddle: sí, Yes sinónimo deyy
icecrime
8
Los pasos 1 y 2 se pueden combinar usando: ay [Ej .: 20y] Seguido por Vp debería ser suficiente. No tienes que ir a una línea para tirar de él.
Bharad
2
Si sobrescribe líneas adicionales con ccCTRL + r0ESC en lugar de V "0p, todas las líneas siguientes se pueden reemplazar con solo. (El repetidor)
Jordan Morris
Yes un sinónimo de yy, pero sugiero reasignarlo para y$que coincida con Dy C.
mgold
Consulte la respuesta de Jordan Morris stackoverflow.com/users/970673/jordan-morris a continuación: realmente usa los comandos vim al máximo al permitirle repetir el comando varias veces.
JESii
105

Vp: seleccione la línea, pegue lo que fue tirado

dorio
fuente
3
VPfunciona igual de bien, lo cual es útil porque puede mantener presionada la tecla Mayús durante toda la secuencia.
George Hilliard
23
muy buen truco, aunque vale la pena señalar una (quizás) advertencia importante: esto hace que el registro de yank se actualice con el contenido de la línea que se está sobrescribiendo, por lo que puede que no funcione bien con algunas tareas, por ejemplo, si desea sobrescribir la misma línea en varios destinos.
underscore_d
8
@underscore_d, se reproduce bien si lo hace V"0p, que se pega desde el último registro tirado.
timblactú
@timblaktu ¿Puedes explicar qué V"0phace? V entra en modo de línea de línea visual y p es para pegar. ¿Cuáles son "y 0 para las gracias?
theprogrammer
43

Esto tiene la desventaja adicional de que la línea X ahora está en el registro predeterminado, lo cual es molesto si encuentro otra línea que debería reemplazarse con A.

Para eliminar texto sin afectar los registros normales, puede utilizar el registro de agujero negro "_:

"_dd
Eugene Yarmash
fuente
10
He añadido algunas asignaciones a mi .vimrc para hacer dy ddusar siempre el agujero negro, y xy xxrealizar lo que la mayoría de los editores llamarían un "corte" (borrar y guardar en el registro por defecto):noremap x d noremap xx dd noremap d "_d noremap dd "_dd
IMSOP
2
Desconfío de reasignar cosas en VIM, porque esto puede no ser fácil en otras computadoras o en complementos de estilo VIM para IDE. Además, los diseñadores de VIM tienden a haber resuelto problemas con las asignaciones predeterminadas si realmente te interesan.
Jordan Morris
15

Sobre la base de las respuestas que sugieren usar Vpo VPpegar sobre una línea, para evitar cambiar el contenido del registro de yank, encuentro que el comando más ergonómico es simplemente:

VPY

RichardW
fuente
Esta es la solución más simple que deja el contenido del tirón igual. ¡Muchas gracias!
heylookltsme
14
  1. aa
  2. j (muévase a la línea que desea reemplazar), y luego
  3. Vp (v mayúscula y luego p, se reemplazará con el contenido extraído)
Mariano Anaya
fuente
¡increíble! De hecho, es muy breve y facilita la selección de varias líneas con el modo visual. También mantiene intacto el tampón de pasta. Es molesto cuando dd sobrescribe ese búfer ...
Aktau
@Aktau esto no deja intacto el búfer.
Jordan Morris
9

Usaría el modo de línea de comandos (Ex) y haría los siguientes dos comandos

:XmA
:Ad

Esto simplemente mueve la línea X justo debajo de A, luego borrando A mueve esa línea hacia arriba

Por ejemplo

:7m3
:3d
ericgamliel
fuente
¿Puede dar un ejemplo? Cuando presiono, por ejemplo, 50Gm30G Vim va a la línea 50 y luego a la parte inferior y eso es todo. Además: el anuncio no hace nada para A = 50 o A = 50G
crujiente
7
  1. Muévase al inicio de la primera línea.

  2. y, $- copia la línea sin el salto de línea al final

  3. Moverse al inicio de la línea objetivo.

    1. V, p- reemplazar solo una línea de destino

    2. c, c, Ctrlr, 0, Esc- sustituir a la línea de meta con el tirón inicial

  4. Moverse al inicio de la siguiente línea objetivo.

  5. . - repite el comando emitido en 4.2.

Notas:

  • 4.1 es y, $porque si lo hace y, yo Ycopiará el salto de línea y Ctrlr, en 0realidad ,  agregará el salto de línea debajo de la línea objetivo.

  • 4.2 reemplaza V p, que no funciona con la repetición porque técnicamente la última acción es eliminar, por .lo que solo eliminaría una línea.

  • Si alguien sabe cómo emitir 'reemplazar línea actual con registro' desde el modo EX (línea de comando), me gustaría saber de usted (y saber dónde encontró la documentación). Puede haber un comando EX repetible que sea más rápido que 4.2 y / o no tenga la advertencia de salto de línea.

Jordan Morris
fuente
1
El paso 4.2 es el asesino aquí, ya que ahora puede repetir todo el proceso con el comando dot como en 4.3 - ¡de eso se trata vim!
JESii
1
No entiendo esto. 'AG' pone mi creador al final de la línea, ingresa al modo de inserción e ingresa una 'G'. ¿Qué es lo que no entiendo?
gustafbstrom
@gustafbstrom crítica justa: lo siento, se suponía que la A representaba el número de línea, pero no lo señalé. Editado.
Jordan Morris
5

Esto es lo que haría

  • Mover el comienzo de la línea A, AG(donde A es un número de línea obviamente)
  • Yank line a algún registro, por ejemplo, a (sin nueva línea). Tipo"ay$
  • Mover para insertar línea, XG
  • Línea sustituta, S
  • Insertar desde el registro a, Ctrl-Ra
Brian Rasmussen
fuente
4

Puedes usar esto con el modo visual.

  • Vaya a la línea A: AG
  • Seleccione la línea con modo visual: VESC
  • ir a la línea X: XG
  • Ingrese al modo sustituto para la línea: S
  • Pegue la línea que copió: shift+ insert(o cualquier otro mapeo que tenga para pegar desde el portapapeles).
Nathan Fellman
fuente
¡Ah! No sabía nada de V y S . Sin embargo, sus pasos no me funcionan porque no me meto en el portapapeles de mi sistema operativo, que es el único al que puedo acceder en el modo de inserción. Así que primero tendría que salir del modo de inserción.
Crujiente
3

También puedes hacer:

Vy (in normal mode at the line you want to copy)
Vp (in normal mode at the line you want to replace)
  • No crea espacios ni extremos de línea.
  • El cursor se coloca al comienzo del texto copiado.

Se pueden usar las mismas teclas para tirar / pegar más de una línea.

V (in normal mode at what you want to yank)
(use jk to move the selection)
y (to yank the selection)
V (in normal mode at where you want to paste)
(use jk to move the selection)
p (to replace the selection with the yanked lines)
Kozmonaut
fuente
2

Puede utilizar estos comandos en el modo normal:

:AmX | Xd

el mcomando es para m[ove], que mueve el número de línea A después del número de línea X, si desea copiar en lugar de mover la línea, utilice co[py]. el dcomando es para d[elete].

Puede mover (copiar usando co) un rango de líneas usando

:start,end m X
Nafaa Boutefer
fuente
2

A la luz del comentario reciente de cicld (¡gracias!), Veo que no entendí completamente el problema original. Mover la línea no es apropiado, pero copiar lo es (ya que la línea está tirada). Así que lo revisaría a:

:1t20:20d_
  1. Copie la primera línea (el :tcomando es un alias para :copy) después de la línea 20 (la colocará en la línea 21)

  2. Elimine la línea 20, colocando la línea eliminada en el registro 'agujero negro' ( _) (es decir, sin afectar el búfer de yank actual)

Como se mencionó en el comentario reciente, esto no afectará la posición actual del cursor.

nkalvi
fuente
1
  1. : ay (donde a es el número de línea. Ejemplo: 20y). Esto tira de una línea (juego de palabras).
  2. Vp
Bharad
fuente
1

Me resulta más fácil usar el comando Ex para esto; ex. para mover la línea 9 a la 46:

 :46|9m.|-1d

Esto moverá el cursor a la línea 46, moverá la línea 9 debajo de la actual, luego borrará la línea anterior (ya que la línea movida es la actual).

O usando marca (s), usando marca 'a':

:46ma a|9m'a|'ad
nk3181544
fuente
La belleza de los comandos EX es que puede ejecutarlos donde sea que esté el cursor (en modo normal). Prefiero :1m20|.+1d(mueva la línea 1 a la línea 20 y elimine la siguiente línea, es decir, el texto que estaba en la línea 20 anteriormente). ¡Aunque es la misma idea!
alrededor del
1

A menudo tengo que Y una línea y reemplazarla en varios lugares, cada uno de los cuales tiene un valor diferente (lo que significa que no puedo hacer una expresión regular).

Y para tirar de la línea original deseada

y luego en cada línea que le gustaría reemplazar, VpzeroY

Ron
fuente
0

Simplemente usaría el registro "Agujero negro":

dado:

nnoremap <Cd> "_dd

la solucion seria:

<Cd> aa

j5shi
fuente