VIM: este no es solo un editor, es una integración con todo su entorno de trabajo

¿Por qué es Vim / Neovim particularmente bueno? El hecho de que su kit de herramientas no es solo un editor (que en sí mismo es muy extensible con complementos y tiene una funcionalidad básica rica y es muy flexible en el campo de la personalización), sino también todo su entorno de trabajo , con todo el kit de herramientas unix-way incluido de gnu / coreutils y no solo Puede tomar cualquier programa o intérprete sin salir del editor y usarlo directamente en el editor.


Prólogo


Esta publicación fue escrita a toda prisa para un círculo privado de personas, pero decidí que es muy posible publicarla en Habr. Para algunos, puede convertirse en una inspiración, alguien ayudará a comprender mejor la filosofía de Vim, y alguien tomará un par de trucos para sí mismo. Por si acaso, haré una reserva de que no debería esperar que empiece a demostrarle algo a alguien en los comentarios, por ejemplo, para convencerte de que definitivamente debes renunciar a tu IDE gordo y comenzar a usar Vim, no estoy nada interesado en esto.


A los negocios


Aquí, por ejemplo, tome un fragmento de código (de la configuración del proyecto Haskell), una lista de dependencias de paquetes (ejemplo en el vacío):


build-depends: X11 , base , directory , extra , GLFW-b , safe , aeson , containers , data-default , text , process , time , dbus 

Que queremos


  1. Ordenar dependencias alfabéticamente
  2. Ordenar sin distinción entre mayúsculas y minúsculas ( X11 y GLFW-b no deberían ir por encima de todo)
  3. Restaurar comas ( aeson irá a la parte superior y ya no debería tener una coma a la izquierda, pero X11 debería tener una coma a la izquierda)
  4. Restaure la sangría (para que también pueda obtener el comando del historial y reutilizarlo en otra configuración con un nivel de anidamiento diferente, o incluso vincular el comando de teclas de acceso rápido en la configuración de Vim)

Solución


En primer lugar, seleccione (mediante resaltado visual) la lista de dependencias, excepto la primera línea de build-depends . Por supuesto, puede presionar V (modo visual con selección línea por línea) y seleccionar las líneas necesarias a través de jk o flechas arriba y abajo. En mi caso, hago esto con un movimiento de mi mano usando una tecla de acceso rápido personalizada para el modo visual:


 xn iz <esc>[zV]z 

Por ejemplo, al estar en el medio de la lista de dependencias, solo presiono viz y todas las dependencias se resaltan, porque se resalta todo el pliegue, que a su vez es el bloque de anidamiento actual (ya que he definido el foldmethod como indent ). Pero también puede escribir manualmente [zV]z secuencialmente sin una tecla de [zV]z rápido personalizada ( [z salta al principio del pliegue, a ]z al final), pero dado que para mí, tal operación se usa a menudo, luego la acorté a la vista: no hay modificadores como un cambio y se comprime en los reflejos en un instante (el análogo estándar más cercano es vip para seleccionar un bloque a las líneas vacías más cercanas).


Luego presione : (dos puntos) para ingresar al modo de comando para ejecutar un comando relativo al resaltado visual actual. De hecho, el modo de comando habitual, pero con marcadores de selección añadidos inmediatamente, es decir se verá así :'<,'> donde '<,'> es el rango de selección, donde '< es la primera línea de la selección visual y '> es la última.


Después de hacer clic ! (signo de exclamación) en el teclado, esto significará que todo lo que va más allá es un comando shell / bash (según la configuración). Se verá así :'<,'>! . De hecho, después de resaltar, puede hacer clic inmediatamente ! y obtenga el mismo resultado - :'<,'>! .


Esta operación redirigirá las líneas resaltadas al comando STDIN y reemplazará las líneas resaltadas con el escape STDOUT de este comando. Por ejemplo, puede usar el comando de sort , solo para verificación, el resultado no es lo que necesitamos - '<,'>!sort y presionar Enter , obtenemos:


  build-depends: , aeson , base , containers , data-default , dbus , directory , extra , GLFW-b , process , safe , text , time X11 

Moda con coreutils y torre general


Restaure la selección anterior (puede presionar gv para restaurar la última selección) y presione ! y luego la flecha hacia arriba: esto restaurará el último comando del historial, por lo que no necesitamos volver a escribir, simplemente extraemos el comando anterior del historial y lo cambiamos. Para una edición más cómoda del comando, puede presionar Ctrl + f ; esto abrirá más. una ventana con edición estándar normal del comando, con todas las capacidades de Vim, por cierto, todos los equipos anteriores del historial serán visibles allí como líneas separadas, que también se pueden seleccionar, editar y ejecutar.


Qué es lo correcto: puede pensar en un hallazgo, mi punto es este: primero eliminamos las comas, las ordenamos sin ellas (sin distinción entre mayúsculas y minúsculas), luego devolvemos las comas, excepto la primera línea.


Primero, elimine las comas (y la primera línea tiene una sangría adicional para que todas las líneas tengan la misma sangría) usando el comando sed con una expresión regular ( [, ] - una coma o espacio, y luego otro espacio, \(\w\) escapó corchetes para resaltar bloque para la sustitución, para que luego esté disponible como \1 , \w es el primer carácter alfabético, en el reemplazo restauraremos el carácter alfabético sustituyendo \1 ):


 :'<,'>!sed 's/[, ] \(\w\)/\1/' 

Obtenemos lo siguiente:


  build-depends: X11 base directory extra GLFW-b safe aeson containers data-default text process time dbus 

A continuación, canalizamos (a través del símbolo | es una característica de bash) al comando de ordenación de sort pasa el -f por insensibilidad a mayúsculas y minúsculas:


 :'<,'>!sed 's/[, ] \(\w\)/\1/' | sort -f 

Obtenemos:


  build-depends: aeson base containers data-default dbus directory extra GLFW-b process safe text time X11 

Casi hecho! Solo queda agregar comas y la primera línea: un par de espacios. Usaremos el mismo sed , en la sintaxis de sus operaciones puede especificar cadenas y rangos de cadenas (como en Vim, la sintaxis es la misma, bueno o casi la misma). El prefijo 1 significará la primera línea, 2,$ significa el rango desde la segunda línea hasta el final ( $ , como ^ significa el comienzo del archivo, por analogía con los mismos caracteres en expresiones regulares que significan el final y el comienzo de la línea). Usaremos \w para omitir la sangría e inmediatamente seleccionaremos el primer carácter alfabético: 1s/\w/ &/ - aquí hacemos un reemplazo para la primera línea, restauramos el primer carácter alfabético a través de & (similar a \1 , solo & significa todo debajo de la expresión regular completa, mientras que \1 significa el primer bloque envuelto entre paréntesis), agregando un par de espacios delante de él. Para las líneas restantes, en lugar de dos espacios, agregue una coma + espacio seguido de: 2,$s/\w/, &/ , todo el comando será así: sed -e '1s/\w/ &/' -e '2,$s/\w/, &/' , - -e utilizamos para separar 2 operaciones entre sí. En Vim, toda la operación se verá así:


 :'<,'>!sed 's/[, ] \([^, ]\)/\1/' | sort -f | sed -e '1s/\w/ &/' -e '2,$s/\w/, &/' 

Aplicamos y obtenemos:


  build-depends: aeson , base , containers , data-default , dbus , directory , extra , GLFW-b , process , safe , text , time , X11 

Hecho No necesita escribirlo por segunda vez, solo escriba los primeros caracteres, por ejemplo: :'<,'>!se (de hecho, solo necesita presionar !se ), y use la flecha hacia arriba para obtener el comando deseado del historial. De una forma u otra, a menudo recomiendo practicar escribir tales cosas de inmediato . Por lo tanto, ambos bombearán sus habilidades laborales diarias en bash y en Vim, como esencialmente estás haciendo lo mismo.


Al final, todo este comando puede asignarse a una tecla de acceso rápido, o abstraerse en una función, y reutilizarse en todas partes para uno o dos.


Utilizando PL de terceros


En lugar de lanzar algo desde coreutils, puede ejecutar el intérprete de algún tipo de lenguaje que sea conveniente para usted, me gusta hacer esas cosas a través de Perl6 (recientemente fue renombrado a Raku ):


 :'<,'>!perl6 -e 'my @x=lines.map(*.subst(/<[,\s]>\s(\w)/,{$0})).sort(*.lc); @x.shift.subst(/\w/,{q/ /~$_}).say; .subst(/\w/,{q/, /~$_}).say for @x' 

Sí, al menos en el zoskoscript (node.js):


 :'<,'>!node -e 'let fs=require("fs"), x=fs.readFileSync(process.stdin.fd).toString().replace(/\n$/,'').split(/\n/).map(x=>x.replace(/[, ] (\w)/,"$1")).sort((a,b)=>a.toLowerCase().localeCompare(b.toLowerCase())); console.log(x.shift().replace(/(\w)/," $1")); process.stdout.write(x.map(x=>x.replace(/(\w)/,", $1")).join("\n"))' 

Esto también se puede hacer en VimL / Vimscript dentro de Vim, sin llamar a comandos externos. Pero esta publicación no se trata de eso.


Naturalmente, como habrás adivinado, puedes guardar fácilmente tu script en un archivo separado, o incluso compilar tu propio programa que toma algo para ingresar a STDIN y genera algo procesado en STDOUT y usarlo en Vim simplemente llamando (que , de nuevo, se puede asignar a una tecla de acceso rápido):


 :'<,'>!~/my-program-or-script 

Por lo tanto, cuando escribe código en Vim, no solo Vim está a su disposición, sino también todo su entorno de trabajo.


Uno de los ejemplos más simples es rechazar un archivo JSON:


 :%!jq 

Solo unas pocas pulsaciones de teclas, ¿por qué reinventar el analizador AST y el prettifayer para JSON para cualquier nuevo editor / IDE / lo que sea, cuando puede tomar y ejecutar un archivo a través de jq sin salir de Vim? No estoy hablando del hecho de que a través de jq puede procesar su gran archivo JSON sin salir de Vim, encontrar, por ejemplo, la clave deseada en el árbol, ordenar, dejar solo los datos necesarios, etc.

Source: https://habr.com/ru/post/483580/


All Articles