Nota: este no es un duplicado de ¿Cómo funciona el comando "d3fg"? ¡Léalo antes de votar para cerrar!
Llegué a un punto muerto en mi búsqueda para que las pequeñas eliminaciones funcionen como las grandes . El problema que tengo es que no puedo entender cómo reasignar comandos como d3d. De hecho, ni siquiera puedo entender cómo funcionan en primer lugar, ni encontrar ninguna mención de ellos en la ayuda de Vim. *
d3jes sencillo: aplica el d
operador al 3j
movimiento,
3ddtambién es sencillo: ejecuta el dd
comando con un "conteo" de 3.
d3d parece que debería ser sencillo, aplica el d
operador a ... pero ¿qué es 3d
? No es una moción. Si escribe 3dsolo, Vim lo trata como un recuento seguido de un operador, y espera pacientemente por más información.
Y no puede aplicar operadores a otros operadores. ddno se describe en la ayuda como una secuencia de dos operadores. Es un comando separado de dos teclas. (cf. dc, que no hace nada)
Tampoco parece ser que el posicionamiento del conteo sea flexible para comandos que requieren dos pulsaciones de teclas: 2gjmueve el cursor hacia abajo dos líneas de pantalla, pero g2jdescarta las dos primeras pulsaciones de teclas por completo y mueve el cursor una línea hacia abajo.
¿Entonces, cómo funciona? ¿Es este un caso especial en el código interno de Vim? ¿Hay alguna forma de crear un d[count]d
mapeo?
EDITAR : ¿Es un objeto de texto? :h text-objects
no lo incluye en la lista de "comandos de selección de objetos de texto", pero sí incluye dd en una lista de eliminaciones "agrupadas de objetos pequeños a grandes". Y d2awborra la palabra debajo del cursor y la siguiente. Por otro lado, c2dno hace nada.
* Estoy seguro de que debe existir alguna mención de ellos, pero no puedo encontrarlo. He leído :help deleting
, :help motion.txt
y probado :helpgrep dNd
para todos los valores de N de 1-9 .
d
actúa como una confirmación; Entonces es lo mismo qued3<CR>
.y3y
yc3c
también funciona igual ... No puedo encontrar ningún documento sobre esto en Vim: help, vi (1), nvi (1) o la especificación POSIX ... Se comporta igual envi
y pornvi
cierto .dd
es idéntico ad_
._
lleva el cursor a la primera línea que no está en blanco en la ([count]
-1) línea hacia abajo, pero está en línea, por lo que cuando se combina con un operador, opera en líneas completas. Por esa razón, tiene sentido que pueda aparecer un recuento entre los dosd
s.Respuestas:
Modo pendiente de operador
Entre escribiendo un operador (como
d
,c
, ogU
) y un movimiento (comow
,i}
, o/foo<CR>
), Vim está en modo de operador-pendiente. Puede crear asignaciones para esto usando:omap
y:onoremap
.En mis ejemplos, voy a asignar el operador pendiente
d
aw
. Esta es una elección aleatoria, porque no sé para qué querías usarla.Crea un omap
Creemos una asignación para el
d
modo pendiente del operador. Asumiré que estamos escribiendo VimScript aquí (como en su.vimrc
), así que omitiré los:
s iniciales .Esto hace
dd
actuar comodw
. También haced[count]d
actuar comod[count]w
. Pero apuesto a que no quería afectar el comportamiento dedd
(es decir, no[count]
suministrado).Mapeos de expresiones
Las asignaciones de expresión le permiten evaluar una expresión de VimScript para producir el lado derecho de la asignación. La expresión debe evaluar a una cadena. Las asignaciones de expresiones se denotan por la
<expr>
palabra clave.Vim también tiene algunas variables integradas que se completan en varios momentos y, a menudo, son útiles durante las asignaciones. Uno de ellos es
v:count
, que se[count]
suministra a un operador o movimiento.Pongamos todo junto. Si no
[count]
se suministra,v:count
será0
. Podemos decirle a nuestro mapeo que solo used
en ese caso.Ahora se
dd
comporta como el predeterminado (elimina una línea), pero sed[count]d
comporta comod[count]w
. ¡Frio!Restrinja su uso después del
d
operadorSin embargo, es posible que notes algo. Ahora
cd
también se comporta comocw
. Esto puede no ser un problema, pero para completar, restringámoslo para que solo funcione después deld
operador.Vim tiene otra variable,
v:operator
que contiene el operador utilizado más recientemente. Vamos a ver eso también, antes de hacer algo especial.NOTA: Dado que los
:map
comandos se pueden encadenar|
, tenemos que escapar de ellos en nuestra expresión aquí. Entonces el operador lógico OR se||
convierte\|\|
.Fresco, así
cd
yc[count]d
han vuelto a hacer nada, al igual que lo hacían antes. Esto es bueno para que otros complementos puedan definircd
.No quiero simplemente borrar algún otro movimiento
Si desea asignar
d[count]d
algo totalmente diferente, nada que ver con la eliminación de texto, también podemos hacer que eso funcione.Cuando está escribiendo comandos en modo Normal, y comienza a escribir un comando por error, puede presionar
<Esc>
para cancelar ese comando. Lo mismo se aplica a sus asignaciones.Hagamos
d[count]d
cambiar la línea actual a lo que sea[count]
.La última parte de la asignación es una expresión Vimscript:
<Esc>cc' . v:count . '<Esc>'
. Eso es<Esc>
para cancelar eld
comando pendiente , luegocc
para cambiar la línea actual,v:count
escribir el valor de[count]
(en modo Insertar) y<Esc>
volver al modo Normal. Tenga en cuenta que estamos construyendo una cadena aquí usando el operador de concatenación Vimscript,.
.Su caso de uso real probablemente será diferente de lo que he esbozado aquí, pero espero que esto lo ayude a poner la pelota en marcha.
Feliz Vimming!
fuente
:omap d d
(!), Pero desafortunadamente el modo pendiente del operador nunca se alcanza debido a mi mapeo para d que establece la función de operador personalizada. Sin embargo, con suerte es posible ajustar las cosas para qued3d
funcione como debería. (Avíseme si tiene alguna idea, o siéntase libre de publicar una solución completa a la otra pregunta si lo prefiere). Si no puedo resolverlo pronto, aceptaré esto y publicaré otra pregunta más específica. ¡Gracias!