Menutup semua tanda kurung yang tertunda

14

Saat menulis kode lisp, kadang-kadang saya tenggelam dalam ekspresi bersarang dan yang saya inginkan adalah memasukkan semua kurung tutup yang hilang. Saat ini saya hanya memasukkan mereka sampai saya mendapatkan paren yang tidak cocok, tetapi itu tidak terlalu efisien.
Apakah ada perintah untuk memasukkan semua tanda kurung yang hilang?

FYI, saya menggunakan smartparens untuk secara otomatis memasukkan parens yang cocok. Tetap saja, terkadang saya hanya perlu melakukan ini.

rlazo
sumber
2
FWIW, Franz Lisp (sebelum CL) memiliki fitur di mana a ]bertindak sebagai paren super kanan, menutup semua paren terbuka, seperti yang Anda minta.
Drew
2
Saya telah menggunakan metodologi yang sama di masa lalu. Sejak itu saya mulai menggunakan paredit , yang menghentikan masalah sebelum dimulai. Satu-satunya peringatan adalah bahwa menempelkan kode tidak mendapatkan perlakuan penyeimbangan yang sama.
Elarson

Jawaban:

6

Inilah fungsi yang menutup semua kurung tertutup dan pasangan yang cocok lainnya. Itu bergantung pada penguraian sexp Emacs. Ini hanya mendukung pasangan yang cocok dengan satu karakter, jadi sesuatu seperti {-akan ditutup }, bukan -}. Bagi Lisp, itu tidak masalah.

(defun close-all-parentheses ()
  (interactive "*")
  (let ((closing nil))
    (save-excursion
      (while (condition-case nil
         (progn
           (backward-up-list)
           (let ((syntax (syntax-after (point))))
             (case (car syntax)
               ((4) (setq closing (cons (cdr syntax) closing)))
               ((7 8) (setq closing (cons (char-after (point)) closing)))))
           t)
           ((scan-error) nil))))
    (apply #'insert (nreverse closing))))
Gilles 'SANGAT berhenti menjadi jahat'
sumber
IIUC, ini mengharuskan titik itu tidak berada di dalam set kurung yang cocok. Saya mendapat kesan bahwa OQ perlu bekerja dari beberapa orang di dalam ekspresi lisp, di mana tanda kurung yang dibuat tidak sesuai tetapi yang lain tidak.
Malabarba
@Malabarba Ini menutup semua tanda kurung yang dibuka sebelumnya, apakah mereka sudah memiliki tanda kurung penutup yang cocok setelah poin atau tidak. Begitulah cara saya memahami pertanyaan itu, tetapi harus diakui tidak jelas tentang hal ini. Di bawah interpretasi Anda, di mana pembatas penutup akan dimasukkan? Misalnya dengan ([-!-foo], apakah Anda memasukkan ])pada titik, atau )setelah foo]?
Gilles 'SO- stop being evil'
dari pemahaman saya, jika sudah ([-!-foo], saya akan memasukkan )setelah foo]. Tapi tentu saja saya bisa salah. Mungkin @rlazo bisa menguraikan.
Malabarba
untuk kasus penggunaan saya, @Gilles benar, saya tidak peduli jika pembatas ditutup setelah titik, saya ingin menutup semuanya sebelum titik.
rlazo
3

Saya telah menemukan bahwa jika Anda telah menginstal lendir, ada perintah untuk melakukan ini, dipanggil slime-close-all-parens-in-sexp

rlazo
sumber
Hmm ... jadi ini tampaknya menutup pada baris saat ini. Mungkin menyenangkan jika ada pendekatan yang menutup "blok saat ini". Ini dapat dicapai dengan pergi ke akhir file dan kemudian bergerak ke belakang sexp sampai sesuatu yang tidak ditemukan ditemukan.
Att Righ
1

Cara yang sangat primitif (dan hampir pasti salah) untuk melakukannya

(defun buffer-needs-parens-fixing ()
  (save-excursion
    (condition-case nil
        (check-parens)
      (error (point)))))

(defun buffer-fix-parens ()
  (interactive)
  (while (buffer-needs-parens-fixing)
    (insert ")")))

Di antara keterbatasan lainnya, diasumsikan bahwa semua kurung yang perlu dimasukkan adalah:

  • yang menutup
  • dibutuhkan di lokasi saat ini

Saya kira itu mungkin cukup berguna untuk kasus penggunaan khusus Anda

Sigma
sumber
Ini macet dalam loop tak terbatas jika Anda memiliki terlalu banyak tanda kurung tutup.
Emil Vikström
@ EmilVikström ya, itu memang tidak kompatibel dengan batasan pertama saya :)
Sigma