Bagaimana cara debug pemetaan?


66

Saya melihat banyak pertanyaan di sini di mana pengguna memiliki pemetaan yang tidak berfungsi dan sebagian besar alasannya hampir sama.

Saya menyarankan untuk menjadikan pertanyaan ini sebagai referensi untuk pertanyaan semacam ini, untuk memberikan prosedur lengkap untuk men-debug pemetaan. Jika pengguna sebagai masalah dengan pemetaan, mereka dapat diarahkan ke sini untuk menghilangkan masalah yang paling umum.

Tentu saja masih akan ada kasus-kasus tertentu yang akan membutuhkan pertanyaan khusus dan tidak akan dibahas di sini.

Jawaban:


90

Pemetaan Anda tidak melakukan apa yang seharusnya dilakukan atau berperilaku berbeda dari yang diharapkan, beberapa langkah harus diikuti untuk memecahkan masalah itu:

Pastikan kunci dipetakan secara efektif untuk apa yang harus dilakukan

Vim memberikan perintah :map. Secara default (ketika tidak ada argumen yang diberikan) perintah akan menampilkan semua pemetaan yang saat ini dibuat. Ini adalah contoh dari hasil perintah:

hasil dari <code>: map </code>

Seperti biasa, doc adalah teman Anda: :h map-listing

Anda dapat melihat di kolom pertama mode pemetaan ( nuntuk mode normal, vuntuk mode visual, dll), kolom kedua menunjukkan kunci yang dipetakan dan kolom terakhir untuk tombol mana yang dipetakan. Perhatikan bahwa sebelum tindakan yang dipetakan, beberapa karakter tambahan mungkin muncul, penting untuk memahaminya:

  • * menunjukkan bahwa itu tidak dapat dipetakan kembali (artinya ini bukan pemetaan rekursif, lihat know when to use norenanti dalam jawaban ini)
  • & menunjukkan bahwa hanya pemetaan skrip-lokal yang dapat dibuat ulang
  • @ menunjukkan pemetaan buffer-lokal

Ketika meminta bantuan tentang pemetaan, sebaiknya tambahkan informasi ini karena dapat membantu orang lain untuk memahami perilaku pemetaan Anda.

Hal ini dimungkinkan untuk membatasi prompt untuk mode tertentu dengan adik-perintah :map, seperti :vmap, :nmap, :omap, dll

Sekarang untuk membatasi pencarian Anda ke pemetaan yang bermasalah Anda dapat melewati urutan kunci yang Anda debug sebagai parameter dari perintah, seperti ini:

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

Perhatikan bahwa <Leader>kunci akan diganti dengan nilai aktualnya dalam daftar.

Jika hasil dari perintah menunjukkan bahwa kunci Anda dipetakan dengan benar, itu mungkin berarti bahwa masalahnya bukan berasal dari Vim tetapi dari terminal Anda atau lingkungan desktop Anda. Lihat bagian Periksa apakah pemetaan Anda benar-benar dicegat oleh Vim

Jika hasil dari perintah menunjukkan bahwa kunci Anda tidak dipetakan dengan benar, lihat bagian berikut.

Periksa apa yang melampaui pemetaan Anda

Penggunaan :mapperintah lainnya yang mudah adalah menggabungkannya dengan verbose: Ini akan meminta file terakhir yang mengubah pemetaan Anda.

Misalnya, lihat dua tangkapan layar ini yang merupakan hasil dari :verbose map: yang pertama adalah pemetaan yang dimodifikasi oleh saya .vimrcdan yang kedua pemetaan yang dibuat oleh sebuah plugin:

Pemetaan diatur dari vimrc

Memetakan set dari sebuah plugin

Sekarang jika Anda melihat bahwa skrip lain memodifikasi pemetaan Anda, Anda harus melihat apakah Anda dapat menghapusnya atau mengubah perilakunya. (Perhatikan bahwa beberapa plugin menyediakan variabel untuk mengaktifkan / menonaktifkan pemetaan mereka, sayangnya tidak semua plugin melakukan itu)

Jika file terakhir yang mengubah pemetaan Anda adalah milik Anda .vimrc, pastikan tidak ada baris lain yang juga menentukan pemetaan untuk kunci yang sama. The .vimrcFile akan dengan senang hati menimpa pemetaan dengan yang terakhir dari jenisnya di file.

Periksa apakah pemetaan Anda benar-benar dicegat oleh Vim

Beberapa situasi mungkin menunjukkan bahwa Vim tidak memotong kunci Anda:

  • Perintah :mapmenunjukkan bahwa kunci Anda dipetakan dengan benar tetapi menekannya tidak melakukan apa-apa.
  • Pemetaan Anda berfungsi pada gVim (GUI) tetapi tidak melakukan apa pun di terminal Vim
  • Pemetaan Anda berfungsi pada emulator terminal yang ditentukan tetapi tidak pada yang lain
  • Pemetaan Anda berfungsi pada OS yang ditentukan tetapi tidak pada yang lain.

Mungkin disebabkan oleh salah satu dari dua hal berikut:

  • Sesuatu memotong kunci sebelum Vim : Ini dapat berupa aplikasi yang berbeda: OS Anda, lingkungan desktop Anda, emulator terminal Anda, Tmux (jika Anda menggunakannya) ...

    Untuk memecahkan masalah itu, Anda harus:

    • Cobalah untuk menghapus sementara Anda .tmux.confjika Anda menggunakan tmux
    • Rujuk ke dokumen terminal Anda atau lingkungan desktop Anda.

    Anda juga bisa merujuk ke situs saudara seperti super-user , Unix dan Linux , askUbuntu , dll ...

    Jika ini masalahnya, Anda kemudian memiliki dua solusi: Anda menghabiskan (banyak) waktu untuk mengubah perilaku aplikasi yang menyebabkan masalah atau Anda menemukan kombinasi tombol lain untuk dipetakan yang tidak dicegat oleh aplikasi lain.

  • Emulator terminal Anda tidak dapat menangani kombinasi tombol yang Anda coba petakan : Emulator terminal diimplementasikan secara berbeda dan beberapa di antaranya tidak dapat menangani beberapa kombinasi tombol tertentu. (Alasan mengapa mereka tidak dapat keluar dari ruang lingkup pertanyaan ini, lihat dokumen mereka atau situs saudara yang disebutkan sebelumnya untuk lebih jelasnya).

    Dalam hal ini, Anda tidak memiliki banyak solusi: Anda mengubah kunci Anda untuk yang lain yang ditangani dengan benar oleh terminal Anda atau Anda mengubah emulator terminal Anda.

Periksa perangkap umum

Beberapa masalah dalam pemetaan cukup berulang dan sebagian besar terkait dengan sintaks vimscript. Jika pemetaan Anda memiliki perilaku yang tidak terduga, ingatlah untuk memeriksa hal-hal berikut:

  • Jangan beri komentar pada baris yang sama dengan pemetaan Anda , sebaliknya berikan komentar pada baris di atas. Contoh:

    Jangan lakukan itu:

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

    Vim akan mempertimbangkan ruang putih, "dan komentar sebagai bagian dari pemetaan yang akan menghasilkan perilaku yang tidak terduga.

    Alih-alih melakukannya:

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

    Ini lebih mudah dibaca dan tidak akan mengacaukan pemetaan Anda.

  • Jangan menyalurkan perintah Anda dengan| . Contoh:

    Jangan lakukan itu:

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

    Vim akan menganggap pipa |sebagai terminasi perintah: Ketika Anda sumber .vimrcpemetaan Anda nnoremap <Leader>x :wakan dibuat maka perintah eksternal !% python -m json.toolsakan dieksekusi.

    Alih-alih melakukannya:

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

    Lihat penjelasan tentang<bar> .

  • Tahu kapan harus menggunakan nore: selalu .

    LearnVimscriptTheHardWay menjelaskannya cukup jelas: tidak pernah menggunakan map, nmap, vmap, dll ... Selalu lebih suka versi nore: noremap, nnoremap, vnoremap, dll ... Mengapa? norekependekan dari non-recursivepemetaan itu berarti sisi kanan pemetaan akan dianggap sebagai fitur bawaan bahkan jika Anda memetakannya kembali. Contoh:

    Katakanlah Anda ingin memetakan >untuk menghapus garis dan -untuk menambah indentasi garis. Jika Anda tidak menggunakan pemetaan non-rekursif Anda akan melakukannya:

    ( Jangan lakukan itu misalnya )

    nmap > dd
    nmap - >
    

    Ketika Anda akan mencapai >garis Anda akan dihapus, itu bagus. Tetapi ketika Anda akan mencapai -garis Anda juga akan dihapus bukannya indentasi. Mengapa? Karena Vim mengerti, "Saya menerima hit di -mana saya harus menerjemahkan >yang seharusnya saya terjemahkan dd".

    Alih-alih lakukan itu

    nnoremap > dd
    nnoremap - >
    

    Dengan cara ini Vim akan menerjemahkan -sebagai >dan tidak akan mencoba melakukan terjemahan lain karena nore.

    Edit catatan "Selalu" mungkin jawaban yang berlebihan dalam beberapa kasus Anda harus menggunakan formulir pemetaan rekursif tetapi itu tidak terlalu umum. Untuk memperjelas, saya akan mengutip @romainl dari jawaban ini :

    Gunakan pemetaan rekursif hanya jika Anda ingin menggunakan pemetaan lain dalam pemetaan Anda. Gunakan pemetaan non-rekursif jika Anda tidak.

  • Ingat bahwa beberapa kombinasi tombol adalah sama : Karena kode heksadesimal yang dihasilkan, beberapa kombinasi tombol akan ditafsirkan oleh Vim sebagai kunci lain. Sebagai contoh

    • <C-h> setara dengan <backspace>
    • <C-j> sebagai <enter>
    • Pada keyboard Prancis <M-a>sama ádan sama dengan semua <m-pemetaan. Seperti @LucHermitte tunjukkan dalam komentar yang merupakan masalah dengan plugin menggunakan jenis pemetaan seperti vim-latex.
    • <C-S-a>setara dengan <C-a> . Memetakan Ctrl + huruf besar terpisah dari Ctrl + huruf kecil tidak mungkin karena terminal mengirim kode ASCII.

    Ketika pemetaan Anda tampaknya memengaruhi kunci lain, coba gunakan kombinasi lhs lainnya, jika itu menyelesaikan masalah, periksa kode heksadesimal mana yang dikirim ke Vim.

  • Periksa apakah pemimpin Anda didefinisikan dengan benar : Jika pemetaan yang melibatkan<leader>Anda tidak berfungsi dan Anda mengganti pemimpin Anda dengan perintahmapleader, periksa apakah definisi pemimpin Anda dilakukan sebelum definisi pemetaan. Jika tidak, Vim akan mencoba membuat pemetaan dengan kunci yang bukan yang Anda pikirkan. Juga jika Anda ingin menggunakan spasi sebagai pemimpin Anda (yang cukup terkini) pastikan Anda menggunakan notasi yang benar:let mapleader = "\<Space>"

Pemetaan Anda masih tidak berfungsi?

Jika Anda menjalani semua langkah jawaban ini dan pemetaan Anda masih tidak berfungsi seperti yang Anda inginkan, Anda mungkin ingin meminta bantuan di situs ini.

Untuk membantu orang lain membantu Anda, ingatlah untuk memberikan beberapa informasi penting seperti:

  • Perintah yang Anda gunakan untuk menentukan pemetaan Anda.
  • Apa yang Anda harapkan akan dilakukan pemetaan Anda.
  • Deskripsi masalah yang tepat:

    "Tidak berhasil" tidak akan sangat membantu orang yang akan mencoba membantu Anda. Anda harus tepat jika pemetaan tidak melakukan apa pun atau bagaimana itu berperilaku berbeda dari yang Anda harapkan.

  • Juga tunjukkan bahwa Anda benar-benar mengikuti langkah-langkah yang dijelaskan di sini dan hasil yang Anda dapatkan dengan :mapdan:verbose map

Semua ini akan menghemat banyak waktu bagi Anda dan pengguna situs.


Perintah yang berguna: :unmap

Terkadang berguna untuk mengatur ulang pemetaan tanpa berhenti dari Vim untuk membantu men-debug perilakunya.

Untuk melakukannya, Anda dapat menggunakan perintah :unmap <key>yang akan menghapus pemetaan yang ditetapkan untuk <key>mode Normal, Visual, dan Operasi-tertunda. :iunmapakan menghapus pemetaan untuk mode Sisipkan. Untuk mode lain, lihat :help :unmap.


Referensi

Pengantar pemetaan yang sangat baik: learnvimscriptthehardway (Dan banyak aspek Vim lainnya)

Doc: :h mapping, :h :map

Bagian 20 dari FAQ Vim adalah tentang pemetaan dan berisi pertanyaan menarik:

Dan bonus: Sebuah pertanyaan tentang praktik terbaik untuk menemukan kunci mana yang digunakan dalam pemetaan Anda


2
Untuk berbagi pengalaman saya dengan pengguna lain seperti yang disarankan moderator kami . Dan karena 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 similarseperti yang saya katakan di baris pertama pertanyaan saya, jadi mengumpulkan alasan-alasan ini akan memungkinkan untuk mengurangi jumlah pertanyaan duplikat tentang pemetaan.
statox

1
Masalah berulang dengan vim-latex dan keyboard Prancis: <m-i>dan ésama untuk vim, dan itu sama dengan semua kunci meta +: mereka terkait dengan diakritik yang berbeda.
Luc Hermitte

1
Penting juga untuk mengetahui cara membaca pemetaan penyangga-lokal ketika kami meminta definisi mereka dengan :map {sequence}-> ada *sorotan terbalik dalam cetakan vim apa sebelum tindakan terkait.
Luc Hermitte

2
Terkadang kami benar-benar ingin men-debug apa yang terjadi. Biasanya ketika pemetaan memanggil pemetaan plug, atau fungsi dengan nama yang tidak mungkin diingat atau dengan parameter kompleks. Dalam hal ini kita dapat mengeksekusi: :debug normal {keysequence}(tanpa Bang), atau :debug i{keysequence}untuk mode insert pemetaan, dll Jika urutan kunci berisi hal-hal seperti tombol khusus ( <cr>, <left>, <c-x>, <m-i>, <leader>...). Maka kita perlu bermain dengan mengeksekusi + tanda kutip ganda + backslash -> :debug execute "normal \<leader>\<cr>Z".
Luc Hermitte

2
Mengenai meta-sequence, ini adalah poin lama dari FAQ karena vim-latex memang memilih untuk menggunakan hal-hal seperti <m-i>. Sebagian besar pengguna tidak menggunakan kunci meta karena mereka sangat berorientasi menjalankan Vim di terminal - di mana meta-key tidak dapat digunakan secara sederhana. Kita perlu menggunakan gvim atau macvim untuk memperhatikan masalah ini.
Luc Hermitte
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.