In verschiedenen IDEs führt die Eingabe von Open-Curly zu einem übereinstimmenden Klammerpaar. In der Regel werden die geschweiften Klammern in einer kontextabhängigen Weise eingefügt. In einem Zeichenfolgenliteral wird keine neue Zwischenzeile zwischen den geschweiften Klammern eingefügt. Außerhalb eines String-Literals gibt es eine neue Zeile, und die Dinge werden sofort eingerückt.Intelligente elektrische Klammer in cc-modes (C#, Java usw.)
Während ich weiter am Cursor tippe, wird der gesamte neue Code korrekt eingerückt. In Emacs, standardmäßig in meinem cc-Modus (csharp-mode, java-mode, usw.), führt ein open-locked den Befehl self-insert aus, der nur die offene Klammer ohne Einrückung einfügt. Die eng-lockige läuft c-electric-brace, die nur die enge lockig, nicht den vollen Umfang einzieht. Das Ergebnis ist, während ich in den geschweiften Bereich eingeben, die Einrückung ist falsch, und ich muss den geschweiften Bereich manuell neu einrücken, wenn es geschlossen wird.
Gibt es einen einfachen Weg, um Emacs dazu zu bringen, sich wie die populären IDEs zu verhalten, die ich benutzt habe? Ich habe ein paar Emacs Lisp geschrieben, aber es ist nicht sehr allgemein und ich möchte wissen, ob ich etwas verpasse.
Ich weiß über die Skelett-Paar-Insert-Maybe-Funktion. Es fügt passende Paare von was auch immer: Klammern, Parens, Zitate, spitze Klammern, eckige Klammern. Diese Funktion führt jedoch keine kontextsensitive Einrückung durch und gibt mir keine leere Zeilenschaltung. Gibt es eine Möglichkeit, um es zu Einzug oder ... gibt es eine andere Funktion, die ich an Open-lockig binden sollte, um zu bekommen, was ich will?
PS: meine Emacs Lisp sieht wie folgt aus:
; 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
)
)
)
Dank dafür. Nur eine Randnotiz, wenn Sie nicht möchten, dass die bsd-like Einrückungsstil, sondern stattdessen die erste geschweifte Klammer auf die gleiche, löschen Sie einfach (if (cheeso-vorherige-sexp-same-Anweisung-same-line) (newline-and-indent)) aus der Funktion cheeso-insert-open-brace. – sluukkonen
Ich muss sagen, das sieht nach einer Menge Codes aus, um so eine kleine Geste zu erreichen; Ich frage mich, ob es eine elegantere Lösung dafür gibt. – polyglot
stimme ich zu; Ich war enttäuscht von der Menge an Code, den ich schreiben musste, um das zu tun, was ich wollte. Aber bisher hat niemand einen einfacheren Weg vorgeschlagen, um das zu erreichen. – Cheeso