Bagaimana cara memformat kode (masukkan baris baru secara otomatis, indentasi, dll)?

24

Saya menggunakan spacemacstetapi mungkin pengetahuan emacs yang diperlukan di sini.

Saya memiliki file JSON dengan satu baris panjang, misalkan JSON ini dari json.org/example:

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

Saya ingin emacs untuk mengaktifkan kembali ini, yang berarti bagi saya tidak mengubah karakter garis paling kiri ke tingkat lekukan yang tepat, tetapi memecah garis dalam beberapa baris.

Jika saya menggunakan spacemacs/indent-region-or-buffer( SPC j =) maka teks tidak berubah sama sekali.

Bagaimana saya bisa meminta dari emacs untuk benar-benar memutus garis panjang ini dan reindent untuk mendapatkan sesuatu seperti ini:

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

Saya tidak tertarik dengan jawaban khusus JSON, misalnya saya percaya bahwa IntelliJ melakukan itu untuk bahasa apa pun yang didukungnya (java, json ...). Saya pikir itu dapat dicapai karena emacs bahasa apa pun memiliki mode utama, atau katakanlah yang paling populer.

EDIT Saya menemukan M-x json-reformat-regionbahwa spacemacskapal dengan dan bekerja, tapi ya, saya ingin itu untuk bahasa apa pun dan dengan selalu pintasan yang sama, berdasarkan mode utama ...

EDIT2 Ok jadi kesimpulan saya adalah bahwa ini diterapkan untuk berbagai bahasa, setidaknya JSON & lisp, mungkin orang lain, dan itu akan lebih mudah untuk lebih banyak lagi (XML / XHTML, go yang telah go-fmt dan juga menggunakan dentang). Namun tidak ada nama fungsi generik yang akan melakukannya untuk semua bahasa. Ada ruang di sini untuk mengimplementasikannya dalam spacemacslapisan untuk berbagai bahasa ... Saya tidak menemukan implementasi X / HTML, yang sedikit mengejutkan saya.

Emmanuel Touzery
sumber
3
Untuk HTML / JS / CSS: web-beautiful.el. Ini adalah yang terbaik yang saya temukan, tetapi itu tergantung pada node.js.
pengasuh

Jawaban:

10

Sepertinya Anda membutuhkan fill-regionfungsi lebih dari indentasi.

  • Pilih garis itu dan lakukan M-x fill-region.
  • Pilih yang sama, sekarang dibagi di beberapa baris, dan lakukan M-x indent-region.

Namun, itu tidak akan menyisipkan baris baru pada titik yang tepat seperti yang ditunjukkan pada contoh Anda. Ini hanya akan membuat garis pas di kolom isian.

Kaushal Modi
sumber
1
yah, itu sesuatu. Mungkin apa yang saya inginkan tidak dapat dicapai. Mungkin saya akan menunggu sedikit lebih lama jika seseorang memiliki solusi ajaib untuk lekukan agresif yang lebih cerdas ... Jika tidak ada yang muncul saya akan menandai ini sebagai jawabannya.
Emmanuel Touzery
@EmmanuelTouzery Apa yang Anda inginkan dapat dicapai dengan sedikit kesalahan selama aturan untuk memasukkan baris baru konsisten. Dalam contoh hasil yang diformat, saya melihat bahwa Anda tidak memiliki baris baru setelah {dalam {"menu":tetapi Anda memiliki satu setelah {dalam {"id":. Saya tidak tahu JSON dan jawaban terformat Anda mungkin memang memiliki pola yang saya lewatkan. Tetapi jika Anda dapat memperbarui pertanyaan Anda dengan seperangkat aturan untuk memasukkan baris baru itu, maka seseorang dapat menemukan jawaban yang Anda inginkan.
Kaushal Modi
Saya pikir itu akan ada untuk bahasa apa pun, termasuk aturan khusus bahasa. Misalnya {pada baris pertama untuk java, pada baris berikutnya untuk C # katakanlah, dan seterusnya.
Emmanuel Touzery
(dengan kata lain, seperti gofmttetapi untuk bahasa apa pun) - gofmt.com
Emmanuel Touzery
19

json.elpaket menyediakan json-pretty-print-buffer. Inilah yang dihasilkannya sebagai contoh Anda:

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

Sepertinya cukup baik untukku.

wvxvw
sumber
2
Ya sebenarnya saya melihat di github.com/gongo/json-reformat bahwa "Dari emacs 24.4, json-pretty-printdan json-pretty-print-buffer(spesifikasi yang sama dengan json-reformat-region) dibundel.". Tapi saya pikir emacs dapat memiliki fungsi yang akan bekerja untuk semua bahasa (khusus untuk setiap bahasa mode utama populer), yang ternyata, tidak.
Emmanuel Touzery
ini jawaban yang benar
Joe Heyming
6

Menurut tip di sini , Anda dapat menggunakan perintah eksternal untuk memformat wilayah di file Json Anda:

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

Anda dapat dengan mudah mengembangkannya untuk memformat seluruh buffer:

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

Emacs tidak memiliki alat pemformatan untuk bahasa pemrograman ( kecuali untuk Lisp ), hanya perintah indentasi.

Tu Do
sumber
1
Saya menemukan M-x json-reformat-regionbahwa spacemacskapal dengan dan bekerja, tapi ya, saya ingin itu untuk bahasa apa pun dan dengan selalu pintasan yang sama, berdasarkan mode utama ... Tampaknya ini tidak didukung, terlalu buruk ...
Emmanuel Touzery
1
Untuk memformat bahasa dengan benar, Anda memerlukan parser bahasa yang sebenarnya. Emacs memiliki parser bahasa bawaan untuk beberapa bahasa, tetapi hanya parser Lisp bawaan yang baru-baru ini digunakan untuk memformat ulang kode, seperti tautan ke demo di atas. Jika ada format eksternal, mudah untuk diintegrasikan dengan Emacs clang-format.
Tu Do
2

Untuk skenario khusus ini json-pretty-printakan melakukan prettify pada benjolan yang disorot dari json.

Fergie
sumber
1

BTW, untuk mode utama menggunakan SMIE sebagai mesin indentasi mereka, ada beberapa bagian yang Anda perlukan untuk itu dalam bentuk auto-fill-modedukungan. Saya pikir fill-paragraphatau fill-regiontidak akan melakukan pekerjaan dengan baik, tetapi jika Anda meletakkan kode Anda ke satu baris, kemudian pergi ke akhir baris itu dan lakukan M-: (smie-auto-fill)itu akan memberikan hasil yang waras (mungkin tidak sempurna oleh peregangan panjang, tho).

Stefan
sumber