Apa perbedaan antara perintah pemetaan remap, noremap, nnoremap dan vnoremap di Vim?

1114

Apa perbedaan antara remap, noremap, nnoremapdan vnoremapperintah pemetaan di Vim?

Chetan
sumber
1
Perhatian, vnoremapdan vmapbekerja dalam mode Visual DAN Pilih. Untuk memiliki pemetaan hanya dalam mode Visual, gunakan xmapdan xnoremap.
Benoit

Jawaban:

1628

remapadalah opsi yang membuat pemetaan bekerja secara rekursif. Secara default aktif dan saya sarankan Anda membiarkannya seperti itu. Sisanya adalah perintah pemetaan , dijelaskan di bawah ini:

:mapdan :noremapmerupakan versi rekursif dan non-rekursif dari berbagai perintah pemetaan. Apa itu artinya jika Anda melakukannya:

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

jakan dipetakan ke gg. Qakan juga dipetakan ke gg, karena jakan diperluas untuk pemetaan rekursif. Wakan dipetakan ke j(dan tidak ke gg) karena jtidak akan diperluas untuk pemetaan non-rekursif.

Sekarang ingat bahwa Vim adalah editor modal . Ini memiliki mode normal , mode visual dan mode lainnya.

Untuk masing-masing set pemetaan ini, ada pemetaan yang berfungsi dalam mode normal, visual, pilih dan operator ( :mapdan :noremap), yang bekerja dalam mode normal ( :nmapdan :nnoremap), satu dalam mode visual ( :vmapdan :vnoremap) dan seterusnya.

Untuk panduan lebih lanjut tentang ini, lihat:

:help :map
:help :noremap
:help recursive_mapping
:help :map-modes
DrAl
sumber
8
Terima kasih atas jawaban anda! Juga, kapan digunakan rekursif, dan kapan digunakan non-rekursif?
Chetan
14
@ Chetan: Tergantung apa yang ingin Anda capai. Saya cenderung menggunakan non-rekursif lebih sering, tetapi jika Anda telah mendefinisikan pemetaan yang relatif rumit menggunakan non-rekursif dan apa pemetaan lain yang melakukan semua yang dilakukan pemetaan pertama dan banyak lagi, akan lebih mudah untuk menggunakan pemetaan rekursif yang mencakup yang asli daripada mengetik ulang seluruh yang non-rekursif lagi (terutama jika Anda kemudian perlu mengubah yang asli).
DrAl
10
Saya berasumsi noremapada yang bertolak belakang map. Maksud saya sesuatu yang menghilangkan pemetaan. Terima kasih atas jawabannya. Itu mengklarifikasi saya
Pavan Manjunath
4
Ini tidak begitu penting untuk sebagian besar kasus penggunaan, tetapi harus dicatat bahwa :map, dll tidak bekerja di semua mode, tepatnya, hanya semua yang umum (khususnya, mode normal, mode visual, mode pilih, dan mode operator-pending). Jika Anda ingin pemetaan berfungsi dalam mode insert, command-line, atau lang-arg, Anda perlu menggunakan :map!, dll. (Sumber: vimdoc.sourceforge.net/htmldoc/map.html#map-overview )
Ken Bellows
3
@whytheq noremap = pemetaan non-rekursif
Dan Bechard
281

Saya pikir dokumentasi Vim seharusnya menjelaskan arti di balik penamaan perintah ini. Memberitahu Anda apa yang mereka lakukan tidak membantu Anda mengingat namanya.

mapadalah "root" dari semua perintah pemetaan rekursif. Formulir root berlaku untuk mode "normal", "visual + select", dan "menunggu operator". (Saya menggunakan istilah "root" seperti dalam linguistik .)

noremapadalah "root" dari semua perintah pemetaan non-rekursif. Formulir root berlaku untuk mode yang sama dengan map. (Pikirkan noreawalan yang berarti "non-rekursif".)

(Perhatikan bahwa ada juga !mode seperti map!itu yang berlaku untuk menyisipkan & baris perintah.)

Lihat di bawah untuk arti "rekursif" dalam konteks ini.

Mempertahankan huruf mode seperti nmemodifikasi mode pemetaan bekerja. Ini dapat memilih subset dari daftar mode yang berlaku (misalnya hanya "visual"), atau memilih mode lain yang maptidak berlaku (misalnya "masukkan").

Gunakan help map-modesakan menunjukkan kepada Anda beberapa tabel yang menjelaskan bagaimana mengontrol mode pemetaan yang berlaku.

Huruf mode:

  • n: hanya normal
  • v: visual dan pilih
  • o: menunggu operator
  • x: hanya visual
  • s: pilih saja
  • i: memasukkan
  • c: garis komando
  • l: masukkan, command-line, regexp-search (dan lainnya. Secara kolektif disebut "Lang-Arg" mode semu)

" Rekursif " berarti pemetaan diperluas ke hasil, kemudian hasilnya diperluas ke hasil lain, dan seterusnya.

Ekspansi berhenti ketika salah satu dari ini benar:

  1. hasilnya tidak lagi dipetakan ke hal lain.
  2. pemetaan non-rekursif telah diterapkan (yaitu "noremap" [atau salah satu dari sejenisnya] adalah ekspansi terakhir).

Pada titik itu, "makna" default Vim dari hasil akhir diterapkan / dieksekusi.

" Non-rekursif " berarti pemetaan hanya diperluas sekali, dan hasilnya diterapkan / dijalankan.

Contoh:

 nmap K H
 nnoremap H G
 nnoremap G gg

Penyebab di atas Kuntuk memperluas ke H, lalu Huntuk memperluas ke Gdan berhenti. Itu berhenti karena nnoremap, yang mengembang dan berhenti segera. Arti dari Gakan dieksekusi (yaitu "melompat ke baris terakhir"). Paling-paling satu pemetaan non-rekursif akan diterapkan dalam rantai ekspansi (itu akan menjadi ekspansi terakhir yang terjadi).

Pemetaan Guntuk gghanya berlaku jika Anda menekan G, tetapi tidak jika Anda menekan K. Pemetaan ini tidak memengaruhi pengepresan Kterlepas dari apakah Gdipetakan secara rekursif atau tidak, karena jalur 2 yang menyebabkan ekspansi Kberhenti, sehingga saluran 3 tidak akan digunakan.

Kelvin
sumber
4
Satu hal: maphanya berlaku untuk mode normal, visual, pilih, dan menunggu operator, tidak untuk semua mode.
Brian McCutchon
1
harus diterima jawabannya.
Tycholiz
ini adalah jawaban yang jauh lebih baik daripada jawaban yang diterima.
MilMike
19

Salah satu perbedaannya adalah:

  • :map tidak nvo== normal + (visual + pilih) + operator tertunda
  • :map!tidak ic == masukkan + mode baris perintah

seperti yang tertera pada help map-modestabel.

Jadi: maptidak memetakan ke semua mode .

Untuk memetakan ke semua mode, Anda membutuhkan keduanya :mapdan :map!.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
5
Hati-hati !! command modeadalah nama historis lain untuk normal modeyaitu. bab 5 vimdoc.sourceforge.net/htmldoc/intro.html#vim-modes-intro ). Singkatan 'c' adalah untuk 'command-line'. Dengan kata lain, secara default: memetakan lhs ke rhs map! lhs rhs secara rekursif untuk mode insert + command-LINE . Itu kecuali remapopsi default dinonaktifkan secara eksplisit dengan set noremap[!]di ~ / .vimrc. Dalam hal ini pemetaan tidak akan bersifat rekursif (tidak disarankan).
Cbhihe