Comment créer automatiquement des accolades correspondantes dans vim?
Cela devrait fonctionner comme suit: Si j'entre une accolade ouverte, la fermeture devrait apparaître automatiquement et le curseur devrait être placé entre les deux. Pour sauter hors de la paire d'accolades, la combinaison Ctrl-jest utilisée.
Il existe de nombreux plugins permettant l'insertion automatique des accolades. Mais ils
- soit utiliser une combinaison de touches différente de celle Ctrl-j de sauter hors de la paire d'accolades ou
- interférer avec les raccourcis clavier UltiSnips .
Les travaux suivants comme prévu
:inoremap ( ()<Esc>:let leavechar=")"<CR>i
:imap <C-j> <Esc>:exec "normal f" . leavechar<CR>a
Mais avec ces paramètres, les extraits de code UltiSnips ne fonctionnent plus. J'ai donc utilisé UltiSnips pour insérer l'accolade de fermeture:
inoremap ( (<C-R>=UltiSnips_Anon('($1)$0', '(')<CR>
Cela fonctionne presque. L'entretoise correspondante est insérée et je peux sauter celle de fermeture avec Ctrl-j. Cependant, cela ne fonctionne que s'il y a un espace devant l'accolade ouverte.
main () // works, the closing parentheses is added
main( // fails without a space
Mes solutions nécessitent soit une liaison de clé différente pour sauter par-dessus l'accolade de fermeture, soit un espace devant l'ouverture. Comment régler ceci?
Remarque: j'ai utilisé des parenthèses comme exemple. Il devrait fonctionner avec des parenthèses, des accolades, des crochets et des signes inférieurs à et ne pas interférer avec le plugin UltiSnips.
)
, remapperc-j
à cela pourrait fonctionner.Réponses:
Ce problème n'est pas anodin, comme vous le verrez. La réponse simple est: utilisez un plugin, comme autoclose ou smartinput . Le remappage naïf des touches ([.. vous présentera des boîtiers électroniques en quelques lignes, c'est pourquoi ces plugins sont créés et pourquoi ils sont généralement assez complexes (s'ils sont bons).
Vous pouvez essayer ceci à la place (ce qui est différent de ma suggestion d'origine):
Où UltiSnips divisera la ligne au
(
lieu de l'incluremain
dans le match. Le problème avec l'utilisation d'un plugin d'extrait de code pour cela est qu'ils ne prennent généralement pas en charge l'imbrication, ils oublieront donc toutes les positions de saut lors de l'insertion du prochain extrait de code (imbriqué).Vous pouvez remapper Ctrl-jpour UltiSnips ou le plugin en conflit. Si les mappages ne sont pas répertoriés dans la documentation, vous pouvez utiliser
:map/imap/nmap <key>
pour afficher le mappage. Si vous voulez Ctrl-jchoisir et faire le travail des deux plugins, vous demandez:Considérez cette boucle bash:
Dans ce cas, vous devrez appuyer Ctrl-j5 fois pour accéder au corps de la boucle. L'utilisation des accolades de fermeture pour sauter hors d'une paire correspondante vous donne beaucoup plus de contrôle sur l'endroit où vous souhaitez réellement déplacer le curseur. Vous pouvez implémenter une pile pour garder une trace des paires insérées et utiliser Ctrl-jpour sauter et déplacer, mais vous rencontrerez des problèmes si vous commencez à supprimer manuellement des accolades sans les supprimer de la pile. Vous allez donc commencer à résoudre les problèmes que les plug-ins d'accolade tentent de résoudre. C'est une roue difficile à réinventer.
En développant cela, vous pouvez obtenir ce que vous avez initialement demandé, en utilisant Ctrl-jpour sauter des accolades et des extraits. Si vous utilisez une valeur fictive pour représenter les positions des extraits et les pousser sur la pile en plus des accolades fermantes, avec un remappage dynamique de Ctrl-jpour correspondre à la remise d'extraits ou d'accolades. Mais ensuite, vous devrez implémenter des heuristiques assez avancées pour comprendre ce que la magie devrait se produire, car vous rencontrez essentiellement deux problèmes à la fois, qui sont actuellement résolus séparément par les créateurs de plugins d'insertion d'extraits et de plugins de correspondance d'accolade, et re-résoudre ces problèmes à nouveau, en plus de leurs solutions, pour atteindre la commodité et, bien, la magie.
Cela revient à contrôler vs commodité. Je pense que le contrôle vous servira mieux dans ce cas, ce qui signifie que vous devriez garder ces problèmes et leurs plugins et mappages de clés associés séparés. Si vous voulez toujours la commodité, c'est faisable, mais c'est difficile.
la source
Je pense que delimitMate fait ce dont vous avez besoin.
Il ferme automatiquement les parenthèses ou les guillemets et place votre curseur entre les deux. Pour sortir d'une paire de parenthèses (tout en étant en mode insertion), vous feriez Ctrl-g+ gmais vous pouvez remapper cela Ctrl-jen l'ajoutant à votre
vimrc
:la source
J'ai trouvé que la fermeture automatique ajoutait un peu de retard et interférait également avec ma configuration (Ultisnips et Supertab), mais j'aime son approche d'émulation d'Eclipse CDT.
J'utilise delimitMate avec les cartes suivantes pour aider à la navigation et à l'indentation, en essayant d'obtenir les mêmes résultats:
Je l'utilise de cette façon: insérez l'ouverture
{ <CR><CR><C-K>
et commencez à écrire dans la ligne intérieure en retrait.la source
Personnellement, j'utilise smartinput pour l'insertion automatique de crochets et de guillemets. Par exemple, taper
{
n'importe où produira{}
avec votre curseur au milieu. Pour quitter le{
groupe de crochets, il vous suffit de taper le}
quand à côté de l'inséré}
.Cependant, cela prend en charge votre exigence de tabstops et de sauter à l'extérieur du support. Il ne crée pas non plus de nouveau entre vos crochets, mais vous avez juste besoin d'une clé supplémentaire pour cela de toute façon -
<CR>
.Vous pouvez mapper
<C-J>
pour passer à la ligne suivante:ou si vous vouliez passer au début de la ligne suivante:
la source
Quelque chose comme ça pourrait fonctionner pour vous.
la source
En fait, Ultisnips peut le faire presque parfaitement (cela peut être nouveau). Modifiant légèrement les réponses données ci-dessus, j'ai un bon succès avec
inoremap () ()<C-R>=UltiSnips#Anon('($1)$0', '()', 'double parentheses', 'i')<CR>
Il faut taper
()
qui trouve mieux mais qui peut aussi être changé(
. Ensuite, les arguments facultatifs supplémentaires àUltiSnips#Anon
sont une description et le modificateuri
qui permet l'expansion in-word.Sauter des parenthèses avec des
<c-j>
œuvres, également imbriquées dans d'autres extraits. Cependant, l'invocation de()
parenthèses imbriquées semble rompre cette fonctionnalité, ce qui n'est pas un gros problème.la source