Wie formatiere ich Code hübsch (Zeilenumbrüche, Einrückungen usw. automatisch einfügen)?

24

Ich benutze, spacemacsaber vermutlich ist es Emacs Wissen, das hier erforderlich ist.

Ich habe eine JSON-Datei mit einer langen Zeile. Sagen wir, diese JSON von json.org/example:

{"menu": {"id": "file", "value": "File", "popup": {"menuitem": [{"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"}]}}}

Ich möchte, dass Emacs dies erneut einfügt, was bedeutet, dass ich das Zeichen ganz links in der Zeile nicht auf die richtige Einrückungsstufe ändere, sondern die Zeile in mehrere Zeilen aufteilt.

Wenn ich spacemacs/indent-region-or-buffer( SPC j =) benutze, wird der Text überhaupt nicht geändert.

Wie könnte ich von Emacs verlangen, diese lange Schlange zu durchbrechen und erneut zu versuchen, so etwas zu bekommen:

{"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}

Ich bin nicht an einer JSON-spezifischen Antwort interessiert, zum Beispiel glaube ich, dass intelliJ das für jede Sprache tut, die es unterstützt (Java, JSON ...). Ich würde denken, dass es für jede Sprache erreichbar ist, für die Emacs einen Hauptmodus hat, oder lassen Sie uns die beliebtesten sagen.

BEARBEITEN Ich habe festgestellt, M-x json-reformat-regiondass es spacemacsmit und funktioniert, aber ja, ich würde es für jede Sprache und mit immer der gleichen Abkürzung, basierend auf dem Hauptmodus, mögen ...

EDIT2 Ok, also meine Schlussfolgerung ist, dass es für verschiedene Sprachen implementiert ist, JSON & lisp zumindest, vermutlich für andere, und es wäre für noch mehr einfach (XML / XHTML, go was go-fmt hat und auch clang verwendet). Es gibt jedoch keinen generischen Funktionsnamen, der dies für alle Sprachen tun würde. Hier ist Platz, um es in spacemacsEbenen für die verschiedenen Sprachen zu implementieren ... Ich habe jedoch keine X / HTML-Implementierung gefunden, was mich ein bisschen überrascht.

Emmanuel Touzery
quelle
3
Für HTML / JS / CSS: web-beautiful.el. Das ist das Beste, was ich gefunden habe, aber es hängt von node.js ab.
Kindermädchen

Antworten:

10

Anscheinend benötigen Sie die fill-regionFunktion mehr als die Einrückung.

  • Wählen Sie diese Linie und machen Sie M-x fill-region.
  • Wählen Sie dasselbe aus und teilen Sie es auf mehrere Zeilen auf M-x indent-region.

Dadurch werden jedoch keine neuen Linien an den exakten Punkten eingefügt, wie in Ihrem Beispiel gezeigt. Dadurch wird die Linie einfach in die Füllspalten eingepasst.

Kaushal Modi
quelle
1
Nun, das ist etwas. Vielleicht war das, was ich wollte, sowieso nicht erreichbar. Vielleicht warte ich etwas länger, falls jemand eine magische Lösung für eine intelligentere aggressive Einrückung hat ... Wenn nichts anderes auftaucht, werde ich dies als Antwort markieren.
Emmanuel Touzery
@EmmanuelTouzery Was Sie wollen, ist mit wenig Aufwand erreichbar, solange die Regeln für das Einfügen des Zeilenumbruchs konsistent sind. In Ihrem Beispiel von formatiertem Ergebnis, sehe ich , dass Sie nicht eine neue Zeile nach haben {in , {"menu":aber Sie haben eine nach {in {"id":. Ich kenne JSON nicht und daher hat Ihre formatierte Antwort wahrscheinlich ein Muster, das mir fehlt. Wenn Sie Ihre Frage jedoch mit einer Reihe von Regeln zum Einfügen dieser neuen Zeile aktualisieren können, kann jemand die gewünschte Antwort finden.
Kaushal Modi
Ich dachte, dass es das für jede Sprache gegeben hätte, einschließlich sprachspezifischer Regeln. Zum Beispiel {in der ersten Zeile für Java, in der nächsten Zeile für C # und so weiter.
Emmanuel Touzery
(mit anderen Worten, so etwas wie, gofmtaber für jede Sprache) - gofmt.com
Emmanuel Touzery
19

json.elPaket bietet json-pretty-print-buffer. Dies ist, was es für Ihr Beispiel erzeugt:

{
  "menu": {
    "popup": {
      "menuitem": [
        {
          "onclick": "CreateNewDoc()",
          "value": "New"
        },
        {
          "onclick": "OpenDoc()",
          "value": "Open"
        },
        {
          "onclick": "CloseDoc()",
          "value": "Close"
        }
      ]
    },
    "value": "File",
    "id": "file"
  }
}

Scheint mir ziemlich anständig.

wvxvw
quelle
2
Ja, tatsächlich habe ich auf github.com/gongo/json-reformat gesehen, dass "From Emacs 24.4 json-pretty-printund json-pretty-print-buffer(ähnliche Spezifikationen wie json-reformat-region) gebündelt wurden." Aber ich dachte, Emacs könnte eine Funktion haben, die für alle Sprachen funktioniert (spezifisch für jede populäre Sprache im Hauptmodus), was es, wie sich herausstellt, nicht tut.
Emmanuel Touzery
Dies ist die richtige Antwort
Joe Heyming
6

Gemäß dem hier aufgeführten Tipp können Sie einen Bereich in Ihrer Json-Datei mit dem Befehl external formatieren:

(defun json-format ()
  (interactive)
  (save-excursion
    (shell-command-on-region (region-beginning)
                             (region-end)
                             "python -m json.tool"
                             (buffer-name)
                             t)))

Sie können es einfach erweitern, um den gesamten Puffer zu formatieren:

(defun json-format ()
  (interactive)
  (save-excursion
    (shell-command-on-region (point-min)
                             (point-max)
                             "python -m json.tool"
                             (buffer-name) t))) 

Emacs hat kein Formatierungswerkzeug für Programmiersprachen ( außer Lisp ), nur Einrückungsbefehle.

Tu Do
quelle
1
Ich habe entdeckt, M-x json-reformat-regiondass spacemacsSchiffe mit und arbeiten, aber ja, ich möchte das für jede Sprache und mit immer der gleichen Abkürzung, basierend auf dem
Hauptmodus
1
Um eine Sprache richtig zu formatieren, benötigen Sie einen tatsächlichen Sprachparser. Emacs verfügt für einige Sprachen über integrierte Sprachparser, aber nur der integrierte Lisp-Parser wird kürzlich für die Neuformatierung von Code als Link zur obigen Demo verwendet. Wenn externe Formatierer vorhanden sind, ist es einfach, Emacs zu integrieren, d clang-format. H.
Tu Do
2

Für dieses spezielle Szenario json-pretty-printwird der hervorgehobene Klumpen von Json hübsch aussehen.

Fergie
quelle
1

Übrigens, für Hauptmodi, die SMIE als Einrückungsengine verwenden, gibt es einen Teil dessen, was Sie dafür benötigen, in Form einer auto-fill-modeUnterstützung. Ich denke fill-paragraphoder fill-regionmache keine gute Arbeit, aber wenn Sie Ihren Code in eine einzelne Zeile schreiben, dann gehen Sie ans Ende dieser Zeile und tun Sie M-: (smie-auto-fill)es sollte vernünftige Ergebnisse liefern (wahrscheinlich nicht perfekt bei weitem, obwohl).

Stefan
quelle