¿Edición multilínea de Vim como en sublimetext?

132

Empecé a usar gvim, y no puedo entender cómo funciona la edición multilínea en gvim.

Por ejemplo:

Texto original:

asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

Ctrl + q, jjjjjj, $ todo está seleccionado, luego presiono I para hacer una inserción multilínea.

Mi intención es insertar comillas como en la primera línea, y luego presionar Esc:

asd "asd asd" asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

¿Que pasó? Esperaba un comportamiento similar al de sublimetext:

ingrese la descripción de la imagen aquí

Si no sabe cómo funciona, simplemente repite las acciones para cada línea. ¿Cómo puede lograr eso? ¿Y qué está haciendo vim aquí?

AlfredoVR
fuente
Simplemente grabe una macro de teclado para cambiar la primera línea y luego reproduzca la macro para todas las demás líneas.
alta5

Respuestas:

214

Hazte un favor dejando caer la capa de compatibilidad de Windows.

El acceso directo normal para ingresar al modo Visual-Block es <C-v>.

Otros se han ocupado de grabar macros, aquí hay algunas otras ideas:

Usando solo el modo de bloqueo visual .

  1. Coloca el cursor en la segunda palabra:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. Presione <C-v>para ingresar al modo de bloqueo visual y expanda su selección hacia la parte inferior:

    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    
  3. Golpe I"<Esc>para obtener:

    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  4. Coloque el cursor sobre el último carácter de la tercera palabra:

    asd "asd as|d| asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  5. Presione <C-v>para ingresar al modo de bloqueo visual y expanda su selección hacia la parte inferior:

    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    
  6. Golpe A"<Esc>para obtener:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

Con modo de bloqueo visual y Surround.vim .

  1. Coloca el cursor en la segunda palabra:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. Presione <C-v>para ingresar al modo de bloqueo visual y expanda su selección hacia la parte inferior y hacia la derecha:

    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    
  3. Presione S"para rodear su selección con ":

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

Con modo de línea visual y :normal.

  1. Presiona Vpara seleccionar toda la línea y expandirla hacia la parte inferior:

    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    
  2. Ejecute este comando: :'<,'>norm ^wi"<C-v><Esc>eea"<CR>para obtener:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    
    • :norm[al]le permite ejecutar comandos de modo normal en un rango de líneas (la '<,'>parte se agrega automáticamente por Vim y significa "actuar en el área seleccionada")

    • ^ coloca el cursor en el primer carácter de la línea

    • w pasa a la siguiente palabra

    • i"inserta un "antes del cursor

    • <C-v><Esc>es la forma en que Vim ingresa un carácter de control en este contexto, aquí se <Esc>usa para salir del modo de inserción

    • ee se mueve al final de la siguiente palabra

    • a"agrega un "después del cursor

    • <CR> ejecuta el comando

    Usando Surround.vim, el comando anterior se convierte en

    :'<,'>norm ^wvees"<CR>
    
romainl
fuente
77
Para los pasos 4 y 5, recomendaría presionar gvpara recuperar su selección visual anterior y luego moverla horizontalmente, tal vez con 2e. ( gv¡
Cuantas
44
surround.vim usa un pequeño sen modo normal pero uno grande Sen modo visual, por lo que en el paso 3 del método surround.vim, las pulsaciones de teclas deberían serS"
joeytwiddle
1
El punto 3 de visual-block + Surround.vim debería ser S", nos"
zool
1
En lugar de los pasos 5 y 6 del modo de bloqueo visual, simplemente puede colocar el cursor después de la tercera palabra y presionar ..
Jonas
2
Esto es genial, pero esto solo funciona en algunos casos donde los caracteres que desea editar en las diferentes líneas están exactamente en la misma posición horizontal en cada línea, y las líneas editadas son una tras otra. ¿No podemos elegir dónde ingresar en el modo de edición en qué línea en Vim? Podemos en Sublim ... EDITAR: En realidad, la segunda respuesta es lo que estaba buscando
Alexandre Bourlier
30

Esas son algunas de las soluciones listas para usar dadas anteriormente, pero también podemos probar algunos complementos que proporcionan múltiples cursores como Sublime.

Creo que este parece prometedor:

Parecía abandonado por un tiempo, pero ha tenido algunas contribuciones en 2014.

Es bastante poderoso, aunque me tomó un tiempo acostumbrarme al flujo (que es bastante sublime pero todavía modal como Vim).

En mi experiencia, si tiene muchos otros complementos instalados, ¡puede encontrar algunos conflictos!

Hay otros intentos de esta característica:

Siéntase libre de editar si nota alguna de estas mejoras en proceso.

joeytwiddle
fuente
Parece que github.com/osyo-manga/vim-over es el más activo del grupo en este momento.
Wernight
Excelente, eso es lo que estaba buscando
Alexandre Bourlier
1
Después de haber probado la mayoría de ellos, hlissner / vim-multiedit parece el mejor AFAIAC
Alexandre Bourlier
1
Verifique mg979 / vim-visual-multi como un buen reemplazo para vim-multiple-cursores
Mushex Antaranian
29

Hay varias formas de lograr eso en Vim. Sin embargo, no sé cuáles son más similares a Sublime Text.


El primero sería a través del modo de inserción multilínea . Coloque el cursor en la segunda "a" en la primera línea, presione Ctrl-V, seleccione todas las líneas, luego presione Iy escriba una comilla doble. Al presionar <esc>se repetirá la operación en cada línea.


El segundo es a través de macros. Coloque el cursor en el primer carácter y comience a grabar una macro con qa. Vaya a la derecha con llll, ingrese al modo de inserción con a, ponga una comilla doble, salga del modo de inserción y regrese al comienzo de su fila con <home>(o equivalente). Presione jpara moverse una fila hacia abajo. Deja de grabar con q. Y luego reproduce la macro con @a. Varias veces.


¿Alguno de los enfoques anteriores funciona para usted?

Torre
fuente
15

si usa el comando "global", puede repetir lo que puede hacer en una línea en cualquier número de líneas.

:g/<search>/.<your ex command>

ejemplo:

:g/foo/.s/bar/baz/g

El comando anterior encuentra todas las líneas que tienen foo y reemplaza todas las apariciones de barra en esa línea con baz.

:g/.*/

hará en cada línea

srini.venigalla
fuente
1
Esto es muy útil, no lo sabía. Parece una combinación de comandos tan poderosa e inteligente.
0xc0de
Por conveniencia, escribí una pequeña función que toma la palabra debajo del cursor (o la palabra seleccionada visualmente), solicita un reemplazo y luego ejecuta el :gcomando descrito aquí. Me gusta usar /gcpara pedir "confirmaciones" para poder presionar yo npara cada reemplazo, o apara cambiarlos todos.
joeytwiddle
11
Ctrl-v ................ start visual block selection
6j .................... go down 6 lines
I" .................... inserts " at the beginning
<Esc><Esc> ............ finishes start
2fdl. ................. second 'd' l (goes right) . (repeats insertion)
SergioAraujo
fuente
En el paso 3, Ino puede ingresar al modo de inserción, ¿sabe por qué sucede esto?
Ninja
Intente cargar vim sin complementos: vim -u NONEe intente realizar la acción deseada nuevamente, podría ser algún mapa o complemento que cambie el comportamiento de su vim.
SergioAraujo
6

No estoy seguro de lo que vimestá haciendo, pero es un efecto interesante. La forma en que estás describiendo lo que quieres suena más a cómo funcionan las macros ( :help macro). Algo como esto haría lo que quieras con las macros (comenzando en modo normal):

  1. qa: Grabar macro para aregistrar.
  2. 0w: 0ir al inicio de la línea, wsaltar una palabra.
  3. i"<Esc>: Ingrese al modo de inserción, inserte ay "regrese al modo normal.
  4. 2e: Salta al final de la segunda palabra.
  5. a"<Esc>: Añadir a ".
  6. jq Ir a la siguiente línea y finalizar la grabación de macro.

Tomados en conjunto: qa0wi"<Esc>2ea"<Esc>

Ahora puede ejecutar la macro con @a, repita la última macro con @@. Para aplicar al resto del archivo, haga algo como lo 99@aque se supone que no tiene más de 99 líneas, la ejecución de la macro finalizará cuando llegue al final del archivo.

Aquí le mostramos cómo lograr lo que desea visual-block-mode(comenzando en modo normal):

  1. Navega hasta donde quieres que esté la primera cita.
  2. Ingrese visual-block-mode, seleccione las líneas que desea afectar, Gpara ir al final del archivo.
  3. Hit I"<Esc>.
  4. Muévase al siguiente lugar donde desea insertar a ".
  5. Desea repetir lo que acaba de hacer para que un simple .sea ​​suficiente.
Thor
fuente
44
No hay necesidad de 99 @ a. Si desea ejecutar una macro en cada línea de un archivo, intente: ¡% norma! @una.
Torre el
Sin los puntos (son solo los extremos de las oraciones, no forman parte de los comandos)
Rook
9999@apuede ser feo, pero es mucho más fácil escribir :%norm! @ay no se vuelve a ejecutar en la línea que acaba de editar. Todavía es bueno saberlo de todos modos. :)
joeytwiddle
0

Mi solución es usar estas 2 asignaciones:

map <leader>n <Esc><Esc>0qq
map <leader>m q:'<,'>-1normal!@q<CR><Down>

Cómo usarlos:

  1. Selecciona tus líneas. Si quiero seleccionar las siguientes 12 líneas, solo presionoV12j
  2. prensa <leader>n
  3. Haz tus cambios a la línea
  4. Asegúrese de estar en modo normal y luego presione <leader>m

Para realizar otra edición, no necesita hacer la selección nuevamente. Simplemente presione <leader>n, haga su edición y presione <leader>mpara aplicar.


Cómo funciona esto:

  • <Esc><Esc>0qq Salga de la selección visual, vaya al comienzo de la línea y comience a grabar una macro.

  • q Deja de grabar la macro.

  • :'<,'>-1normal!@q<CR> Desde el comienzo de la selección visual hasta la línea antes del final, reproduzca la macro en cada línea.

  • <Down> Regresa a la última línea.


También puede asignar la misma clave pero para diferentes modos:

vmap <leader>m <Esc><Esc>0qq
nmap <leader>m q:'<,'>-1normal!@q<CR><Down>

Aunque esto arruina tu habilidad para hacer otra edición. Tendrá que volver a seleccionar sus líneas.

willmcpherson2
fuente