Jak debugować mapowanie?

65

Widzę tu wiele pytań, w których użytkownik ma mapowanie, które nie działa i przez większość czasu przyczyny są dość podobne.

Sugeruję, aby uczynić to pytanie odniesieniem do tego rodzaju pytań, aby podać pełną procedurę debugowania mapowania. Jeśli użytkownik ma problem z mapowaniem, może zostać przekierowany tutaj, aby wyeliminować najczęstsze problemy.

Oczywiście nadal będą istnieć szczególne przypadki, które będą wymagały specjalnego pytania i nie zostaną tutaj omówione.

statox
źródło

Odpowiedzi:

88

Twoje mapowanie nie działa tak, jak powinno, lub zachowuje się inaczej niż oczekiwano. Aby rozwiązać ten problem, należy wykonać kilka kroków:

Sprawdź, czy klucz jest skutecznie przypisany do tego, co powinien zrobić

Vim udostępnia polecenie :map. Domyślnie (gdy nie podano argumentu) polecenie wyświetli wszystkie aktualnie utworzone odwzorowania. Oto przykład wyniku polecenia:

wynik <code>: map </code>

Jak zawsze dokument jest twoim przyjacielem: :h map-listing

Możesz zobaczyć w pierwszej kolumnie tryb mapowania ( ndla trybu normalnego, vdla trybu wizualnego itp.), Druga kolumna pokazuje zamapowane klucze, a ostatnia kolumna, do której są zamapowane klucze. Pamiętaj, że przed mapowanymi akcjami mogą pojawić się dodatkowe postacie, ważne jest, aby je zrozumieć:

  • * wskazuje, że nie można go ponownie zastosować (tj. nie jest to mapowanie rekurencyjne, patrz know when to use noredalej w tej odpowiedzi)
  • & wskazuje, że można stosować tylko mapowania lokalne dla skryptów
  • @ wskazuje lokalne odwzorowanie bufora

Prosząc o pomoc dotyczącą mapowania, dobrze jest dodać tę informację, ponieważ może ona pomóc innym osobom zrozumieć zachowanie twojego mapowania.

Jest możliwe, aby ograniczyć zachęty do konkretnego trybu z siostrzanych-poleceń :map, jak :vmap, :nmap, :omap, itd.

Teraz, aby ograniczyć wyszukiwanie do problematycznego mapowania, możesz przekazać sekwencję klawiszy, którą debugujesz, jako parametr poleceń:

:map j
:map <Leader>m
:map <F5>

Zauważ, że <Leader>klucz zostanie zastąpiony jego rzeczywistą wartością na liście.

Jeśli wynik polecenia pokazuje, że twoje klucze są poprawnie zamapowane, prawdopodobnie oznacza to, że problem nie pochodzi od Vima, ale z twojego terminala lub środowiska pulpitu. Zobacz część Sprawdź, czy Vim przechwytuje twoje mapowanie

Jeśli wynik polecenia pokazuje, że klucze nie są poprawnie zmapowane, zobacz następną część.

Sprawdź, co przesłoniło twoje mapowanie

Innym wygodnym zastosowaniem :mappolecenia jest połączenie go z verbose: Wyświetli się ostatni plik, który zmodyfikował twoje mapowanie.

Na przykład zobacz te dwa zrzuty ekranu, które są wynikiem :verbose map: pierwszy to mapowanie zmodyfikowane przez mój, .vimrca drugi mapowanie utworzone przez wtyczkę:

Zestaw do mapowania z vimrc

Zestaw mapowania z wtyczki

Teraz, jeśli zauważysz, że inny skrypt zmodyfikował twoje mapowanie, będziesz musiał sprawdzić, czy możesz go usunąć lub zmodyfikować jego zachowanie. (Należy pamiętać, że niektóre wtyczki zapewniają zmienne do włączania / wyłączania mapowań, niestety nie wszystkie wtyczki to robią)

Jeśli ostatnim plikiem, który zmienił twoje mapowanie, jest twój .vimrc, upewnij się, że nie ma innej linii, która definiowałaby mapowanie dla tego samego klucza. .vimrcPlik chętnie zastępują mapowania z ostatniego w swoim rodzaju w pliku.

Sprawdź, czy Vim przechwytuje twoje mapowanie

Kilka sytuacji może wskazywać, że Vim nie przechwytuje twojego klucza:

  • Polecenie :mappokazuje, że twój klucz jest poprawnie zamapowany, ale jego naciśnięcie nic nie robi.
  • Twoje mapowanie działa na gVim (GUI), ale nic nie robi w terminalu Vim
  • Twoje mapowanie działa na określonym emulatorze terminali, ale nie na innym
  • Twoje mapowanie działa na zdefiniowanym systemie operacyjnym, ale nie na innym.

Prawdopodobnie jest to spowodowane jedną z dwóch następujących rzeczy:

  • Coś przechwytuje klucz przed Vimem : mogą to być różne aplikacje: twój system operacyjny, środowisko pulpitu, emulator terminala, Tmux (jeśli go używasz) ...

    Aby rozwiązać ten problem, należy:

    • Spróbuj tymczasowo usunąć swoje, .tmux.confjeśli używasz Tmux
    • Zapoznaj się z dokumentacją terminala lub środowiska pulpitu.

    Możesz również odwoływać się do witryn siostrzanych, takich jak superużytkownik , Unix i Linux , askUbuntu itp.

    Jeśli to jest problem, masz dwa rozwiązania: albo spędzasz (dużo) czasu, aby zmienić zachowanie aplikacji, która powoduje problem, albo znajdujesz inną kombinację klawiszy na mapie, która nie jest przechwytywana przez inną aplikację.

  • Twój emulator terminala nie może obsłużyć kombinacji klawiszy, którą próbujesz zmapować : Emulatory terminali są zaimplementowane inaczej i niektóre z nich nie są w stanie obsłużyć określonej kombinacji klawiszy. (Powodem, dla którego nie mogą być poza zakresem tego pytania, zobacz ich doktora lub wspomniane wcześniej strony siostrzane, aby uzyskać więcej informacji).

    W takim przypadku nie masz wielu rozwiązań: albo zmieniasz klucz na inny, który jest obsługiwany poprawnie przez terminal, albo zmieniasz emulator terminala.

Sprawdź typowe pułapki

Niektóre problemy z mapowaniami są dość powtarzające się i związane są głównie ze składnią vimscript. Jeśli Twoje mapowanie zachowuje się nieoczekiwanie, pamiętaj o sprawdzeniu następujących punktów:

  • Nie umieszczaj komentarza w tym samym wierszu co twoje odwzorowanie , zamiast tego wstaw komentarz w wierszu powyżej. Przykład:

    Nie rób tego:

    inoremap ii <esc>    " ii to go back into normal mode
    

    Vim rozważy białe spacje, "i komentarz jako część mapowania, co spowoduje nieoczekiwane zachowanie.

    Zamiast tego zrób to:

    " ii to go back into normal mode
    inoremap ii <esc>
    

    Jest łatwiejszy do odczytania i nie zepsuje mapowania.

  • Nie potokuj swoimi poleceniami| . Przykład:

    Nie rób tego:

    nnoremap <Leader>x :w | !% python -m json.tools
    

    Vim rozważy potok |jako zakończenie polecenia: Po źródle zostanie utworzone .vimrcmapowanie nnoremap <Leader>x :w, a następnie polecenie zewnętrzne !% python -m json.toolszostanie wykonane.

    Zamiast tego zrób to:

    nnoremap <Leader>x :w <bar> !% python -m json.tools
    

    Zobacz wyjaśnienie na temat<bar> .

  • Wiedzieć, kiedy używać nore: zawsze .

    LearnVimscriptTheHardWay to wyjaśnić dość jasno: nigdy nie używaj map, nmap, vmapitd ... Zawsze wolę wersję nore: noremap, nnoremap, vnoremap, etc ... Dlaczego? noreoznacza non-recursivemapowanie, co oznacza, że ​​prawa strona mapowania będzie uważana za funkcję wbudowaną, nawet jeśli zostanie ona przekształcona. Przykład:

    Powiedzmy, że chcesz zmapować, >aby usunąć linię i -zwiększyć wcięcie linii. Jeśli nie korzystasz z mapowania nierekurencyjnego, zrobisz to:

    ( Nie rób tego, to na przykład )

    nmap > dd
    nmap - >
    

    Kiedy uderzysz, >twoja linia zostanie usunięta, to dobrze. Ale kiedy uderzysz, -twoja linia również zostanie usunięta zamiast wcięcia. Dlaczego? Ponieważ Vim zrozumiał: „Otrzymałem trafienie, na -które powinienem przetłumaczyć, na >który z kolei powinienem przetłumaczyć dd”.

    Zamiast tego zrób to

    nnoremap > dd
    nnoremap - >
    

    W ten sposób Vim przetłumaczy -jako >i nie będzie próbował wykonać żadnego innego tłumaczenia z powodu nore.

    Edytuj notatkę „Zawsze” może być przesadną odpowiedzią, w niektórych przypadkach trzeba użyć rekurencyjnego formularza mapowania, ale nie jest to tak naprawdę powszechne. Aby to wyjaśnić, zacytuję @romainl z tej odpowiedzi :

    Używaj mapowania rekurencyjnego tylko wtedy, gdy zamierzasz użyć innego mapowania w swoim mapowaniu. Jeśli nie, używaj mapowań nierekurencyjnych.

  • Pamiętaj, że niektóre kombinacje klawiszy są równoważne : Z powodu generowanych kodów szesnastkowych niektóre kombinacje klawiszy będą interpretowane przez Vima jako kolejny klucz. Na przykład

    • <C-h> jest równa <backspace>
    • <C-j> tak jak <enter>
    • Na francuskich klawiaturach <M-a>jest tak samo jak ái ze wszystkimi <m-mapowaniami. Jak zauważył @LucHermitte w komentarzu, jest to problem z wtyczkami używającymi tego rodzaju mapowań, takich jak vim-latex.
    • <C-S-a>jest równoważne z <C-a> . Odwzorowanie Ctrl + wielka litera oddzielnie od Ctrl + mała litera nie jest możliwe, ponieważ terminale wysyłają kody ASCII.

    Kiedy twoje mapowanie wydaje się wpływać na inny klucz, spróbuj użyć innej kombinacji lhs, jeśli to rozwiąże problem, sprawdź, które kody szesnastkowe są wysyłane do Vima.

  • Sprawdź, czy twój lider jest poprawnie zdefiniowany : Jeśli twoje powiązania mapowania<leader>nie działają i zmieniłeś swojego lidera za pomocą poleceniamapleader, sprawdź, czy definicja twojego lidera została wykonana przed definicją mapowań. W przeciwnym razie Vim spróbuje utworzyć mapowania z kluczem, który nie jest tym, o czym myślisz. Również jeśli chcesz użyć spacji jako lidera (co jest dość aktualne), upewnij się, że użyłeś poprawnej notacji:let mapleader = "\<Space>"

Twoje mapowanie nadal nie działa?

Jeśli wykonałeś wszystkie kroki tej odpowiedzi, a Twoje mapowanie nadal nie działa tak, jak chcesz, prawdopodobnie będziesz chciał poprosić o pomoc na tej stronie.

Aby pomóc innym w pamiętaniu o dostarczeniu pewnych ważnych informacji, takich jak:

  • Polecenie użyte do zdefiniowania mapowania.
  • Czego oczekujesz od mapowania.
  • Dokładny opis problemu:

    „To nie działa” nie będzie naprawdę pomocne dla osób, które będą próbowały ci pomóc. Powinieneś sprecyzować, czy mapowanie nic nie robi lub jak działa inaczej niż się spodziewałeś.

  • Wskaż także, że faktycznie wykonałeś kroki opisane tutaj i wyniki, które otrzymujesz z :mapi:verbose map

Wszystko to pozwoli zaoszczędzić tobie i użytkownikom strony dużo czasu.


Przydatne polecenie: :unmap

Czasami może być przydatne zresetowanie mapowania bez wychodzenia z Vima, aby pomóc w debugowaniu jego zachowania.

Aby to zrobić, możesz użyć polecenia, :unmap <key>które usunie przypisanie przypisane do <key>trybów Normalny, Wizualny i Operacyjny. :iunmapusunie mapowania dla trybu Wstaw. Inne tryby patrz :help :unmap.


Bibliografia

Doskonałe wprowadzenie do mapowania: learnvimscriptthehardway (i wiele innych aspektów Vima)

Doc: :h mapping, :h :map

Rozdział 20 FAQ Vima dotyczy mapowania i zawiera interesujące pytania:

I bonus: pytanie o najlepsze praktyki, aby znaleźć klucze, których należy użyć w mapowaniu

statox
źródło
2
Aby podzielić się moim doświadczeniem z innymi użytkownikami, tak jak sugerował nasz moderator . A ponieważ, I see a lot of questions on here where a user has a mapping which doesn't work and most of the time the reasons are pretty similarjak powiedziałem w pierwszym wierszu mojego pytania, zgromadzenie tych powodów powinno pozwolić na zmniejszenie liczby duplikatów pytań dotyczących mapowania.
statox
1
Powtarzający się problem z lateksem vim i klawiaturami francuskimi: <m-i>i ésą takie same dla vim, i to samo z wszystkimi klawiszami meta +: są powiązane z innym znakiem diakrytycznym.
Luc Hermitte,
1
Ważne jest również, aby wiedzieć, jak odczytywać lokalne odwzorowania bufora, gdy pytamy o ich definicję za pomocą :map {sequence}-> istnieje *odwrócone podświetlenie w tym, co vim drukuje przed powiązaną akcją.
Luc Hermitte,
2
Czasami naprawdę chcemy debugować to, co się dzieje. Zwykle, gdy mapowanie wywołuje mapowanie wtyczki lub funkcję o nazwie niemożliwej do zapamiętania lub o złożonych parametrach. W takim przypadku możemy wykonać: :debug normal {keysequence}(bez Wybuchu), lub :debug i{keysequence}do trybu wstawiania odwzorowań itp Jeśli klucz zawiera takie rzeczy jak sekwencja klawiszy specjalnych ( <cr>, <left>, <c-x>, <m-i>, <leader>...). Następnie musimy zagrać w execute + double-quotes + backslash -> :debug execute "normal \<leader>\<cr>Z".
Luc Hermitte
2
Jeśli chodzi o meta-sekwencje, jest to stary punkt FAQ, ponieważ vim-latex zdecydował się na użycie takich rzeczy <m-i>. Większość użytkowników nie używa meta-klucza, ponieważ są silnie zorientowani na uruchomienie Vima w terminalu - tam, gdzie nie można po prostu użyć meta-klucza. Aby zauważyć problem, musimy użyć gvim lub macvim.
Luc Hermitte,