Come posso utilizzare il completamento della modalità di inserimento in una macro?


11

Sto cercando di definire una macro che genera rapidamente un elenco di parole a caso.
Voglio che la macro lo trasformi in un elenco come

a
b
c
d
e

in questo

arezzo
bywords
czars
détente
eyrie

Quello che ho finora:

  • posiziona il cursore sulla lettera a
  • inizia a registrare macro qq
  • a entra in modalità inserimento
  • <C-x><C-k> - perform dictionary completion on the character before cursor - in this case the lettera`
  • <C-p>seleziona l'ultimo elemento nell'elenco di completamento che appare, sul mio sistema è la parola arezzo. (NB Ho longestincluso nella mia 'completeopt'impostazione, che è necessario per <C-p>funzionare in questo modo durante il completamento:) 'set completeopt=longest,menuone,preview'.
  • <C-y> accetta il completamento
  • ^[^[ uscire dalla modalità di inserimento
  • j passa alla riga successiva, pronto per eseguire la stessa operazione sulla riga successiva
  • q interrompere la registrazione

quando creo la macro e eseguo i passaggi manualmente, tutto funziona bene, tuttavia quando eseguo la macro, vedo un messaggio lampeggiante nella riga di comando qualcosa del tipo:

scansione del file del dizionario

e non accade nulla, solo i comandi nella macro jvengono eseguiti, ovvero il cursore si sposta lungo la linea, ma nessuno dei comandi di completamento viene eseguito.
È possibile utilizzare i completamenti della modalità di inserimento in una macro e, in tal caso, come posso farlo?


Non capisco il tuo <C-p>passaggio ... quando lo faccio a mio modo di vedere, mi dà solo il messaggio back at original- non seleziona l'ultimo elemento .. Ho usato due volte il tasto freccia per selezionare l'ultima parola (il mio caso azures), ho premuto Invio e allora Esc+j+q.. allora funziona abbastanza bene sull'esecuzione di macro
Sundeep

1
@spasic ah buon punto, avrei dovuto menzionarlo, ma sto usando la set completeopt=longest,menuone,previewsua longestopzione che causa <C-p>l'inserimento immediato. Se rimuovo longestdalla completeoptstringa, ottengo lo stesso comportamento di te. Inoltre, sì, i tasti freccia hanno funzionato! grazie (ho dimenticato che puoi usarli per navigare nell'elenco di completamento)
the_velour_fog

Forse il menu popup sta interferendo. Magari prova :set completeopt=e a<c-x><c-k><esc>jcome macro.
Antony,

@Antony Non sono sicuro del motivo per cui <Cp> non funzionava, ma i tasti freccia direzionali funzionavano.
the_velour_fog

Risposte:


2

EDIT : Davvero sei dopo il completamento del dizionario; non è necessario necessariamente inserire la modalità (Ctrl + X) per farlo. Come hai scoperto, lavorare con le macro è un vero dolore. Lo script seguente può essere utilizzato per completare il dizionario senza la modalità di inserimento, in modo da poterlo ripetere facilmente all'interno di una macro.

Aggiungi il codice qui sotto al tuo .vimrcfile, chiudi e riapri le finestre di vim <C-k>per creare la nuova funzione, quindi registra te stesso alternativamente premendo per completare e jpassare alla riga successiva. Ho aggiunto un segno di spunta per l' longestopzione e se è disabilitata, seleziona una voce casuale usando il tempo casuale del sistema. Se trova l' longestopzione, cerca manualmente la voce di corrispondenza più lunga dal dizionario e la inserisce.

Se non ti piace la <C-k>mappatura, sentiti libero di cambiarla come ritieni opportuno. Dovrebbe funzionare con qualsiasi mappatura ti piaccia.

Inoltre, il comando per restituire l'espressione per la mappatura da valutare aggiunge un \<esc>carattere alla fine in modo da lasciare automaticamente la modalità di inserimento dopo ogni inserimento, e un 0cwin primo piano per entrare nella modalità di inserimento per iniziare e assicurarsi di sovrascrivere l'intera parola correttamente. A seconda del comportamento esatto che desideri (se le tue parole non sono ben posizionate all'inizio di ogni riga) puoi bcwinvece utilizzare per trovare la parola iniziale effettiva. Tuttavia, vedrai alcune stranezze quando torni alle parole che iniziano la linea. Probabilmente c'è un comando più avanzato per ignorare la fine della linea e fare entrambe le cose contemporaneamente, ma non sono riuscito a trovarne uno.

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

Inoltre, non sarebbe difficile estendere la logica qui per creare mappature alternative (utilizzando, ad esempio, parametri di funzione) che eseguono qualsiasi funzione fornita dalla modalità di inserimento. Sarò felice di aiutarvi con tali requisiti e aggiornare questo script come ho tempo.


Sembra una spiegazione plausibile del problema, ma ho provato entrambe le soluzioni suggerite e nessuna delle due sembrava aiutare.
Ricco

Hai provato anche il sleepcomando?
Tim

Sì, anche se solo con il valore suggerito di 5 secondi. Sei riuscito a far funzionare entrambe le soluzioni? Potresti pubblicare un elenco completo di passaggi?
Ricco

Non sono la persona che ha scritto la domanda. Comunque, io posso riprodurre il problema: è necessario aggiungere più lunga di completeoptquanto descritto nei commenti (di nuovo, non da me). modifica : Oops, 'longest'è richiesto per il ctrl-ppassaggio: no ctrl-y. Tuttavia i passaggi descritti dall'interrogatorio funzionano per me vim -Nu NONEcon la completeoptmodifica.
Ricco

Penso di aver trovato una soluzione, dammi qualche minuto per aggiornare la mia risposta con essa.
Tim
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.