¿Cómo puedo usar la finalización del modo de inserción en una macro?


11

Estoy tratando de definir una macro que genere rápidamente una lista de palabras aleatorias.
Quiero que la macro convierta esto en una lista como

a
b
c
d
e

dentro de esto

arezzo
bywords
czars
détente
eyrie

Lo que tengo hasta ahora:

  • poner el cursor en la letra a
  • comenzar a grabar macro qq
  • a ingrese al modo de inserción
  • <C-x><C-k> - perform dictionary completion on the character before cursor - in this case the lettera`
  • <C-p>seleccione el último elemento en la lista de finalización que aparece, en mi sistema es la palabra arezzo. (Nota: he longestincluido en mi 'completeopt'entorno, que es necesario para <C-p>trabajar de esta manera durante la finalización:) 'set completeopt=longest,menuone,preview'.
  • <C-y> aceptar la finalización
  • ^[^[ salir del modo de inserción
  • j pasar a la siguiente línea, listo para hacer la misma operación en la siguiente línea
  • q para de grabar

cuando creo la macro y sigo los pasos manualmente, todo funciona bien, sin embargo, cuando ejecuto la macro, veo un mensaje parpadeando en la línea de comando como:

escanear archivo de diccionario

y no sucede nada, solo jse ejecutan los comandos en la macro , es decir, el cursor se mueve hacia abajo de la línea, pero ninguno de los comandos de finalización se ejecuta.
¿Es posible usar las finalizaciones del modo de inserción en una macro, y si es así, cómo puedo hacerlo?


No entiendo su <C-p>paso ... cuando hago eso en mi vim, solo da el mensaje back at original, no selecciona el último elemento ... Usé la tecla de flecha hacia arriba dos veces para seleccionar la última palabra (mi caso azures), presioné enter y entonces Esc+j+q... luego funciona bastante bien en la ejecución de macro
Sundeep

1
@spasic ah buen punto, debería haber mencionado, pero estoy usando set completeopt=longest,menuone,previewsu longestopción que hace <C-p>que se inserte de inmediato. Si elimino longestde la completeoptcadena, obtengo el mismo comportamiento que usted. Además, sí, ¡las teclas de flecha funcionaron! gracias (olvidé que puedes usarlos para navegar por la lista de finalización)
the_velour_fog

Tal vez el menú emergente está interfiriendo. Tal vez intente :set completeopt=y a<c-x><c-k><esc>jcomo su macro.
Antony

@Antony No estoy seguro de por qué <Cp> no funcionaba, pero las flechas direccionales funcionaban.
the_velour_fog

Respuestas:


2

EDITAR : Realmente estás después de completar el diccionario; no necesariamente necesita el modo de inserción (modo Ctrl + X) para hacer esto. Como descubriste, hacer que trabajar con macros sea un verdadero dolor. El siguiente script se puede usar para completar el diccionario sin el modo de inserción, para que pueda repetirlo fácilmente dentro de una macro.

Agregue el código siguiente a su .vimrcarchivo, cierre y vuelva a abrir las ventanas vim para obtener la nueva función, y luego grabe presionando alternativamente <C-k>para completar y javanzar a la siguiente línea. Agregué un cheque para la longestopción y si está deshabilitada, selecciona una entrada aleatoria usando el tiempo aleatorio del sistema. Si encuentra la longestopción, busca manualmente la entrada más larga del diccionario y la inserta.

Si no le gusta el <C-k>mapeo, no dude en cambiarlo como mejor le parezca. Debería funcionar con cualquier mapeo que desee.

Además, el comando para devolver la expresión para el mapeo para evaluar agrega un \<esc>carácter al final para que dejemos el modo de inserción automáticamente después de cada inserción, y un 0cwfrente para ingresar al modo de inserción para comenzar y asegúrese de sobrescribir toda la palabra correctamente. Dependiendo del comportamiento exacto que desee (si sus palabras no están bien al bcwprincipio de cada línea), puede usar en su lugar para encontrar el comienzo real de la palabra. Sin embargo, verá algunas rarezas al volver a las palabras que comienzan la línea. Probablemente haya un comando más avanzado para ignorar el final de la línea y hacer ambas cosas a la vez, pero no pude encontrar una.

map <expr> <C-k> CompleteDictionary()
fun! CompleteDictionary()
    let cword = expand(“<cword>”)
    let res = []
    for m in readfile(&dictionary)
        if m =~ '^' . cword
            call add(res, m)
        endif
    endfor
    if &completeopt =~ 'longest'
        let max = 0
        let maxindex = 0
        let index = 0
        for item in res
            if strlen(item) > max
                let max = strlen(item)
                let maxindex = index
            endif
            let index = index + 1
        endfor
        return "0cw" . res[maxindex] . "\<esc>"
    else
        return "0cw" . res[system('@echo %RANDOM%') % len(res)] . "\<esc>"
    endif
endfun

Además, no sería difícil extender la lógica aquí para crear asignaciones alternativas (utilizando, por ejemplo, parámetros de función) que realicen cualquier función que proporcione el modo de inserción. Estaré encantado de ayudar con dichos requisitos y actualizar este script cuando tenga tiempo.


Esto suena como una explicación plausible del problema, pero probé las dos soluciones sugeridas, y ninguna pareció ayudar.
Rico

¿Probaste el sleepcomando también?
Tim

Sí, aunque solo con su valor sugerido de 5 segundos. ¿Has logrado que cualquiera de las soluciones funcione? ¿Podría publicar una lista completa de pasos?
Rico

No soy la persona que escribió la pregunta. Sin embargo, yo puedo reproducir el problema: hay que añadir más largo a completeoptcomo se describe en los comentarios (de nuevo, no por mí). edit : Vaya, 'longest'se requiere para el ctrl-ppaso: no ctrl-y. Aún así, los pasos descritos por el que hace las preguntas me funcionan vim -Nu NONEcon completeopteditado.
Rico

Creo que he encontrado una solución, deme unos minutos para actualizar mi respuesta con ella.
Tim
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.