Jaka jest różnica między poleceniami mapowania remap, noremap, nnoremap i vnoremap w Vimie?

1113

Jaka jest różnica między tymi remap, noremap, nnoremapi vnoremappoleceń mapowania w vim?

Chetan
źródło
1
Ostrożnie vnoremapi vmappracuj w trybie Visual AND Select. Aby mieć mapowanie tylko w trybie wizualnym, użyj xmapi xnoremap.
Benoit

Odpowiedzi:

1626

remapjest opcją, która powoduje, że mapowania działają rekurencyjnie. Domyślnie jest włączony i zalecam pozostawienie go w ten sposób. Reszta to polecenia mapowania opisane poniżej:

:mapi :noremaprekurencyjnymi i nierekurencyjnymi wersjami różnych poleceń mapowania. Oznacza to, że jeśli:

:map j gg
:map Q j
:noremap W j

jzostanie zamapowany na gg. Qzostanie również zmapowany gg, ponieważ jzostanie rozszerzony dla mapowania rekurencyjnego. Wzostanie zamapowany na j(i nie na gg), ponieważ jnie zostanie rozwinięty dla mapowania nierekurencyjnego.

Teraz pamiętaj, że Vim jest edytorem modalnym . Ma tryb normalny, tryb wizualny i inne tryby.

Dla każdego z tych zestawów odwzorowań istnieje odwzorowanie, które działa w trybach normalnym, wizualnym, wyboru i operatora ( :mapi :noremap), jeden działający w trybie normalnym ( :nmapi :nnoremap), jeden w trybie wizualnym ( :vmapi :vnoremap) i tak dalej.

Aby uzyskać więcej wskazówek na ten temat, zobacz:

:help :map
:help :noremap
:help recursive_mapping
:help :map-modes
DrAl
źródło
8
Dzięki za odpowiedź! Ponadto, kiedy stosuje się rekurencję, a kiedy stosuje się nierekurencję?
Chetan
14
@Chetan: To zależy od tego, co chcesz osiągnąć. Zwykle używam nierekurencyjnych częściej, ale jeśli zdefiniowałeś stosunkowo skomplikowane mapowanie przy użyciu nierekurencyjnych i co innego mapowania, które robi wszystko, co robi pierwsze mapowanie i więcej, łatwiejsze może być użycie mapowania rekurencyjnego, które obejmuje oryginalny, a nie ponownie przepisywać cały nierekurencyjny (szczególnie, jeśli trzeba będzie zmodyfikować oryginalny).
DrAl
10
Zakładałem, że jestem noremapprzeciwieństwem map. Mam na myśli coś, co usuwa mapowanie. Dziękuję za odpowiedź. Wyjaśniło mi to
Pavan Manjunath,
4
Nie jest to tak ważne w większości przypadków użycia, ale należy zauważyć, że :mapitp. Nie działają we wszystkich trybach, dokładnie we wszystkich trybach (konkretnie w trybie normalnym, trybie wizualnym, trybie wyboru i tryb oczekiwania operatora). Jeśli chcesz, aby mapowanie działało w trybie wstawiania, wiersza poleceń lub lang-arg, musisz użyć :map!itp. (Źródło: vimdoc.sourceforge.net/htmldoc/map.html#map-overview )
Ken Bellows
3
@whytheq noremap = mapowanie nierekurencyjne
Dan Bechard
281

Myślę, że dokumentacja Vima powinna była wyjaśnić znaczenie nazewnictwa tych poleceń. Samo powiedzenie, co robią, nie pomaga zapamiętać nazwisk.

mapto „root” wszystkich rekurencyjnych poleceń mapowania. Formularz główny dotyczy trybów „normalny”, „wizualny + wybór” i „oczekiwanie na operatora”. (Używam terminu „root” jak w lingwistyce .)

noremapjest „rootem” wszystkich nierekurencyjnych poleceń mapowania. Formularz główny dotyczy tych samych trybów co map. (Pomyśl o noreprzedrostku oznaczającym „nierekurencyjny”).

(Pamiętaj, że istnieją również takie !tryby, map!które dotyczą wstawiania i wiersza poleceń).

Zobacz poniżej, co oznacza „rekurencyjny” w tym kontekście.

Przygotowując literę trybu, taką jak nmodyfikacja trybów, w których działa mapowanie. Może wybrać podzbiór listy odpowiednich trybów (np. Tylko „wizualny”) lub wybrać inne tryby, mapktóre nie miałyby zastosowania (np. „Wstaw”).

Użyj help map-modespokaże ci kilka tabel wyjaśniających, w jaki sposób kontrolować, które tryby mają zastosowanie do mapowania.

Litery trybu:

  • n: tylko normalne
  • v: wizualne i wybierz
  • o: oczekuje na operatora
  • x: tylko wizualnie
  • s: wybierz tylko
  • i: wstaw
  • c: wiersz poleceń
  • l: wstawianie, wiersz poleceń, wyszukiwanie wyrażeń regularnych (i inne. Zbiorowo nazywane pseudo-trybem „Lang-Arg”)

Rekurencyjny ” oznacza, że ​​mapowanie jest rozwijane do wyniku, następnie wynik jest rozwijany do innego wyniku i tak dalej.

Rozszerzenie zatrzymuje się, gdy spełniony jest jeden z poniższych warunków:

  1. wynik nie jest już mapowany na nic innego.
  2. zastosowano mapowanie nierekurencyjne (tj. „noremap” [lub jeden z jego podobnych] jest ostatecznym rozszerzeniem).

W tym momencie stosuje się / wykonuje domyślne „znaczenie” końcowego wyniku Vima.

Nierekurencyjny ” oznacza, że ​​mapowanie jest rozszerzane tylko raz, a wynik jest stosowany / wykonywany.

Przykład:

 nmap K H
 nnoremap H G
 nnoremap G gg

Powyższe powoduje Krozszerzenie do H, a następnie Hrozszerzenie Gi zatrzymanie. Zatrzymuje się z powodu nnoremap, który rozszerza się i zatrzymuje natychmiast. Znaczenie Gzostanie wykonane (tj. „Skok do ostatniej linii”). Co najwyżej jedno nierekurencyjne mapowanie zostanie kiedykolwiek zastosowane w łańcuchu ekspansji (byłoby to ostatnie rozszerzenie).

Mapowanie Gna ggma zastosowanie tylko po naciśnięciu G, ale nie po naciśnięciu K. To odwzorowanie nie wpływa na naciśnięcie Kniezależnie od tego, czy Gzostało odwzorowane rekurencyjnie, czy nie, ponieważ jego linia 2 powoduje Kzatrzymanie ekspansji , więc linia 3 nie będzie używana.

kelwin
źródło
4
Jedno: mapdotyczy tylko trybów normalnego, wizualnego, wyboru i oczekiwania operatora, a nie wszystkich trybów.
Brian McCutchon,
1
należy przyjąć odpowiedź.
Tycholiz
jest to zdecydowanie lepsza odpowiedź niż zaakceptowana.
MilMike
19

Jedną różnicą jest to, że:

  • :map robi nvo== normalny + (wizualny + wybierz) + operator w toku
  • :map!robi ic == wstaw + tryb wiersza poleceń

jak podano w help map-modestabelach.

Więc: mapnie mapuje na wszystkie tryby .

Aby odwzorować na wszystkie tryby, potrzebujesz zarówno :mapi :map!.

Ciro Santilli
źródło
5
Ostrożnie !! command modeto kolejna historyczna nazwa normal modeviz. rozdział 5 vimdoc.sourceforge.net/htmldoc/intro.html#vim-modes-intro ). Skrót „c” oznacza „wiersz poleceń”. Innymi słowy: domyślnie: map! lhs rhs rekurencyjnie mapuje lhs na rhs dla trybów wstawiania + linia poleceń . Jest tak, chyba że remapdomyślna opcja jest wyraźnie wyłączona set noremap[!]w ~ / .vimrc. W takim przypadku mapowanie nie byłoby rekurencyjne (niewskazane).
Cbhihe,