Comment déboguer un mapping?

66

Je vois beaucoup de questions ici où un utilisateur a un mappage qui ne fonctionne pas et la plupart du temps les raisons sont assez similaires.

Je suggère de faire de cette question une référence pour ce type de question, afin de donner une procédure complète pour déboguer un mappage. Si un utilisateur rencontre un problème avec un mappage, il peut être redirigé ici pour éliminer les problèmes les plus courants.

Bien sûr, il y aura toujours des cas particuliers qui nécessiteront une question spécifique et ne seront pas abordés ici.

statox
la source

Réponses:

90

Votre mappage ne fait pas ce qu'il devrait faire ou se comporte différemment que prévu, plusieurs étapes doivent suivre pour résoudre ce problème:

Vérifiez que la clé est bien associée à ce qu'elle devrait faire

Vim fournit une commande :map. Par défaut (en l'absence d'argument), la commande affiche tous les mappages créés. Voici un exemple du résultat de la commande:

résultat de <code>: map </ code>

Comme toujours le doc est ton ami: :h map-listing

Vous pouvez voir dans la première colonne le mode du mappage ( npour le mode normal, vpour le mode visuel, etc.), la deuxième colonne indique les clés mappées et la dernière colonne à laquelle les clés sont mappées. Notez qu'avant les actions mappées, certains caractères supplémentaires peuvent apparaître, il est important de les comprendre:

  • * indique qu'il n'est pas remappable (c'est-à-dire qu'il ne s'agit pas d'un mappage récursif, voir know when to use noreplus loin dans cette réponse)
  • & indique que seuls les mappages locaux au script sont remappables
  • @ indique un mappage local tampon

Lorsque vous demandez de l’aide sur un mappage, il est bon d’ajouter ces informations, car elles peuvent aider d’autres personnes à comprendre le comportement de votre mappage.

Il est possible de limiter l'invite à un mode particulier avec les sœurs de commandes :map, comme :vmap, :nmap, :omap, etc.

Maintenant, pour limiter votre recherche au mappage problématique, vous pouvez passer la séquence de clés que vous déboguez comme paramètre des commandes, comme ceci:

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

Notez que la <Leader>clé sera remplacée par sa valeur réelle dans la liste.

Si le résultat de la commande indique que vos clés sont correctement mappées, cela signifie probablement que le problème ne vient pas de Vim, mais de votre terminal ou de votre environnement de bureau. Voir la partie Vérifier si votre mapping est réellement intercepté par Vim

Si le résultat de la commande indique que vos clés ne sont pas correctement mappées, voir la partie suivante.

Vérifiez ce qui a surchargé votre mapping

Une autre utilisation pratique de la :mapcommande consiste à la combiner avec verbose: Ceci affichera le dernier fichier ayant modifié votre correspondance.

Par exemple, voyez ces deux captures d'écran qui résultent de :verbose map: la première est une cartographie modifiée par my .vimrcet la deuxième une cartographie créée par un plugin:

Jeu de mappage de vimrc

Mapping set à partir d'un plugin

Maintenant, si vous voyez qu'un autre script a modifié votre mapping, vous devrez voir si vous pouvez le supprimer ou modifier son comportement. (Notez que certains plugins fournissent des variables pour activer / désactiver leurs mappages, malheureusement tous ne le font pas)

Si le dernier fichier qui a modifié votre mappage est votre .vimrc, assurez-vous qu'aucune autre ligne ne définit également un mappage pour la même clé. Le .vimrcfichier remplacera volontiers tout mappage avec le dernier de ce type dans le fichier.

Vérifiez si votre cartographie est réellement interceptée par Vim

Plusieurs situations peuvent indiquer que Vim n'intercepte pas votre clé:

  • La commande :mapindique que votre clé est correctement mappée, mais son appui ne fait rien.
  • Votre mapping fonctionne sur gVim (GUI) mais ne fait rien dans le terminal Vim
  • Votre mappage fonctionne sur un émulateur de terminal défini mais pas sur un autre.
  • Votre mappage fonctionne sur un système d'exploitation défini, mais pas sur un autre.

Cela est probablement dû à l'une des deux choses suivantes:

  • Quelque chose intercepte la clé avant Vim : il peut s'agir de différentes applications: votre système d'exploitation, votre environnement de bureau, votre émulateur de terminal, Tmux (si vous l'utilisez) ...

    Pour résoudre ce problème, vous devriez:

    • Essayez de supprimer temporairement votre .tmux.confsi vous utilisez tmux
    • Reportez-vous à la doc de votre terminal ou de votre environnement de bureau.

    Vous pouvez également faire référence à des sites apparentés tels que superutilisateur , Unix et Linux , askUbuntu , etc.

    Si tel est le problème, vous avez alors deux solutions: soit vous passez (beaucoup) de temps à changer le comportement de l'application à l'origine du problème, soit vous trouvez une autre combinaison de touches à mapper qui n'est pas interceptée par une autre application.

  • Votre émulateur de terminal ne peut pas gérer la combinaison de touches que vous essayez de mapper : les émulateurs de terminal sont implémentés différemment et certains d'entre eux ne sont pas en mesure de gérer une combinaison de touches particulière. (La raison pour laquelle ils ne le peuvent pas est hors du champ de cette question, voir leur doc ou les sites frères mentionnés précédemment pour plus de détails).

    Dans ce cas, vous n’avez pas beaucoup de solutions: soit vous changez votre clé pour une autre qui est gérée correctement par votre terminal, soit vous changez d’émulateur de terminal.

Vérifiez les pièges courants

Certains problèmes de mappages sont assez récurrents et sont principalement liés à la syntaxe vimscript. Si votre mappage a un comportement inattendu, n'oubliez pas de vérifier les points suivants:

  • Ne mettez pas de commentaire sur la même ligne que votre mappage , mais mettez le commentaire sur la ligne ci-dessus. Exemple:

    Ne fais pas ça:

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

    Vim considérera les espaces, le "et le commentaire comme faisant partie du mappage, ce qui entraînera un comportement inattendu.

    Au lieu de cela, faites-le:

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

    Ceci est plus facile à lire et ne gâchera pas votre cartographie.

  • Ne transmettez pas vos commandes avec| . Exemple:

    Ne fais pas ça:

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

    Vim considérera le tuyau |comme une fin de commande: lorsque vous spécifiez votre source, .vimrcle mappage nnoremap <Leader>x :wsera créé, la commande externe !% python -m json.toolssera exécutée.

    Au lieu de cela, faites-le:

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

    Voir une explication sur<bar> .

  • Savoir quand utiliser nore: toujours .

    LearnVimscriptTheHardWay expliquer assez clairement: ne jamais utiliser map, nmap, vmap, etc ... Préférez toujours la version Nore: noremap, nnoremap, vnoremap, etc ... Pourquoi? noresignifie non-recursivemappage, cela signifie que le côté droit du mappage sera considéré comme une fonctionnalité intégrée, même si vous le remappez. Exemple:

    Supposons que vous souhaitiez mapper >pour supprimer une ligne et -incrémenter le retrait d'une ligne. Si vous n'utilisez pas de mappages non récursifs, vous le ferez:

    ( Ne faites pas que c'est pour l'exemple )

    nmap > dd
    nmap - >
    

    Lorsque vous frappez >votre ligne sera supprimée, c'est bien. Mais lorsque vous frappez, -votre ligne sera également supprimée au lieu d'être mise en retrait. Pourquoi? Parce que Vim a compris "j'ai reçu un hit sur -lequel je devrais traduire et auquel je devrais traduire >, à son tour dd".

    Au lieu de cela

    nnoremap > dd
    nnoremap - >
    

    De cette façon, Vim traduira -comme >et n'essaiera pas de faire une autre traduction à cause du nore.

    Modifier la note "Toujours" peut être une réponse exagérée. Dans certains cas, vous devrez utiliser le formulaire de mappage récursif, mais ce n'est pas vraiment courant. Pour clarifier, je citerai @romainl de cette réponse :

    Utilisez un mappage récursif uniquement si vous avez l'intention d'utiliser un autre mappage dans votre mappage. Utilisez des mappages non récursifs si vous ne le faites pas.

  • N'oubliez pas que certaines combinaisons de touches sont équivalentes : En raison des codes hexadécimaux produits, certaines combinaisons de touches seront interprétées par Vim comme une autre clé. Par exemple

    • <C-h> est équivalent à <backspace>
    • <C-j> comme <enter>
    • Sur les claviers français, <M-a>c'est pareil áet pareil avec tous les <m-mappages. Comme l'a souligné @LucHermitte dans le commentaire, il existe un problème de plug-ins utilisant ce type de mappage comme vim-latex.
    • <C-S-a>est équivalent à <C-a> . Mapper Ctrl + lettre majuscule séparément de Ctrl + lettre minuscule n'est pas possible en raison de la façon dont les terminaux envoient des codes ASCII.

    Lorsque votre correspondance semble affecter une autre clé, essayez d'utiliser une autre combinaison lhs, si cela résout le problème, vérifiez quels codes hexadécimaux sont envoyés à Vim.

  • Vérifiez que votre leader est correctement défini : Si vos mappages impliquant<leader>ne fonctionnent pas et que vous avez changé votre leader avec la commandemapleader, vérifiez que la définition de votre leader est bien effectuée avant la définition des mappages. Sinon, Vim essaiera de créer des correspondances avec une clé qui n’est pas celle que vous pensez. De plus, si vous souhaitez utiliser la barre d'espace comme guide (ce qui est assez courant), assurez-vous d'avoir utilisé la notation correcte:let mapleader = "\<Space>"

Votre cartographie ne fonctionne toujours pas?

Si vous avez suivi toutes les étapes de cette réponse et que votre mappage ne fonctionne toujours pas comme vous le souhaitez, vous voudrez probablement demander de l'aide sur ce site.

Pour aider les gens à vous aider, n'oubliez pas de fournir des informations cruciales telles que:

  • La commande que vous avez utilisée pour définir votre correspondance.
  • Ce que vous attendez de votre cartographie.
  • Une description précise du problème:

    "Ça ne marche pas" ne sera pas vraiment utile aux personnes qui essaieront de vous aider. Vous devez préciser si le mappage ne fait rien ou comment il se comporte différemment de ce que vous attendiez.

  • Indiquez également que vous avez bien suivi les étapes décrites ici et les résultats obtenus avec :mapet:verbose map

Tout cela fera gagner beaucoup de temps à vous et aux utilisateurs du site.


Une commande utile: :unmap

Parfois, il peut être utile de réinitialiser un mappage sans quitter Vim pour faciliter le débogage de son comportement.

Pour ce faire, vous pouvez utiliser la commande :unmap <key>qui supprimera le mappage attribué aux <key>modes Normal, Visuel et En attente d’exploitation. :iunmapsupprimera les mappages pour le mode Insertion. Pour les autres modes, voir :help :unmap.


Références

Une excellente introduction à la cartographie: learnvimscriptthehardway (et de nombreux autres aspects de Vim)

Le doc: :h mapping, :h :map

La section 20 de la FAQ de Vim concerne la cartographie et contient des questions intéressantes:

Et un bonus: une question sur les meilleures pratiques pour trouver les clés à utiliser dans votre cartographie

statox
la source
2
Partager mon expérience avec d’autres utilisateurs, comme l’a suggéré notre modérateur . Et parce 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 similarque, comme je l’ai dit à la première ligne de ma question, rassembler ces raisons devrait permettre de réduire le nombre de questions en double sur la cartographie.
statox
1
Un problème récurrent avec les claviers vim-latex et français: <m-i>et ésont les mêmes pour vim, et c'est la même chose pour toutes les touches méta +: ils sont associés à un diacritique différent.
Luc Hermitte
1
Il est également important de savoir comment lire les mappages locaux au tampon lorsque nous demandons leur définition avec :map {sequence}-> il y a une *surbrillance inversée dans ce que vim affiche avant l'action associée.
Luc Hermitte
2
Parfois, nous voulons vraiment déboguer ce qui se passe. Généralement, lorsque le mappage appelle un mappage de prise ou une fonction avec un nom impossible à retenir ou avec des paramètres complexes. Dans ce cas , nous pouvons exécuter: :debug normal {keysequence}(sans bang), ou :debug i{keysequence}pour les applications en mode d'insertion, etc. Si la séquence clé contient des choses comme des touches spéciales ( <cr>, <left>, <c-x>, <m-i>, <leader>...). Ensuite, nous devons jouer avec execute + double-quotes + backslash -> :debug execute "normal \<leader>\<cr>Z".
Luc Hermitte
2
En ce qui concerne les méta-séquences, c’est un vieux sujet de FAQ car vim-latex a choisi d’utiliser des choses comme <m-i>. La plupart des utilisateurs n'utilisent pas la clé méta car ils sont fortement orientés vers l'exécution de Vim dans le terminal, où la méta-clé ne peut pas être utilisée simplement. Nous devons utiliser gvim ou macvim pour détecter le problème.
Luc Hermitte