Come si può formattare il codice (inserire automaticamente nuove righe, rientro, ecc.)?


24

Sto usando spacemacsma presumibilmente è la conoscenza di emacs che è richiesta qui.

Ho un file JSON con una sola linea lunga, diciamo questo JSON da json.org/example:

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

Vorrei che Emacs lo reindentasse, il che significa per me non cambiare il carattere più a sinistra della linea con il livello di rientro corretto, ma spezzare la linea in più righe.

Se uso spacemacs/indent-region-or-buffer( SPC j =) il testo non viene affatto modificato.

Come potrei chiedere a Emacs di rompere effettivamente questa lunga fila e di ricorrere per ottenere qualcosa del genere:

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

Non mi interessa una risposta specifica per JSON, ad esempio credo che intelliJ lo faccia per qualsiasi linguaggio supportato (java, json ...). Penso che sia realizzabile per qualsiasi lingua. Emacs ha una modalità importante per, o diciamo, le più popolari.

EDIT Ho scoperto M-x json-reformat-regionche viene spacemacsfornito con e funziona, ma sì, mi piacerebbe che per qualsiasi lingua e con sempre la stessa scorciatoia, basato sulla modalità principale ...

EDIT2 Ok, quindi la mia conclusione è che è implementato per varie lingue, almeno JSON e lisp, presumibilmente altri, e sarebbe facile per ancora di più (XML / XHTML, go che ha funzionato e anche usando clang). Tuttavia, non esiste un nome di funzione generico che lo farebbe per tutte le lingue. Qui c'è spazio per implementarlo a spacemacsstrati per le varie lingue ... Non ho trovato un'implementazione X / HTML, il che mi sorprende un po '.


3
Per HTML / JS / CSS: web-beautiful.el. Questo è il migliore che ho trovato, ma dipende da node.js.
tata

Risposte:


10

Sembra che tu abbia bisogno della fill-regionfunzione più del rientro.

  • Seleziona quella riga e fai M-x fill-region.
  • Seleziona lo stesso, ora diviso su più righe e fai M-x indent-region.

Ciò, tuttavia, non inserirà nuove linee nei punti esatti, come mostrato nel tuo esempio. Adatterà semplicemente la linea alle colonne di riempimento.


1
bene, questo è qualcosa. Forse quello che volevo non era realizzabile comunque. Forse aspetterò ancora un po 'nel caso in cui qualcuno abbia una soluzione magica per un rientro aggressivo più intelligente ... Se non viene fuori niente, lo segnerò come risposta.
Emmanuel Touzery,

@EmmanuelTouzery Quello che vuoi è realizzabile con un po 'di elisp purché le regole per l'inserimento della nuova riga siano coerenti. Nel vostro esempio di risultato formattato, vedo che non si dispone di un ritorno a capo dopo {in {"menu":ma avete uno dopo l' {in {"id":. Non conosco JSON e quindi la tua risposta formattata probabilmente ha uno schema che mi manca. Ma se riesci ad aggiornare la tua domanda con una serie di regole per l'inserimento di quella nuova riga, allora qualcuno può trovare la risposta che desideri.
Kaushal Modi,

Ho pensato che sarebbe esistito per qualsiasi lingua, comprese le regole specifiche della lingua. Ad esempio {sulla prima riga per Java, sulla riga successiva per C # diciamo e così via.
Emmanuel Touzery,

(in altre parole, qualcosa di simile gofmtma per qualsiasi lingua) - gofmt.com
Emmanuel Touzery,

19

json.elil pacchetto fornisce json-pretty-print-buffer. Questo è ciò che produce per il tuo esempio:

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

Sembra abbastanza decente per me.


2
Sì, in effetti ho visto su github.com/gongo/json-reformat che "Da emacs 24.4 json-pretty-printe json-pretty-print-buffer(specifiche simili a json-reformat-region) è stato raggruppato". Ma ho pensato che emacs potesse avere una funzione che avrebbe funzionato per tutte le lingue (specifiche per ciascuna lingua popolare in modalità principale), cosa che, a quanto pare, non ha.
Emmanuel Touzery,

questa è la risposta corretta
Joe Heyming,

6

Secondo il suggerimento qui , puoi usare un comando esterno per formattare una regione nel tuo file Json:

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

Puoi facilmente estenderlo per formattare l'intero buffer:

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

Emacs non ha uno strumento di formattazione per i linguaggi di programmazione ( tranne Lisp ), ma solo i comandi di rientro.


1
Ho scoperto M-x json-reformat-regionche viene spacemacsfornito con e funziona, ma sì, lo vorrei per qualsiasi lingua e con sempre la stessa scorciatoia, basato sulla modalità principale ... Sembra che questo non sia supportato,
peccato

1
Per formattare correttamente una lingua, è necessario un parser di lingua reale. Emacs ha parser di lingua incorporato per alcune lingue, ma solo il parser Lisp incorporato è stato recentemente utilizzato per la riformattazione del codice, come collegamento alla demo sopra. Se esistono formattatori esterni, è facile integrarsi con Emacs ie clang-format.
Tu Do,

2

Per questo specifico scenario json-pretty-printsi prettificherà il grumo evidenziato di json.


1

A proposito, per le principali modalità che utilizzano SMIE come motore di indentazione, c'è una parte di ciò che ti serve sotto forma di auto-fill-modesupporto. Credo che fill-paragrapho fill-regionnon voglio fare un lavoro buono, ma se si mette il codice su una sola riga, poi andare alla fine di quella linea e farlo M-: (smie-auto-fill)dovrebbe dare risultati sane (probabilmente non perfetto per un lungo tratto, tho).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.