Jak mogę używać uzupełniania trybu wstawiania w makrze?

11

Próbuję zdefiniować makro, które szybko generuje listę losowych słów.
Chcę, aby makro przekształciło to w taką listę

a
b
c
d
e

zaangażowany w to

arezzo
bywords
czars
détente
eyrie

Co mam do tej pory:

  • umieść kursor na literze a
  • rozpocznij rejestrowanie makra qq
  • a wejdź w tryb wstawiania
  • <C-x><C-k> - perform dictionary completion on the character before cursor - in this case the lettera`
  • <C-p>wybierz ostatni element z wyświetlonej listy ukończeń, w moim systemie jest to słowo arezzo. (Uwaga: longestUwzględniłem w swoim 'completeopt'ustawieniu, które jest wymagane <C-p>do pracy w ten sposób podczas ukończenia:) 'set completeopt=longest,menuone,preview'.
  • <C-y> zaakceptować zakończenie
  • ^[^[ wyjdź z trybu wstawiania
  • j przejdź w dół do następnej linii, gotowy do wykonania tej samej operacji w następnej linii
  • q Zatrzymaj nagrywanie

kiedy tworzę makro i wykonuję kroki ręcznie, wszystko działa dobrze, jednak kiedy wykonuję makro, widzę komunikat migający w linii poleceń coś takiego:

skanowanie pliku słownika

i nic się nie dzieje, polecenia jsą uruchamiane tylko w makrze , tzn. kursor przesuwa się w dół linii, ale nie uruchamia się żadne polecenie zakończenia.
Czy można używać uzupełnień w trybie wstawiania w makrze, a jeśli tak, to jak to zrobić?

the_velour_fog
źródło
Nie rozumiem twojego <C-p>kroku ... kiedy to robię w moim vimie, to po prostu daje komunikat back at original- nie wybiera ostatniego elementu. Użyłem dwa razy klawisza strzałki w górę, aby wybrać ostatnie słowo (moja sprawa azures), nacisnąłem enter i potem Esc+j+q.. to działa całkiem dobrze na uruchamianiu makr
Sundeep
1
@spasic ah dobra uwaga, powinienem wspomnieć, ale używam set completeopt=longest,menuone,previewjej longestopcji, która powoduje <C-p>natychmiastowe wstawienie. Jeśli usunę longestz completeoptłańcucha, otrzymam takie samo zachowanie jak ty. Także tak, klawisze strzałek działały! dzięki (zapomniałem, że można ich użyć do poruszania się po liście ukończenia)
the_velour_fog
Może menu podręczne przeszkadza. Może spróbuj :set completeopt=i a<c-x><c-k><esc>jjako makro.
Antony
@Antony Nie jestem pewien, dlaczego <Cp> nie działał, ale klawisze strzałek kierunkowych działały.
the_velour_fog

Odpowiedzi:

2

EDYCJA : Naprawdę jesteś po zakończeniu słownika; aby to zrobić, niekoniecznie potrzebujesz trybu wstawiania (tryb Ctrl + X). Jak odkryłeś, praca z makrami sprawia prawdziwy ból. Poniższego skryptu można użyć do wykonania uzupełniania słownika bez trybu wstawiania, dzięki czemu można łatwo powtórzyć go w makrze.

Dodaj poniższy kod do .vimrcpliku, zamknij i ponownie otwórz wszystkie okna vima, aby uzyskać nową funkcję, a następnie nagraj się na przemian naciskając, <C-k>aby ukończyć i jprzejść do następnego wiersza. Dodałem opcję sprawdzania, longesta jeśli jest wyłączona, wybiera losowy wpis przy użyciu losowego czasu systemowego. Jeśli znajdzie tę longestopcję, ręcznie wyszukuje najdłużej pasujący wpis ze słownika i wstawia go.

Jeśli nie podoba Ci się <C-k>mapowanie, możesz je zmienić według własnego uznania. Powinien działać z każdym mapowaniem, które lubisz.

Ponadto polecenie zwrócenia wyrażenia do oceny mapowania dodaje \<esc>znak na końcu, dzięki czemu automatycznie wychodzimy z trybu wstawiania po każdym wstawieniu, oraz znak 0cwz przodu, aby przejść do trybu wstawiania na początku i upewnić się, że zastąpimy całe słowo poprawnie. W zależności od dokładnego zachowania, jakie chcesz (jeśli twoje słowa nie są ładnie na początku każdej linii), możesz bcwzamiast tego użyć faktycznego początku słowa. Jednak wracając do słów rozpoczynających wiersz, zobaczysz pewne dziwactwa. Prawdopodobnie istnieje bardziej zaawansowane polecenie, aby zignorować zakończenie linii i wykonać oba jednocześnie, ale nie mogłem go znaleźć.

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

Ponadto, nie byłoby trudno rozszerzyć logikę tutaj, aby utworzyć alternatywne odwzorowania (przy użyciu, na przykład, parametrów funkcji), które wykonują dowolną funkcję zapewnianą przez tryb wstawiania. Z przyjemnością pomogę w spełnieniu takich wymagań i zaktualizuję ten skrypt, gdy będę miał czas.

Tim
źródło
To brzmi jak wiarygodne wyjaśnienie problemu, ale wypróbowałem oba sugerowane rozwiązania i żadne z nich nie pomogło.
Bogaty
Próbowałeś też sleeppolecenia?
Tim
Tak, chociaż tylko z sugerowaną wartością 5 sekund. Czy udało Ci się uruchomić jedno z rozwiązań? Czy możesz opublikować pełną listę kroków?
Bogaty
Nie jestem osobą, która napisała pytanie. Jednakże, można odtworzyć problem: trzeba dodać najdłużej do completeoptjak opisano w komentarzach (ponownie, nie przeze mnie). edycja : Ups, 'longest'jest wymagany dla ctrl-pkroku: nie ctrl-y. Nadal kroki opisane przez pracę pytanie-pytającego dla mnie vim -Nu NONEz completeoptedycji.
Bogaty
Myślę, że znalazłem rozwiązanie, daj mi kilka minut na zaktualizowanie mojej odpowiedzi.
Tim