Usar cursor múltiple no es una cosa de Vimmer
Como dije en los comentarios, usar múltiples cursores (incluso con un complemento) no es realmente "seguir el camino de Vim", entiendo totalmente que es atractivo para alguien que viene de Sublime-Text, pero a menudo puedes encontrar alternativas que son al menos tan eficiente con las funciones integradas de Vim.
Por supuesto, encontrar estas soluciones alternativas no siempre es fácil y, a veces, lleva tiempo, pero será más fácil con su experiencia Vim y verá que con el tiempo múltiples cursores le parecerán totalmente inútiles.
Eso es genial, pero ¿cómo puedo encontrar una forma alternativa?
No hay una respuesta universal, ya que depende mucho de lo que intentes hacer, solo intentaré darte algunas pistas sobre lo primero que debes intentar:
El comando punto .
El comando Dot es probablemente una de las herramientas más poderosas en Vim, simplemente nos permite repetir el último cambio. No podría explicarlo mejor que Drew Neil en su Vim Práctico . Creo que todos los Vimmer deberían considerar leer este libro.
La fortaleza de este comando es que el último cambio puede ser una acción que funcione en un personaje, una línea o un archivo completo. Por ejemplo, un cambio puede delimitarse en el momento en que ingresa al modo de inserción y el momento en que regresa al modo normal.
Con eso en mente, es fácil hacer lo que quería hacer con el multicursor:
Primero configuremos nuestro entorno: escribamos como sugirió
\section[]{}
Luego haga un cambio repetible.
El cursor está ahora encendido }
, presione F[
para volver al [
personaje. Luego ingrese al modo de inserción con i
y escriba My first section in this book
y regrese al modo normal con ESC
:
\section[My first section in this book]{}
Y aquí viene la parte mágica: escriba f{
para colocar el cursor sobre el {
personaje y presione .
para repetir el último cambio:
\section[My first section in this book]{My first section in this book}
Todo el desafío del comando dot es aprender a hacer cambios repetibles: vendrá con grokking Vim, pero lo básico es entender cómo hacer su cambio de manera repetible.
Por ejemplo, para insertar un punto y coma al final de una línea, preferirá usar en
A;
lugar de $a;
. ¿Por qué?
Debido a que A;
crea una acción atómica, cuando la use .
en otra línea, sin importar dónde se encuentre en la línea, insertará el punto y coma al final. Mientras que cuando lo usa $a;
, divide su cambio en dos partes $a
y la inserción de ;
modo que si lo usa .
, insertará el punto y coma en la posición actual del cursor.
NOTA La fórmula mágica en Vim es n.
. Un flujo de trabajo realmente genial es:
- busca el lugar con el que deseas editar
/pattern
- haz tu edición repetible
- use
n
para ir al siguiente lugar para editar
- usar
.
para repetir la edición
- repite los dos últimos pasos: eres el rey del mundo (o al menos de las ediciones)
macros
Las macros son otra herramienta extremadamente importante en Vim, ya que le permite grabar una secuencia de pulsaciones de teclas y repetirla como si la hubiera vuelto a escribir.
Usaré, como ejemplo, su segundo caso de uso:
variable1 = 2
my_variable2 = 12
var3 = 14
Una vez más, lo importante es aprender cómo hacer que sus macros sean eficientes (daré un contraejemplo justo después):
Coloque el cursor sobre la palabra variable1
y comience a grabar su macro con
qq
. Esto significa "comenzar a grabar todas mis pulsaciones de teclas futuras en el registro denominado q
".
Comience a hacer su edición escribiendo:
0
ir al principio de la línea
e
ir al final de la primera palabra
a
para agregar después de su cursor
.someStuff
agregar el texto deseado
<Esc>
para detener la inserción
j
ir a la siguiente línea
q
para dejar de grabar la macro
Obtendrás:
variable1.someStuff = 2
my_variable2 = 12
var3 = 14
- Ahora puede usar la macro para repetir su edición. Como está en la línea correcta para editar, simplemente puede ejecutar la macro con
@q
. Como queremos ejecutarlo dos veces, puede usarlo 2@q
y obtendrá el siguiente resultado:
variable1.someStuff = 2
my_variable2.someStuff = 12
var3.someStuff = 14
NOTA 1 Como habrás notado, usar 0ea
al principio de la macro fue realmente importante. De hecho, si hubiera colocado el cursor al final de la primera palabra antes de grabar la macro y ejecutarla nuevamente, su resultado habría sido:
variable1.someStuff = 2
my_variable2 = 12.someStuff
var3 = 14.someStuff
Como su cursor, el texto se habría insertado en la posición del cursor después de cambiar de línea (es decir, el final de la línea en este caso)
NOTA 2 Las macros son extremadamente potentes e incluso puede crear macros recursivas cuando se sienta cómodo con ellas. Aquí su macro podría haber sido:
`0ea.someStuff<Esc>j@q`
La final @q
habría llamado a la macro por sí misma en lugar de usarla 2@q
; simplemente lo habrías usado @q
y todo el trabajo se habría hecho.
bloqueo visual
Aquí viene otro truco que no se aplica directamente a su caso de uso, pero puede ser realmente útil para editar una gran cantidad de líneas al mismo tiempo. Consigamos este extracto del código CSS:
li.one a{ background-image: url('/images/sprite.png'); }
li.two a{ background-image: url('/images/sprite.png'); }
li.three a{ background-image: url('/images/sprite.png'); }
¿Qué pasa si moviste los sprites de images
a components
?
Así se puede poner el cursor sobre el i
de images
y pulse <C-v>
. Esto iniciará el modo de bloque visual que permite seleccionar bloques. Ahora puede escribir t/
para seleccionar la palabra que desea cambiar y 2j
seleccionar todas las apariciones de la palabra.
Después de eso, simplemente tiene que escribir c
para cambiar la palabra y luego components
. Cuando salga del modo de inserción verá:
li.one a{ background-image: url('/components/sprite.png'); }
li.two a{ background-image: url('/components/sprite.png'); }
li.three a{ background-image: url('/components/sprite.png'); }
El comando global
El comando global es una herramienta que permite aplicar un comando en modo ex en líneas que coinciden con un patrón, una vez más, esa es una buena manera de aplicar el mismo cambio en un lugar diferente sin necesidad de múltiples cursores.
La sintaxis es la siguiente:
:[range] g / pattern / command
Para más detalles sobre el [range]
parámetro, consulte :h :range
. No lo detallaré aquí, simplemente recordaré que %
representa todo el archivo, '<,'>
representa la última selección y 1,5
representa las líneas 1 a 5 del archivo.
Este parámetro define las líneas que serán tratadas por el comando global. Si no se especifica ningún rango, el comando global se usará %
de manera predeterminada.
El argumento [patrón] es un patrón de búsqueda, ya que está acostumbrado a usarlo con el motor de búsqueda. Como integra el historial de búsqueda, puede dejar este campo en blanco y el comando global utilizará el último patrón de búsqueda en el historial de búsqueda.
Finalmente, el parámetro [comando] es un comando ex como probablemente esté acostumbrado.
Ahora el comportamiento del comando global es bastante simple:
- Iterar a través de todas las líneas definidas en el parámetro [rango]
- Si la línea actual coincide con el patrón definido, aplique el comando
Como el parámetro [comando] es un comando ex, puede hacer muchas cosas. Tomemos el siguiente pseudocódigo que no es muy interesante y tiene muchos mensajes de depuración:
var myList = null
var i = 0
myList = new List()
echo "List instantiated"
for (i=0; i<10; i++)
myList.Add(i)
echo i . " added to the list"
echo "end of for loop"
Ahora supongamos que está seguro de que este código funciona y desea eliminar estas echo
declaraciones inútiles :
Puede aplicar su comando global en todo el archivo, por lo que tendrá que anteponer el comando con %
(o sin nada, ya que %
es el rango predeterminado).
Sabes que las líneas que deseas eliminar coinciden con el patrón echo
Desea eliminar estas líneas, por lo que deberá usar el comando :delete
que también se puede abreviar comod
Entonces simplemente tendrá que usar la siguiente función:
:%global/echo/delete
Que también se puede abreviar como
:g/echo/d
Tenga en cuenta que %
desapareció, global
se abrevia como g
y delete
como d
. Como te puedes imaginar, el resultado es:
var myList = null
var i = 0
myList = new List()
for (i=0; i<10; i++)
myList.Add(i)
NOTA 1 Un punto importante que me llevó un tiempo darme cuenta es que el
normal
comando es un comando ex, lo que significa que puede usarlo con el comando global. Eso puede ser realmente poderoso: digamos que quiero duplicar todas las líneas que contienen eco, no necesito una macro o incluso la fórmula mágica n.
. Simplemente puedo usar
:g/echo/normal YP
Y voilá:
var myList = null
var i = 0
myList = new List()
echo "List instantiated"
echo "List instantiated"
for (i=0; i<10; i++)
myList.Add(i)
echo i . " added to the list"
echo i . " added to the list"
echo "end of for loop"
echo "end of for loop"
NOTA 2 "Oye, ¿qué pasa si quiero usar mi comando en líneas que no coinciden con un patrón específico?"
global
tiene un comando opuesto vglobal
abreviado v
que funciona exactamente igual, global
excepto que el comando se aplicará en líneas que no coinciden con el parámetro [patrón]. De esta manera si aplicamos
:v/echo/d
En nuestro ejemplo anterior obtenemos:
echo "List instantiated"
echo i . " added to the list"
echo "end of for loop"
El delete
comando se ha aplicado en líneas que no contenían echo
.
Aquí espero que esas pocas sugerencias le den ideas sobre cómo deshacerse de su complemento de cursor múltiple y usar Vim de la manera Vim ;-)
Como puede imaginar, estos ejemplos son bastante simples y solo están hechos para demostrar que cuando sigue la forma de Vim realmente rara vez necesita varios cursores. Mi consejo sería cuando encuentre una situación en la que piense que sería útil, escríbala y tómese un tiempo más tarde para encontrar una mejor solución. El 99% de las veces eventualmente encontrarás una forma más rápida / eficiente de hacerlo.
También me repetiré una vez más, pero realmente te animo a que leas
Practical Vim de Drew Neil porque este libro no trata sobre "Cómo hacer eso o esto en Vim" sino sobre "Cómo aprender a pensar a la manera de Vim" lo que le permitirá construir su propia solución a sus problemas futuros de una buena manera.
PD: Un agradecimiento especial a @Alex Stragies por su trabajo de edición y las correcciones que hizo a esta larga publicación.