Làm thế nào để mã định dạng đẹp (tự động chèn dòng mới, thụt lề, v.v.)?


24

Tôi đang sử dụng spacemacsnhưng có lẽ đó là kiến ​​thức cần thiết ở đây.

Tôi có một tệp JSON với một dòng dài, hãy nói JSON này từ json.org/example:

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

Tôi muốn emacs nhắc lại điều này, điều đó có nghĩa là tôi không thay đổi ký tự ngoài cùng bên trái thành mức thụt lề thích hợp, nhưng ngắt dòng thành nhiều dòng.

Nếu tôi sử dụng spacemacs/indent-region-or-buffer( SPC j =) thì văn bản hoàn toàn không thay đổi.

Làm thế nào tôi có thể yêu cầu từ emacs thực sự phá vỡ dòng dài này và giới thiệu để có được một cái gì đó như thế này:

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

Tôi không quan tâm đến câu trả lời dành riêng cho JSON, ví dụ tôi tin rằng intelliJ thực hiện điều đó cho bất kỳ ngôn ngữ nào mà nó hỗ trợ (java, json ...). Tôi nghĩ rằng có thể đạt được cho bất kỳ emacs ngôn ngữ nào có chế độ chính cho, hoặc giả sử những ngôn ngữ phổ biến nhất.

EDIT Tôi phát hiện ra M-x json-reformat-regionrằng spacemacstàu có và hoạt động, nhưng vâng, tôi muốn điều đó cho bất kỳ ngôn ngữ nào và luôn có cùng một phím tắt, dựa trên chế độ chính ...

EDIT2 Ok vì vậy, kết luận của tôi là nó được triển khai cho nhiều ngôn ngữ khác nhau, ít nhất là JSON và lisp, có lẽ là những ngôn ngữ khác, và nó sẽ dễ dàng hơn nữa (XML / XHTML, sử dụng tiếng kêu và cũng sử dụng tiếng kêu). Tuy nhiên, không có tên hàm chung nào có thể làm điều đó cho tất cả các ngôn ngữ. Có không gian ở đây để triển khai nó trong spacemacscác lớp cho các ngôn ngữ khác nhau ... Tôi đã không tìm thấy triển khai X / HTML, điều này làm tôi ngạc nhiên một chút.


3
Đối với HTML / JS / CSS : web-beautiful.el. Đây là thứ tốt nhất tôi tìm thấy, nhưng nó phụ thuộc vào node.js.
mẫu

Câu trả lời:


10

Có vẻ như bạn cần fill-regionchức năng nhiều hơn thụt đầu dòng.

  • Chọn dòng đó và làm M-x fill-region.
  • Chọn giống nhau, bây giờ chia thành nhiều dòng và làm M-x indent-region.

Tuy nhiên, điều đó sẽ không chèn các dòng mới vào các điểm chính xác như trong ví dụ của bạn. Nó chỉ đơn giản là làm cho dòng phù hợp trong các cột điền.


1
tốt, đó là một cái gì đó. Có lẽ những gì tôi muốn không thể đạt được dù sao. Có lẽ tôi sẽ đợi thêm một thời gian nữa trong trường hợp ai đó có một giải pháp kỳ diệu cho một vết lõm hung hăng thông minh hơn ... Nếu không có gì khác xuất hiện tôi sẽ đánh dấu đây là câu trả lời.
Emmanuel Touzery

@EmmanuelTouzery Những gì bạn muốn có thể đạt được với ít elisp miễn là các quy tắc để chèn dòng mới là nhất quán. Trong ví dụ của bạn về kết quả định dạng, tôi thấy rằng bạn không có một dòng mới sau {trong {"menu":nhưng bạn phải lần lượt {tại {"id":. Tôi không biết JSON và vì vậy câu trả lời được định dạng của bạn có thể có một mẫu mà tôi đang thiếu. Nhưng nếu bạn có thể cập nhật câu hỏi của mình với một bộ quy tắc để chèn dòng mới đó, thì ai đó có thể đưa ra câu trả lời bạn muốn.
Kaushal Modi

Tôi nghĩ rằng nó đã tồn tại cho bất kỳ ngôn ngữ nào, bao gồm các quy tắc dành riêng cho ngôn ngữ. Ví dụ: {trên dòng đầu tiên cho java, trên dòng tiếp theo cho C # hãy nói, v.v.
Emmanuel Touzery

(nói cách khác, một cái gì đó giống như gofmtnhưng đối với bất kỳ ngôn ngữ nào) - gofmt.com
Emmanuel Touzery

19

json.elgói cung cấp json-pretty-print-buffer. Đây là những gì nó tạo ra cho ví dụ của bạn:

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

Có vẻ khá tốt với tôi.


2
Có trong thực tế tôi đã thấy trên github.com/gongo/json-reformat rằng "Từ emacs 24.4 json-pretty-printjson-pretty-print-buffer(thông số kỹ thuật tương tự như json-reformat-region) đã được đóng gói." Nhưng tôi nghĩ emacs có thể có chức năng hoạt động cho tất cả các ngôn ngữ (cụ thể cho từng ngôn ngữ chế độ chính phổ biến), nhưng nó, như hóa ra, không.
Emmanuel Touzery

đây là câu trả lời đúng
Joe Heyming

6

Theo mẹo ở đây , bạn có thể sử dụng lệnh bên ngoài để định dạng một vùng trong tệp Json của mình:

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

Bạn có thể dễ dàng mở rộng nó để định dạng toàn bộ bộ đệm:

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

Emacs không có công cụ định dạng cho các ngôn ngữ lập trình ( ngoại trừ Lisp ), chỉ có các lệnh thụt lề.


1
Tôi phát hiện ra M-x json-reformat-regionrằng spacemacstàu có và hoạt động, nhưng vâng, tôi muốn điều đó cho bất kỳ ngôn ngữ nào và luôn luôn có cùng một phím tắt, dựa trên chế độ chính ... Có vẻ như điều này không được hỗ trợ, quá tệ ...
Emmanuel Touzery

1
Để định dạng đúng ngôn ngữ, bạn cần một trình phân tích cú pháp ngôn ngữ thực tế. Emacs có trình phân tích cú pháp ngôn ngữ tích hợp cho một số ngôn ngữ, nhưng chỉ có trình phân tích cú pháp Lisp tích hợp gần đây được sử dụng để định dạng lại mã, như liên kết đến bản demo ở trên. Nếu các trình định dạng bên ngoài tồn tại, rất dễ tích hợp với Emacs tức là clang-format.
Từ Đỗ

2

Đối với kịch bản cụ thể này json-pretty-printsẽ làm đẹp thêm phần nổi bật của json.


1

BTW, đối với các chế độ chính sử dụng SMIE làm công cụ thụt đầu dòng của chúng, có một phần của những gì bạn cần cho nó dưới dạng auto-fill-modehỗ trợ. Tôi nghĩ fill-paragraphhoặc fill-regionsẽ không làm tốt công việc, nhưng nếu bạn đặt mã của mình vào một dòng duy nhất, thì hãy đi đến cuối dòng đó và làm M-: (smie-auto-fill)nó sẽ cho kết quả lành mạnh (có thể không hoàn hảo bởi một đoạn dài, tho).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.