Dans divers environnements de développement intégrés, la saisie d'une boucle ouverte entraîne l'apparition d'une paire de caractères accolés. Généralement, les accolades sont insérées de manière contextuelle. Dans un littéral de chaîne, il n'y a pas de saut de ligne interposé entre les accolades. En dehors d'un littéral de chaîne, il y a une nouvelle ligne, et les choses sont immédiatement indentées. Comme je continue à taper au curseur, tout nouveau code est correctement indenté. Dans Emacs, cependant, par défaut dans mon mode cc (mode csharp, mode java, etc.), une commande open-curly exécute self-insert-commande qui insère simplement l'accolade ouverte sans retrait. Le bouclé court c-électrique-accolade, qui indent le bouclé proche seulement, pas toute la portée. Le résultat est alors que je saisis dans la portée bouclée, l'indentation est tout faux, et je dois re-indenter manuellement la portée bouclée quand il se ferme.Accolade électrique intelligente dans les modes cc (C#, Java, etc.)
Existe-t-il un moyen facile de faire en sorte qu'Emacs se comporte comme les IDE courants que j'ai utilisés? J'ai écrit quelques Emacs Lisp à faire, mais ce n'est pas très général et je veux savoir si je mets quelque chose en erreur.
Je connais la fonction skeleton-pair-insert-maybe. Il insère des paires appariées de : accolades, parenthèses, guillemets, chevrons et crochets. Mais cette fonction n'effectue pas d'indentation contextuelle et ne me donne pas le retour à la ligne vide. Existe-t-il un moyen de le mettre en retrait ou ... y a-t-il une autre fonction que je devrais lier à ouvrir-bouclée pour obtenir ce que je veux?
PS: mon Emacs Lisp ressemble à ceci:
; The default binding for "open curly" was skeleton-pair-insert-maybe. It
; inserts a pair of braces and then does not insert a newline, and does not
; indent. I want the braces to get newlines and appropriate indenting. I
; think there is a way to get this to happen appropriately just within emacs,
; but I could not figure out how to do it. So I wrote this alternative. The
; key thing is to determine if the point is within a string. In cc-mode, this
; is at least sometimes done by looking at the font face. Then, if not in a
; literal string, do the appropriate magic. This seems to work.
(defun cheeso-insert-open-brace()
"if point is not within a quoted string literal, insert an open brace, two newlines, and a close brace; indent everything and leave point on the empty line. If point is within a string literal, just insert a pair or braces, and leave point between them."
(interactive)
(if
; are we inside a string?
(c-got-face-at (point) c-literal-faces)
; if so, then just insert a pair of braces and put the point between them
(progn
(self-insert-command 1)
(insert "}")
(backward-char)
)
; not inside a literal string.
; therefore, insert paired braces with an intervening newline, and indent everything appropriately.
(progn
(self-insert-command 1)
(c-indent-command)
(newline)
(insert "}")
(c-indent-command)
(previous-line)
(newline-and-indent)
; point ends up on an empty line, within the braces, properly indented
)
)
)
Merci pour cela. Juste un sidenote, si vous ne voulez pas utiliser le style indentation bsd-like, mais au lieu de garder le premier accolade sur la même chose, il suffit de supprimer (si (cheeso-avant-sexp-même-déclaration-même ligne) (newline-and-indent)) à partir de la fonction cheeso-insert-open-brace. – sluukkonen
Je dois dire que cela ressemble à beaucoup de codes pour accomplir un si petit geste; Je me demande s'il existe une solution plus élégante à cela. – polyglot
Je suis d'accord; J'ai été déçu de la quantité de code que j'ai dû écrire pour que je fasse ce que je voulais. Mais, jusqu'à présent, personne n'a suggéré une façon plus simple de le faire. – Cheeso