Supprimer automatiquement la paire de fermeture sans provoquer de paires déséquilibrées

8

Je suis en train d' écrire une fonction VIML qui, en mode d'insertion, permet à <BS>travers la partie d'ouverture d'une paire ( [, {, etc.) pour supprimer la partie de fermeture de la paire si elle est le caractère suivant le curseur ( un peu comme paires d'auto- et vim-autoclose ). Cette fonction sera différente car la partie de fermeture de la paire ne sera pas supprimée s'il y a des paires déséquilibrées.

Exemples:

Le format est celui <initial> => <result-after-backspace>où mon curseur se trouve devant le |.

((|)    =>   (|)

((|))   =>   (|)

(|)     =>   |

(defn   =>   (defn
  (|)          |)

Comment puis-je déterminer si les paires sont déséquilibrées ou non avant de continuer et de supprimer la paire de clôture?

J'ai testé les paires automatiques et vim-autoclose . Avec les deux plugins, la partie de fermeture de la paire est toujours supprimée.

200_success
la source
Pourriez-vous clarifier votre préface? Souhaitez-vous éviter tous les plugins, ou seulement ceux similaires aux deux que vous mentionnez? Si ce dernier, qu'en est-il de ces deux-là que vous n'aimez pas?
Tom
Je ne veux pas utiliser de plugins pour cela. J'ai mis à jour la préface.
1
J'ai voté pour clore cette question. Je pense que le sujet de base en tant que tel est très bien, mais vos restrictions en font une question "veuillez écrire du code pour moi plz kthxbye" en ce moment. Je ne pense pas que nous voulons autoriser ce genre de questions ici ...
Martin Tournoij
1
@Carpetsmoker Au-delà du libellé de cette question, il y a un problème qui n'a pas encore été résolu dans aucun plugin que j'ai vu. Il me semble clair qu'une fois que cette question aura été répondue avec succès, chaque plugin de type à fermeture automatique ou à paire automatique pourra bénéficier de sa solution. Comment proposeriez-vous que je modifie le libellé pour le rendre acceptable?
2
@merb, le plugin paredit fait exactement ce que vous voulez. Si vous voulez cette fonctionnalité sans utiliser le plugin, je vous suggère d'examiner la source sur github. Je pense que ce serait plus instructif que moi d'essayer d'en reproduire une version ici. github.com/kovisoft/paredit
Quincy Bowers

Réponses:

1

Si je comprends bien votre question, la clé est de déterminer si le caractère sur le curseur est un délimiteur correspondant.

Considérez les commandes en mode normal v%"zyet v%%"zy.

  • Si le curseur se trouve sur un délimiteur correspondant, la première commande tirera sur une chaîne de longueur d'au moins 2, le délimiteur, sa paire et tout texte au milieu @z. Le second tirera une chaîne de longueur exactement 1 - encore une fois, le délimiteur lui-même - dans @z.
  • Si le curseur se trouve sur un délimiteur inégalé, la première commande insérera une chaîne de longueur 1 - le délimiteur lui-même - dans @z. Avorter.
  • Si le curseur n'est pas sur un délimiteur et qu'il y a un délimiteur dans la ligne, alors la deuxième commande tirera une chaîne de longueur supérieure à 1 @z. Avorter.
  • Si le curseur n'est pas sur un délimiteur et qu'il n'y a pas d'autre délimiteur dans la ligne, alors la première commande tirera une chaîne de longueur exactement 1 - le caractère lui-même - dans @z. Avorter.

Ainsi, nous avons le résultat suivant:

Le curseur se trouve sur un délimiteur correspondant si et seulement si la commande en mode normal v%"zytire une chaîne de longueur d'au moins 2 @zet que la commande en mode normal v%%"zytire une chaîne de longueur exactement 1 @z.

Conseils pour VimL: :norm ...et vous strlen(@z)aideront ici.

wchargin
la source
Est-ce que cela répond à votre question ou est-ce que je manque quelque chose?
wchargin
Déterminer si le caractère du curseur correspond ou non n'est pas exactement la clé. L'essentiel est de déterminer si une forme donnée est équilibrée ou non. Si le formulaire est équilibré et que nous nous trouvons dans cette position (|):, appuyer sur <BS>devrait supprimer les deux. Cependant, si le formulaire de niveau supérieur est déséquilibré, comme ceci (defn (|):, appuyer sur <BS>ne devrait supprimer que ce qui serait normalement supprimé - dans ce cas, nous laisser avec (defn |).
1

Ok donc j'ai fini par parcourir paredit.vim et en retirant quelques fonctions pour créer ceci: vim-pear . Il insère et supprime les délimiteurs par paires tout en conservant un état équilibré.


la source
Cool :-) Comment l'utiliser? Puis-je simplement l'installer et il sera activé par défaut? Est-il également possible d'activer / désactiver cela uniquement pour des types de fichiers spécifiques?
Martin Tournoij
Activé pour tout par défaut. Soumettez un PR si vous voulez quelque chose comme ça. Je peux le faire moi-même à un moment donné.
Le lien est (actuellement) rompu.
Rich