Memodifikasi lekukan beberapa bentuk Emacs Lisp

8

Saya ingin beberapa bentuk Emacs Lisp diindentasi seperti Common Lisp. Misalnya, di Emacs Lisp, ifindentasi seperti ini:

(if COND
    THEN
  ELSE)

sementara saya lebih suka seperti ini:

(if COND
    THEN
    ELSE)

Saya bisa melakukan ini:

(setq lisp-indent-function #'common-lisp-indent-function)

Tapi ini berdampak pada semua bentuk, sehingga melanggar lekukan makro Emacs Lisp, seperti cl-letfdan makro apa pun yang ditetapkan pengguna.

Elena
sumber

Jawaban:

17

Menjawab:

Simbol untuk fungsi dan makro memiliki lisp-indent-functionproperti yang dapat Anda atur dengan declareatau dalam kasus Anda, karena ifsudah ditentukan, Anda bisa menggunakannya put.

Anda dapat membaca tentang kemungkinan nilai properti di sini:

M-: (info "(elisp) Indenting Macros") return

ifPengaturan default adalah 2yang berarti bentuk kedua mendapatkan perlakuan khusus dan diimbangi.

Anda dapat mengubah nilai properti menjadi 'defundan semua formulir tubuh akan berbaris.

(put 'if 'lisp-indent-function 'defun)

Praktek terbaik:

Penting untuk dicatat bahwa ada alasan untuk gaya lekukan. ifdi Elisp TIDAK seperti ifdi Common Lisp.

Perhatikan tanda tangan yang berbeda:

Gangguan Umum: (if TEST THEN &OPTIONAL ELSE)

Emacs Lisp: (if COND THEN ELSE...)

Dalam Emacs lisp, Anda dapat memiliki banyak bentuk setelah kondisi yang Anda inginkan tetapi hanya bentuk pertama adalah klausa THEN, semua bentuk lainnya adalah bagian dari klausa ELSE.

Ini adalah ifformulir Elisp yang valid yang tidak valid di CL:

(if something
    (message "THEN")
  (message "all")
  (message "these")
  (message "run")
  (message "on")
  (message "ELSE"))

Ini menunjukkan mengapa penting bahwa klausa LALU lebih menjorok, itu membuatnya menonjol terhadap semua bentuk ELSE.

Selain lekukan yang penting bagi kemampuan pengguna untuk mengurai kode, itu juga akan bertentangan dengan pola gaya elisp yang diterima. 99,99999% (dihitung secara carfefully) dari kode elisp yang Anda temui akan menggunakan skema indentasi default yang persis sama. Mengubah lekukan ifuntuk Anda gunakan sendiri akan menyulitkan Anda untuk bekerja pada orang lain dan membuatnya sulit bagi orang lain untuk mengerjakan milik Anda.

Jordon Biondo
sumber
2

Saya sebenarnya menggunakan indentasi Lisp Umum, dengan indentasi Elisp untuk if. Anda dapat menyesuaikan beberapa kode yang mirip dengan milik saya:

(setq lisp-indent-function 'common-lisp-indent-function)
(eval-after-load 'cl-indent
  `(progn
     (put 'cl-flet 'common-lisp-indent-function
          (get 'flet 'common-lisp-indent-function))
     (put 'cl-labels 'common-lisp-indent-function
          (get 'labels 'common-lisp-indent-function))
     (put 'if 'common-lisp-indent-function 2)))
abo-abo
sumber
Terima kasih, tetapi ini akan mengharuskan saya untuk memperbaiki lekukan semua makro yang ditentukan pengguna juga. Saya lebih suka mengikuti rute yang berlawanan dan memperbaiki lekukan ifseperti yang dilakukan oleh lisp-indent-function.
Elena
Saya sudah memiliki konfigurasi ini selama bertahun-tahun. Ada nol makro lain yang perlu saya "perbaiki". Ingatlah untuk meletakkan declarepernyataan di setiap makro baru, yang bagus untuk dilakukan dalam hal apa pun.
abo-abo