Consejos para jugar golf en vim

32

Recientemente me di cuenta de cómo vim funciona muy bien para el golf, especialmente para . Además, de acuerdo con meta vim es un 'lenguaje de programación' perfectamente aceptable, al menos, para el alcance de este sitio, eso es.

¿Qué consejos generales tienes para jugar al golf en Vim? Estoy buscando ideas que se puedan aplicar a problemas de código de golf y que también sean al menos algo específicas para Vim (por ejemplo, "eliminar comentarios" no es una respuesta).

Por favor, publique un consejo por respuesta.

DJMcMayhem
fuente
44
Esta es una pregunta de consejos particularmente útil porque "Consejos para jugar golf en vim" y "Consejos para usar vim eficientemente como editor de texto" son básicamente lo mismo.
DLosc

Respuestas:

15

Tenga en cuenta las variantes en mayúsculas de los comandos comunes. Esto puede ahorrar trivialmente una pulsación de tecla en muchos contextos. Por ejemplo:

A = $a
C = c$
D = d$
I = ^i
S = cc
X = dh
Y = yy

¡Otro es usar en Glugar de gg, pero solo si usa un conteo! Por ejemplo, sin un conteo, se ggmueve al principio y se Gmueve al final. Sin embargo, con un recuento, ambos se mueven a la línea que especifique, por lo que 5Ges más corto pero equivalente a 5gg .

Otro, es usar Hen lugar de gg, pero es importante tener en cuenta que esto solo funciona si puede garantizar que cualquier entrada no ocupará más que el número predeterminado de filas (creo que es 24, pero puede variar).

DJMcMayhem
fuente
1
Si un desafío es el editor de golf específico (y, por lo tanto, generalmente se obtiene mediante pulsaciones de teclas), una letra mayúscula es también dos pulsaciones de teclas (también lo es $, al menos Cy Dahorraría algo).
Martin Ender
1
Algo que no tengo claro al anotar al presionar las teclas es si las letras consecutivas que requieren la tecla Mayús solo cuentan la tecla Mayús una vez por grupo, ya que podría (al menos para fines prácticos) mantenerla presionada mientras presiona las otras teclas.
Alex A.
66
@AlexA. Personalmente, creo que los modificadores no deberían contar. Tal vez necesitamos una meta publicación sobre esto ...
DJMcMayhem
Gy ggno son equivalentes El primero va al final del búfer y el segundo va al principio.
Jordania
@ Jordania Ese es un buen punto. Quise decir que son iguales cuando se cuenta, por ejemplo, 5Ges equivalente a 5gg. Agregaré más detalles sobre ese punto.
DJMcMayhem
11

Cada vez que falla un comando, emitirá un ruido ding, que cancelará la macro actual. Puede (ab) usar esto para crear una forma cruda de bucle. Por ejemplo, si desea repetir las pulsaciones de teclas <foobar>hasta que el búfer tenga menos de 3 líneas. Tu puedes hacer

qq<foobar>3G``@qq

lo que significa:

qq                 'Start recording in register q
  <foobar>         'Keystrokes
          3G       'Go to line 3. If line 3 doesn't exist, this is effectively a "break" statement.
            ``     'Jump back to previous cursor location
              @q   'Call macro q
                q  'Stop recording

Es importante tener en cuenta que si está probando esto en una sesión vim, @qpodría tener efectos secundarios no deseados, ya que las macros se cargan desde .vim_profile. Puede solucionar esto de dos maneras diferentes. Probablemente la mejor solución es lanzar vim con

vim -i NONE

También puedes eliminar tu .viminfo.

Si ya ha lanzado vim, puede escribir

qqq

al principio para poner a cero la macro.

Otras condiciones con las que puede reemplazar el 3G son

f<char>    'Jump to first occurence of <char>. Also see F, t and T

o

<number>|  'Go to the <number>'th character on the current line.
DJMcMayhem
fuente
8

Hay más versiones abreviadas de comandos ex que crees. Por ejemplo, probablemente ya sabía que :globalse puede acortar :g, pero ¿sabía que eso :nnoremapes equivalente a :nn?

Es una buena idea ejecutar :h :footodos los comandos ex que está utilizando en su respuesta para ver si hay una versión más corta.

Pomo de la puerta
fuente
6
:%s/\n//g

siempre es equivalente a

:%s/\n//

que también es equivalente a

:%s/\n

Sorpresivamente suficiente. (En general, sin ningún indicador, la última barra diagonal en una :sexpresión nunca es necesaria).

Pomo de la puerta
fuente
2
Esto funciona para la nueva línea, pero no funciona para ningún personaje que pueda aparecer más de una vez en una línea. Por ejemplo :%s/x, no elimina cada aparición de x, solo la primera en cada línea.
DJMcMayhem
1
También puede usar :&&para repetir un comando sustituto y sus banderas.
DJMcMayhem
6

Digamos que está en modo de inserción y desea hacer un solo comando de modo normal. Puedes escribir eso así:

isome_text<esc><foobar>gisome_more_text

No lo hagas así. En su lugar, use <C-o>, que ejecuta un solo comando normal y luego vuelve inmediatamente al modo de inserción.

isome_text<C-o><foobar>some_more_text
DJMcMayhem
fuente
Tampoco creo que esos espacios sean necesarios
Fund Monica's Lawsuit
@QPaysTaxes Tienes razón, no lo son. Pensé que lo haría más legible. Lo editaré.
DJMcMayhem
¿No necesita un <CR>después <foobar>para enviar el comando?
Financia la demanda de Mónica
@QPaysTaxes Solo si es un comando ex o una búsqueda. (Por ejemplo, cualquier comando que comience con a :, /o ?)
DJMcMayhem
Oh mi error. Confundí el comando y los modos normales. Genial: D
Financia la demanda de Mónica
5

Hay tres operadores de "cambio de caso",

gu    "Convert to lowercase
gU    "Convert to uppercase
g~    "Toggle case

Dado que estos son operadores, toman un movimiento, por lo que para convertir el carácter actual en minúsculas usaría

gul

Aquí es donde entra el truco divertido. :) Si desea cambiar el caso de un solo personaje o la línea actual, es un byte más corto en modo visual. Por ejemplo gules equivalente a

vu

Y gu_(_ es la línea actual) es equivalente a

Vu

Este truco no funciona para alternar, ya que v?desencadena una búsqueda hacia atrás en modo visual, (como v/si se moviera en la dirección opuesta), por lo que necesita en su vg?lugar. Sin embargo, aquí es donde puede usar el~ operador para guardar aún más bytes! (Gracias @Doorknob por señalar esto)

Puedes ver este truco en acción en mi respuesta vim aquí , y en la respuesta V equivalente en la publicación.

DJMcMayhem
fuente
1
¡No lo olvides ~, lo que alterna el caso del personaje debajo del cursor y mueve uno hacia la derecha!
Pomo de la puerta
5

El alfabeto en 10 pulsaciones de teclas

Todo el crédito por esta técnica es para Lynn, quien la utilizó por primera vez en esta respuesta . Lo escribo aquí para la posteridad.

Use las siguientes diez teclas para tirar del alfabeto en minúsculas:

:h<_␍jjYZZ

(Dónde hay un retorno de carro, es decir, la tecla Intro).

Explicación

:h<_␍abre la sección de ayuda v_b_<_example(un ejemplo de selección visual en bloque), que contiene el texto abcdefghijklmnopqrstuvwyxz. jjYbaja a esa línea y tira de ella, luego ZZcierra la ventana de ayuda.

Jordan
fuente
4

Conoce tus registros

Yankear o eliminar texto en un registro específico (p "aY. Ej. ) Para usarlo más tarde no siempre es necesario. Vim tiene varios registros que se rellenan automáticamente con los sujetos de varios comandos. Escriba :help registerspara verlos todos, pero aquí hay algunos de particular interés:

  • Registro sin nombre: ""- El último texto que fue eliminado o eliminado.

  • Registro numerado "0: el último texto que se tiró.

  • Registros numerados "1- "9- El último texto que se eliminó a menos que fuera menos de una línea. Cada vez que "1se llena, sus contenidos anteriores se desplazan "2y así sucesivamente.

  • Pequeño registro de eliminación: "-- El último texto más corto que una línea que se eliminó.

  • Último texto insertado: ".

En particular, los registros "-y "1pueden ser útiles juntos, permitiéndole borrar un texto con, por ejemplo, dden el "1registro y borrar otro texto con Del "-(por supuesto, la semántica no es idéntica, pero a menudo no es necesario que sea )

Todos los registros pueden ser un poco difíciles de controlar, pero puede ver el contenido de todos sus registros en cualquier momento escribiendo :registers.

Jordán
fuente
3

Esto surgió en el chat antes, así que pensé que podría publicarlo como un consejo completo.

<C-a>e <C-x>incrementa y disminuye el siguiente número en la línea. Esta es una característica extremadamente útil para algunas matemáticas simples, pero también permite un pequeño truco ordenado.

Digamos que necesitas saltar al siguiente número. Por ejemplo, necesitamos cambiar

I need 2 spell better

a

I need to spell better

La forma obvia es saltar al 2, luego hacer:

sto                "Synonymous with 'clto'

Como esto es más corto que

:s/2/to<cr>

Hay muchas formas diferentes de saltar al 2. Por ejemplo,

/2<cr>
ww 
2w
ee
2e
8|
f2

Así como muchas otras formas.

Estas son todas 2 (o más) pulsaciones de teclas. Sin embargo, puesto <C-a>y <C-x>no sólo los números de aumento / disminución, sino también saltar al siguiente número, podemos tomar un byte con

<C-a>sto
DJMcMayhem
fuente
3

Movimientos golfistas

Con frecuencia, si está trabajando con un bloque de texto (especialmente en desafíos de ), deberá pasar al primer o último carácter en el búfer. Gy ggson bastante buenos, pero hay algunas cosas molestas. Por ejemplo, para obtener el último carácter, necesita G$y ggno necesariamente lo colocará en la primera columna si hay espacios en blanco iniciales. Aquí hay algunos movimientos más agradables, aunque tenga en cuenta que solo funcionan si su texto no tiene líneas vacías en el medio:

  • Primer carácter del búfer: {es mejor que gg0. Si hay líneas vacías en el medio del texto, también puede usar lo goque lo lleva al primer carácter en el búfer sin importar qué.

  • Último carácter del búfer: }es mejor queG$

¡Estos también funcionan como argumento para un operador, pero tenga en cuenta que son movimientos de carácter inteligente, no movimientos de línea inteligente!

DJMcMayhem
fuente
Hes más golfista quegg
Kritixi Lithos
@KritixiLithos, excepto que Hno es confiable. Su comportamiento depende del tamaño de la ventana visible y de dónde se encuentre en el búfer. (Se reasigna en V para evitar esta confusión)
DJMcMayhem
2

Hacer cálculos con el registro de expresión

Puede hacer cálculos tanto en modo normal como en modo inserción.

Modo normal

En modo normal, si escribe @=su cursor se moverá a la línea de comando, donde puede ingresar cualquier expresión. Cuando presiona Intro, el resultado de la expresión se ejecutará como comandos de modo normal.

Por ejemplo, suponga que desea ir a la columna central de la línea actual. La llamada a la función col('$')devuelve el número de columnas en la línea, por lo que podemos lograrlo escribiendo lo siguiente:

@=col('$')/2<CR>|

Cuando presiona enter, el cursor vuelve al búfer y vim espera a un operador (como |) como si acabara de ingresar un número. Alternativamente, podría haber ingresado esto:

@=col('$')/2.'|'

... pero por supuesto eso es más bytes.

Modo de inserción

También puede usar el registro de expresión en modo de inserción presionando en <Ctrl-r>=lugar de @=. Funciona igual en modo normal, excepto que el resultado de la expresión que ingrese se ejecutará en modo de inserción. Por ejemplo, si escribiste<Ctrl-r>=col('$')<CR> , el número de columnas en la línea actual se insertaría en el cursor como si lo hubiera escrito.

Para obtener más información sobre el registro de expresiones, escriba :help "=.

Reutilizando expresiones

La última expresión que utilizó se almacena en el registro de la expresión, "=. Escribir @=<CR>en modo normal o <Ctrl-r>=<CR>en modo de inserción evaluará la expresión nuevamente, permitiéndole usarlos de manera muy parecida a las macros.

Hacer cálculos en sustituciones

También puede evaluar expresiones al hacer sustituciones de expresiones regulares. Todo lo que tiene que hacer es comenzar su sustitución con \=. Por ejemplo, suponga que desea numerar las líneas en este archivo:

foo
bar
baz

La llamada a la función line('.')devuelve el número de línea actual, por lo que el trabajo es fácil. Ingresando esto:

:s/^/\=line('.').' '/g<CR>

... produce el resultado deseado:

1 foo
2 bar
3 baz

Para usar grupos capturados en tal expresión, puede usar la submatch()función, donde, por ejemplo, submatch(0)es equivalente a \0una sustitución ordinaria, submatch(1)es equivalente a \1, etc. Esto, desafortunadamente, consume muchas teclas.

Para obtener más información sobre la sustitución de expresiones, escriba :help sub-replace-expression.

Jordán
fuente
Para su último ejemplo hay formas más cortas. Por ejemplo, i1 <esc>bqqywjPb<C-a>@qq@qes una solución de modo normal puro que es 5 bytes más corta. Y si estás en Unix, incluso podrías hacerlo :%!nl. Aún así buenos consejos!
DJMcMayhem
1
Mi objetivo era demostrar cómo usar la función, no cómo numerar líneas con la menor cantidad de teclas.
Jordania
1

Puede modificar directamente el texto de una macro, que puede ser significativamente más corto que un condicional enrevesado. Por ejemplo, supongamos que desea pegar algo n veces, donde n es la entrada del usuario. Primero intenté hacer esto:

qq/[1-9]<enter><c-x>``p@qq@q

Explicación:

qq                             #Start Recording
  /[1-9]<enter>                #Search for a number that isn't 0.
                <c-x>          #Decrement that number
                     ``p       #jump back to your previous location and paste.
                        @q     #Recursive call to macro 'q'
                          q@q  #Stop recording, and run the macro

Esto es 18 pulsaciones de teclas, y una forma realmente fea de hacerlo. En su lugar, vaya a la ubicación de ese número y haga esto:

Ap<esc>"qdd@q

Explicación:

Ap<esc>                 #Append a 'p' to the end of the current line.
       "qdd             #Delete the current line into register q
           @q           #Run macro q.

Esto es 9 pulsaciones de teclas, una gran mejora.

Editar:

Aún más corto es ejecutar la macro para su número y luego escribir su comando. Por ejemplo:

"qdd@qp

Explicación:

"qdd         #Delete the current line into register q
    @q       #Run register q
      p      #Paste

7 pulsaciones de teclas.

DJMcMayhem
fuente
1
1. Uso D, no dd. 2. Si el comando no involucra registros, puede hacerlo aún más corto. Por ejemplo, si desea repetir el carácter xtantas veces como el número debajo del cursor, en lugar de "qD@qix<esc>, use D@"ix<esc>.
Pomo de la puerta