¿Es posible hacer que una tecla de acceso rápido con prefijo numérico ejecute una función tantas veces?


7

Me parece que si ingresa un prefijo numérico antes de ejecutar un comando ex, la convención que aplica es configurar el comando para preparar una operación en un rango de línea. Se explica en la documentación,

UN NÚMERO DE LÍNEAS

Cuando sepa cuántas líneas desea cambiar, puede escribir el número y luego ":". Por ejemplo, cuando escribe "5:", obtendrá:

    :.,.+4

Ahora puede escribir el comando que desea usar. Utilizará el rango "." (línea actual) hasta ". + 4" (cuatro líneas hacia abajo). Por lo tanto, abarca cinco líneas.

Ahora lo que estoy tratando es una función personalizada mía, esta:

function! MyAmazingEnhancedDot()
    if v:hlsearch == 1
        :normal! .n
    else
        :normal! .j
    endif
endfun

Esta es solo una forma de simplificar las tareas repetitivas que incluyen repetir una operación en un rango de líneas o en una serie de coincidencias de búsqueda.

Esta función está vinculada a una tecla de acceso rápido. Tales como Alt+ .o lo que sea.

Mi objetivo es poder hacer algo muy poderoso: debería ser capaz de escribir /varName<CR>ciwnew-var<ESC>n9<Alt+.>para renombrar 10 instancias de varNameto new-var.

Lo que realmente sucede si hago esto es que no realiza el cambio de nombre y las 9 líneas se manipulan con mi .operación de edición guardada desde la columna 0.

Sólo puedo suponer que Vim está interpretando mis pulsaciones de teclado así: :.,.+8 normal! .n.

En el lado del vaso medio lleno, el :normal! .jcaso del enlace realmente funciona, porque el jmovimiento que no tiene efecto no tiene ninguna consecuencia en esta situación. (Todavía necesito el jpara que funcione en un caso de uso interactivo sin prefijo numérico).

Entonces, mi pregunta es ¿cómo puedo anular el comportamiento de expansión de línea que Vim aplica a mi enlace? Lo que sería fantástico es si puedo leer el prefijo numérico como argumento o algo así.

Respuestas:


6

Por defecto, vim trata todas las funciones como si fueran comandos ex predeterminados, es decir, cualquier número prefijado se usa como {range}. Para cambiar esto, necesita modificar su función y su mapa para usar un conteo.

Mapa con conteo

Los mapas pueden contar y están disponibles a través de v:county v:count1. El primero contiene 0 si no se proporciona ningún recuento y el segundo contiene 1 como valor predeterminado. Puede crear un mapa para su función:

nnoremap <M-.> :<C-u>call MyAmazingEnhancedDot(v:count1)<cr>

Para más información :h v:count

Comandos con conteo

Los comandos pueden tener la opción de a {range}o a countcomo prefijo. Al crear el comando, el indicador -countdeshabilita la opción de rango y la <count>variable por defecto es 0. Opcionalmente, se puede proporcionar un valor predeterminado -count=N. El valor del prefijo está disponible a través de la variable counten su función.

Un comando usando count se vería así:

:command -count=1 EDot call MyAmazingEnhancedDot(<count>)

Ahora cuando llama a 9EDotsu función se llama con el recuento de en 9lugar de un rango.

Para más información ver :h command-count

Ambos ejemplos

Aquí está tu código:

function MyAmazingEnhancedDot(count)
  let c = a:count
  while c > 0
    if v:hlsearch == 1
      :normal! .n
    else
      :normal! .j
    endif
    let c -= 1
  endwhile
endfunction

command -count=1 EDot call MyAmazingEnhancedDot(<count>)

nnoremap <M-.> :<C-u>exe v:count1 . "EDot"<CR>

Ahora puedes hacer tu ejemplo

/varName<CR>ciwvar-name<esc>n9<M-.>

1
Frio. Ahora parece que hay también muchas maneras de resolver mi problema! Entiendo que combinaste ambos mecanismos en el ejemplo que diste para ilustrar cómo usarlos. Pero me pregunto si no es suficiente usar nnoremap <M-.> :<C-u>call MyAmazingEnhancedDot(v:count1)<cr>y omitir el command -count=1 EDot call MyAmazingEnhancedDot(<count>)?
Steven Lu

Omitir la opción de comando está bien. El único beneficio que obtiene de la opción de comando es poder llamarlo desde comandos ex como :9EDot. Si no usa mucho los comandos ex, omítalo.
jecxjo

Increíble. ¡Ahora tu respuesta perfecta está completa!
Steven Lu
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.