¿Cómo elimino un bloque de texto grande sin contar las líneas?


91

En vim, a menudo necesito eliminar o tirar / poner grandes bloques de texto.

Puedo contar las líneas de texto e ingresar algo como 50ddeliminar 50 líneas.

Pero eso es un poco doloroso. ¿Cómo puedo borrar este gran bloque de texto sin tener que saber cuántas líneas borrar de antemano?


44
¿Cómo sabes dónde está el final? Si puede describir el final, puede eliminarlo hasta ese punto. Si puedes describir cómo puedes movehasta el final. Luego, eliminar hasta el final no es diferente a pasar al final.
Martin York

@Loki, avanzar hasta el final usualmente solo usa la página hacia abajo y las teclas de flecha hasta que llegue allí. Se puede ser el primero o décimo línea en blanco, que puede ser la primera llave de cierre. La conclusión es que varía bastante.

2
también verifique esta respuesta: stackoverflow.com/a/16407391/164835
Kent

Respuestas:


111

Vaya a la línea de inicio de su bloque y escriba ma(marque "a", aunque, por supuesto, puede usar letras diferentes , e incluso varias letras para diferentes marcas, siempre que pueda mantener en su cabeza de qué letra es una marca) .

Luego vaya a la última línea e ingrese d'a(eliminar para marcar "a") o y'a(tirar para marcar "a") (a) .

Eso eliminará / eliminará todas las líneas de la actual a la marcada (inclusive)

Luego puede pegarlo en otro lugar con los comandos de pegado normales, como po P.

También es compatible con vi, así como vim, en la remota posibilidad de que su entorno no ha sido bendecida con este último.


(a) También lo uso para guardar mi lugar en el archivo si tengo que ir a buscar otro lugar para, por ejemplo, copiar y pegar la definición de una función a la que quiero llamar.

Simplemente marco la línea actual de la misma manera, may luego me alejo para encontrar lo que esté buscando.

Luego, una vez que lo encontré y lo copié en un registro, solo ingresé 'apara volver a marcar "a", la línea que guardé de antemano, donde luego puedo pegarla.


99
También podría usar el modo visual para esto, ¿verdad?
jmc

3
Esa es una forma, jmc, pero no estoy seguro de que vi estándar tenga un modo visual.

55
Desde que pasé de la selección visual a las marcas y números de línea relativos hace aproximadamente un año, descubrí que los comandos de movimiento vi son mucho más rápidos y eficientes que la selección visual. Aunque lo último es más fácil cada vez que presiono la vtecla, me pregunto si realmente lo necesito o ¿hay una mejor forma de movimiento?
Sukima

1
Sí, de la misma manera es interesante, @Sukima, que me siento más eficiente cuanto menos uso el mouse, incluso en una GUI. Me encuentro siendo más rápido si puedo permanecer en el teclado.

3
Si alguna vez está editando algo con líneas realmente largas, la versión de backtick de esto también puede ser muy útil (que se refiere al lugar dentro de la línea, en lugar de la línea completa).
msouth

65

En Vim, use el modo de línea visual :

  1. Coloque el cursor en la línea superior del bloque de texto / código para eliminar
  2. Presione V(Eso es "V" mayúscula: Shift+ v)
  3. Mueva el cursor hacia abajo hasta la parte inferior del bloque de texto / código para eliminar
  4. prensa d

Para eliminar grandes bloques de texto, esto es preferible al modo visual simple porque no necesita preocuparse sobre en qué columna se encuentra el cursor.


3
En el paso 3. puedes moverte más rápido usando movimientos de objetos. Por ejemplo, puede usar }para seleccionar párrafos completos o )para oraciones. Hay más, puedes leer sobre ellos en:h object-motions
mxlian

2
También buscar una subcadena /something<CR>es un método muy eficiente para llegar al final de su bloque de selección
mxlian

1
Este es mi método preferido. Sin embargo, alternativamente, sin tener que presionar repetidamente jpara mover el cursor hacia abajo (paso 3), puede escribir el número de línea seguido de Gpara seleccionar hasta esa línea. Ejemplo:V150Gd
Ranhiru Jude Cooray


39

Puede eliminar fácilmente un gran bloque de texto conociendo su estructura.

Si es un párrafo, use: d{(por ejemplo, puede prefijar con el número de párrafos)

Si es un bloque de código entre paréntesis, use: d%

Si el texto aparece hasta el final del archivo, use: dG

Si sabe cómo termina, use: d/y escriba el texto final seguido de Enter(también puede usar la expresión regular, por lo que las posibilidades son infinitas).

Alternativamente, use el modo visual ( V) y use las teclas de movimiento para seleccionar rápidamente el texto (por ejemplo, por {) y eliminarlo ( d).

O como sugirió Lie Ryan, use d/search-string/epara eliminar texto del cursor actual a la cadena buscada.

Ver: :help dy :help motionpara más información.


2
También hay d/search-string/eque eliminar desde el cursor actual hasta el final de la cadena de búsqueda, incluida la cadena de búsqueda en sí, y c/search-queryentrar en modo de inserción después de la eliminación. Usar d/with set incsearches una combinación ordenada, ya que le permite averiguar de manera interactiva si está operando en el rango de texto correcto y le ayuda a saber cuándo dejar de escribir la consulta de búsqueda para evitar escribir más de lo necesario.
Mentira Ryan

44
También encuentro dcon a(externo) o i(interno) y un especificador de objeto muy útil. Los objetos como wpor palabra, ppara el párrafo, (o bpara (...), [por [...], {o Bpara {...}, etc. documentación para visuales-operadores .
Shahbaz

22

Puede usar movimientos y / u objetos de texto. Por ejemplo, puede eliminar todo desde el cursor hasta la siguiente línea en blanco con d}. Si el cursor está dentro de un párrafo, el párrafo se puede eliminar con dipo dap. Si el cursor está dentro de una etiqueta HTML, puede eliminarlo con dito dat.

Los buenos mnemónicos para estos son " d elete i nside" y " d elete a round" (párrafo / etiqueta / paréntesis).


11

Yo suelo hacer

:<start>,<end>d

que eliminará cada línea entre los números de línea inicial y final proporcionados (incluidas las líneas dadas).

Tenga en cuenta que ambos starty endpueden ser números de línea absolutos, patrones o desplazamientos desde otra posición.

Ver también el comentario de doubleDown sobre ver Vim's documentación de gama , tiene algunos consejos útiles.

Ejemplo:

Digamos que tiene el siguiente archivo:

1. The quick brown
2. fox jumps
3. over the
4. lazy dog.

Luego, usando el comando :2,3do :/fox/,/over/do :/quick/+1,/lazy/-1o :+1,+2dsi estás en la primera línea o :-1,.dsi estás en la tercera línea, terminas con:

1. The quick brown
4. lazy dog.

¿Pero esto significa que aún necesitas contar las líneas? ¿O entendí mal tu respuesta?
Martin Tournoij

77
No necesita contar las líneas, pero sí necesita saber los números de línea.
jmc

En primer lugar no :set ruler, y luego ir a la parte superior y la parte inferior del texto para encontrar starty endnúmeros de línea, y luego hacerlo:<start>,<end>d
roblogic

1
También puede usar números de línea relativos:+12,+24d
rpattabi el

2
En realidad, puede usar un par de números de línea, un par de patrones o un par mixto para <start>y <end>para esto. Para referencia, ver :h [range]. Por lo tanto, en realidad es un poco más flexible de lo que parece.
doubleDown

5

Si se trata de bloques delimitados (p. Ej., Código o etiquetas XML / HTML) con los que está tratando, puede colocar el cursor al comienzo del bloque y usar el modo visual junto con %seleccionar rápidamente bloques enteros de código y luego presionar dpara eliminarlos


55
Alternativamente, se puede utilizar dappara borrar un párrafo, da(, da{, da[, eliminar bloques delimeted por paréntesis, llaves o corchetes. Para html hay dat, que elimina una etiqueta, da'y da"elimina cadenas. También hay los dip, di(variantes, etc., que se elimine todo dentro de los delimitadores, pero deja intactos los delimitadores. Alternativamente, puede usar vap(resp vip) para seleccionar todos los párrafos (resp inner). (Y entonces hay va(y vi(.) Además, hay capy cip(o ca(y ci() para eliminar e ir al modo de inserción (es decir, "cambiar"). Y yappara tirar
jmc

Creo que algunos de los enlaces @jmc descritos en su comentario anterior provienen del plugin surround.vim de Tim Pope. Es un gran complemento que recomendaría instalar, pero significa que estos enlaces no son parte de la instalación predeterminada de vim.
Haegin

5

Además de todos los otros buenos consejos, estoy agregando d+ Shift+ Lpara eliminar todo, desde la posición actual del cursor hasta la última línea visible en la pantalla. Repetir el comando lo bajará relativamente rápido.


5

El complemento numbers.vim es muy útil para esto. Es una forma mejorada de preceder cada línea con un número de línea. ¡Como 'number'y 'relativenumber', ambos se unieron!

Está habilitado de forma predeterminada después de la instalación, también desea agregarlo set numbera su vimrc si aún no lo tiene, ya que se comporta de manera extraña si no lo tiene.

En modo normal, se parece a :set relativenumber:

  3 call plug#begin('~/.vim/plugged')
  2 
  1 Plug 'myusuf3/numbers.vim'
7   set number█
  1 
  2 " Add indentation 'guidelines' (:IndentLinesToggle or <F11>)
  3 Plug 'Yggdroot/indentLine'

Le muestra números de línea relativos, excepto la línea donde está el cursor, donde muestra el número de línea absoluto (7 en este caso).

Si luego cambiamos al modo de inserción , se comportará como si numberestuviera configurado mostrando siempre números de línea absolutos:

  4 call plug#begin('~/.vim/plugged')
  5 
  6 Plug 'myusuf3/numbers.vim'
  7 set number█
  8   
  9 " Add indentation 'guidelines' (:IndentLinesToggle or <F11>)
 10 Plug 'Yggdroot/indentLine'

Hay algunas opciones más y algunos comandos (consulte la página de inicio), pero los valores predeterminados deberían funcionar para la mayoría de las personas.


Al principio pensé que esta respuesta estaba un poco fuera de tema, pero luego instalé el complemento y tengo que decir que es un cambio de juego para mí. Solía ​​intercambiar manualmente y el paso mental adicional significaba que evitaba usar esos movimientos. ¡Gracias!
Sukima

1
Esto suena como algo que podría hacer un autocmd InsertEnter / InsertLeave para alternar la numeración de línea relativa. ¿Me estoy perdiendo de algo?
Ben

Llegué MUY tarde a la fiesta, pero @Ben tiene razón, esto es solo un par de líneas de autocomando. Por ejemplo, en mi vimrc tengo set number, set relativenumberentonces autocmd InsertEnter * :set norelativenumberyautocmd InsertLeave * :set relativenumber
B Layer

4

Otro enfoque es si está tratando de eliminar un patrón específico, simplemente puede escribir d/delimEnter.


2

Puede usar el procedimiento normal de entrada dmás un movimiento (como ya se explicó en las otras respuestas). El complemento EasyMotion proporciona nuevos movimientos que puede usar para resolver su problema de manera rápida y fácil.

Supongamos que desea eliminar de la posición actual del cursor al final de cualquier palabra en la pantalla, las teclas de movimiento serían <Leader><Leader>e(similares al emovimiento normal ). Luego escriba las letras resaltadas que aparecen al final de la palabra en cuestión. También hay un movimiento de línea para que pueda eliminar la línea actual hasta la línea en cuestión con <Leader><Leader>j.

Tengo mi <Leader>llave configurada ,. Entonces, el comando completo es d<Leader><Leader>e{letra (s) resaltada (s)}.

De :help easymotion:

EasyMotion proporciona una forma mucho más simple de usar algunos movimientos en vim. Toma la <number>salida de <number>W o <number>F {char}, poniendo de relieve todas las opciones posibles y lo que le permite presionar una tecla para saltar directamente a la meta.

Cuando se activa uno de los movimientos disponibles, todo el texto visible que precede o sigue al cursor se desvanece y los objetivos de movimiento se resaltan.

Editar:

El repositorio github de EasyMotion está en https://github.com/Lokaltog/vim-easymotion .

Este reddit sobre personas que usan easymotion podría ser una lectura divertida.


1

Hay una solución simple que puede resolver su problema.

Coloque el cursor al comienzo del bloque de texto que desea eliminar y realice d50gg.

Esto eliminará todas las líneas de su posición actual a la línea 50 de su texto.

eq: si su cursor está en la línea 46 , d50ggborrará 4 líneas.


1
Sugeriría usar en Glugar de gg, ya que también funciona en vi, y por supuesto, :set numbersiempre es útil para encontrar el número de línea a la que desea ir.
Random832

El objetivo de esta pregunta es que no sabes cuántas líneas quieres eliminar.
200_success

200_success, no tiene que saber cuántas líneas desea eliminar con la respuesta que publiqué. Todo lo que tiene que saber es "a qué línea desea eliminar"
Geee

1

Use el modo visual con resaltado de línea.

  1. Coloque el cursor en la línea superior del bloque de texto / código para eliminar
  2. Presione Shift+v
  3. Mueva el cursor hacia abajo hasta la parte inferior del bloque de texto / código para eliminar
  4. prensa d

Prefiero este método para eliminar bloques de código porque elimina líneas enteras en comparación con simplemente usar el modo visual, donde debe colocar el cursor en la columna derecha para eliminar lo que desea.


3
Básicamente repites la respuesta con @ 200_success.
Martin Schröder

1

No me gusta estar relativenumberencendido todo el tiempo, así que configuré mi Vim para habilitarlo solo cuando estoy en modo visual:

" Entering Visual mode
nnoremap <silent>     v :set relativenumber cursorcolumn<CR>v
nnoremap <silent> <C-q> :set relativenumber cursorcolumn<CR><C-q>
nnoremap <silent>    gv :set relativenumber cursorcolumn<CR>gv
nnoremap <silent>     V :set relativenumber<CR>V

" When finished
augroup ClearCursorColumnAndLine
    autocmd!
    autocmd CursorHold * set norelativenumber nocursorcolumn nocursorline
augroup END

Esto facilita su tarea:

V49jd

porque después de golpear Vpuedes ver qué tan lejos está la línea objetivo.

Esto puede resultar molesto a largo plazo (el texto se desplaza hacia la derecha y hacia la izquierda cuando el número relativo está habilitado / deshabilitado), pero hasta ahora lo estoy disfrutando bastante.


1
Creo que usas v<Esc>d50j?
Martin Tournoij

Gracias, de hecho lo había escrito incorrectamente. En realidad, comienzo Vsi sé que haré una operación en línea, y luego puedo dejarlo dhasta el final, para mayor confianza.
joeytwiddle

Mi respuesta parece ser la aproximación de un hombre pobre al plugin números.vim ofrecido en otra respuesta. ;-)
joeytwiddle

1

Lo que funcionó muy bien para mí con vi:

  1. :set number para ver el número de la línea hasta donde quería borrar;

    +1289 idle 
    +1289 idle 
    +1290 # <- I want to delete until here
    +1291 if [[ ! -z "$SFIN" ]]
    
  2. Regrese a la línea donde tuvo que comenzar la eliminación

  3. Eliminación usada de la línea actual, en modo normal> d1290G