Cara mengedit elisp tanpa tersesat di dalam tanda kurung


13

Saya memodifikasi beberapa kode elisp dari linum.el:

(custom-set-variables '(linum-format 'dynamic))
(defadvice linum-update-window (around linum-dynamic activate)
   (let* ((w (length (number-to-string
      (+ (count-lines (point-min) (point-max)) 1))))
         (linum-format (concat " %" (number-to-string w) "d ")))
            ad-do-it))

Saya bisa memperbaiki bug di mana lekukan itu off-per-satu dengan memodifikasi (count-lines (point-min) (point-max))untuk (+ (count-lines (point-min) (point-max)) 1). Itu mudah.

Tapi sekarang saya ingin memodifikasinya sehingga lebar minimum adalah 2 dengan menambahkan if-conditional di mana (concat " %" (number-to-string w) "2d ")jika jumlah barisnya <10.

Ini seharusnya mudah! Tambahkan satu syarat dan salin / tempelkan concat. Sepotong kue, kan? Maksud saya, saya tahu apa yang seharusnya saya lakukan tetapi saya jarang menyentuh elisp dan saya selalu gentar ketika saya harus memodifikasi apa pun dengan banyak tanda kurung.

Gaya "benar", dari apa yang saya mengerti, adalah untuk menyusun kode berdasarkan indentasi dan membungkus tanda kurung di akhir baris daripada pada sendiri. Berasal dari bahasa gaya 'C' lainnya, saya berjuang dengan baik membaca dan menulis kode dengan cara ini. Jadi pertanyaan saya adalah: apa yang saya lakukan salah? Bagaimana saya bisa mengedit elisp dan menavigasi kode sehingga saya tidak harus duduk di sana dan menghitung setiap tanda kurung?

Ketika saya bekerja dengan sesuatu di elisp yang menjadi terlalu dalam, saya harus menutup pintu, menarik tirai, dan mulai memposisikan tanda kurung K&R sehingga saya tidak hanya bisa membaca tetapi memodifikasi benda sialan itu tanpa panik.

Jelas saya melakukan ini semua salah. Bagaimana saya bisa menyentuh elisp seperti ini tanpa rasa takut?

Harap dicatat bahwa pertanyaan saya adalah bagaimana menavigasi dan mengedit elisp bukan sebagai pertanyaan tentang gaya. Saya menggunakan yang berikut ini sebagai panduan gaya: https://github.com/bbatsov/emacs-lisp-style-guide

Pembaruan:

Cara memformat elisp dengan benar sebelum mempermalukan diri Anda di emacs.stackexchange:

Tandai elisp Anda dan lakukan M-x indent-region.

Solusi Masalah:

Bagi mereka yang ingin tahu bagaimana melakukan pembenaran yang tepat untuk linum dengan lebar minimum dua, berikut adalah solusinya:

(defadvice linum-update-window (around linum-dynamic activate)
  (let* ((w (length (number-to-string
                     (+ (count-lines (point-min) (point-max)) 1))))
         (linum-format (if (> w 1)
                           (concat " %" (number-to-string w) "d ")
                         " %2d ")))
    ad-do-it))

1
Semua orang berjuang dengan membaca cadel yang berasal dari C. Hanya butuh waktu, tetapi akhirnya menjadi sangat alami. Anda juga mungkin dapat menyelesaikan masalah Anda dengan mengubah format-linum ke string format seperti "% 2d".
Jordon Biondo

Saya tidak bisa hanya menggunakan %2dkarena sekali lebarnya bergeser ke 3 atau lebih karakter maka itu bergerak dari membawa kanan-dibenarkan ke kiri-dibenarkan.
Zhro

Ada beberapa perpustakaan yang menyoroti tanda kurung yang cocok yang sangat berharga (menurut saya), misalnya highlight-parentheses,; rainbow-delimiters; dll. Ini adalah versi sederhana saya sendiri highlight-parenthesesyang memungkinkan pengguliran tanpa menghapus tanda kurung yang terakhir diwarnai: stackoverflow.com/a/23998965/2112489 Di masa depan, ini adalah satu pertanyaan per pelanggan / utas.
lawlist

1
Kedengarannya seperti masalah Anda benar-benar membaca , bukan mengedit kode Elisp. Anda sepertinya memiliki masalah dalam memahami struktur Lisp, dan itu mengganggu pengeditan Anda.
PythonNut

1
Dalam pembelaan Anda, itu sepotong kode yang cukup buruk. Saya membacanya sendiri salah 3 kali pertama karena itu. Juga, paredit .
Malabarba

Jawaban:


12

Ada sejumlah paket tambahan yang mungkin membantu, seperti paredit, smartparens, dan lispy. Paket-paket ini memudahkan navigasi dan memanipulasi kode lisp sehingga Anda dapat berpikir dalam ekspresi s dan membiarkan editor khawatir tentang menyeimbangkan parens.

Emacs juga memiliki banyak perintah bawaan untuk menangani sexps dan daftar yang layak dipelajari dan dapat membantu Anda lebih terbiasa dengan struktur kode lisp. Ini umumnya terikat dengan C-M-awalan, seperti:

  • C-M-f/ C-M-buntuk bergerak maju / mundur dengan sexp
  • C-M-n/ C-M-puntuk bergerak maju / mundur berdasarkan daftar
  • C-M-u/ C-M-duntuk naik / turun satu tingkat
  • C-M-t untuk menukar dua sexps di sekitar titik
  • C-M-k untuk membunuh sexp
  • C-M-SPC untuk menandai sexp
  • C-M-q untuk indentasi ulang sexp

Contoh kode yang Anda berikan mungkin lebih jelas jika Anda memperbaiki lekukan: beri titik di awal (defadvice...dan tekan C-M-quntuk indentasi ulang seluruh ekspresi. Untuk mengganti (concat...saya akan mulai dengan menempatkan titik di awal sexp dan memukul C-M-ountuk membagi garis sambil menjaga lekukan. Kemudian tambahkan Anda (if..., dan gunakan perintah di atas untuk melompat ke akhir daftar untuk menambahkan paren penutup lain, kembali ke awal untuk indentasi ulang, dll.

Anda mungkin juga ingin menghidupkan show-paren-mode, yang akan menyoroti paren yang sesuai ketika titik berada di awal atau akhir daftar. Anda mungkin lebih suka menyorot seluruh ekspresi daripada paren yang cocok, jadi coba ubahsuaikan show-paren-style.

Seperti @Tyler disebutkan dalam komentar pada jawaban lain, Anda harus melihat manual untuk mempelajari lebih lanjut tentang ini dan perintah terkait.


Catatan yang C-M-qbisa dipanggil dengan argumen awalan ( C-u C-M-q) untuk mencetak ekspresi di titik. Ini akan memecah semuanya pada baris dan indentasi yang terpisah sehingga sarangnya sangat jelas. Anda biasanya tidak ingin kode pelat Anda terlihat seperti itu, tetapi mungkin membantu untuk memahami sedikit kode tanpa secara manual menjalankan K&R penuh di atasnya. (Dan Anda selalu C-x udapat membatalkan).
glucas

6

Cara yang baik untuk mengedit LISP adalah dengan memanipulasi AST, alih-alih karakter atau garis individual. Saya sudah melakukan itu dengan paket saya lispy yang saya mulai 2 tahun yang lalu. Saya pikir sebenarnya perlu sedikit latihan untuk mempelajari bagaimana melakukan ini dengan baik, tetapi bahkan hanya dengan dasar-dasarnya saja sudah dapat membantu Anda.

Saya bisa menjelaskan bagaimana saya akan melakukan perubahan ini:

Langkah 1

Posisi awal biasanya memiliki titik sebelum sexp tingkat atas. Inilah |intinya.

|(defadvice linum-update-window (around linum-dynamic activate)
   (let* ((w (length (number-to-string
      (+ (count-lines (point-min) (point-max)) 1))))
         (linum-format (concat " %" (number-to-string w) "d ")))
            ad-do-it))

Anda ingin memiliki indentasi kode yang benar, jadi tekan isekali. Ini akan memperbaikinya dengan baik.

Langkah 2

Anda ingin menandai "d "dengan suatu wilayah, karena objek yang dapat memanipulasi lispyadalah daftar, yang tidak perlu ditandai, atau urutan simbol atau / dan daftar yang perlu ditandai dengan suatu wilayah.

Tekan atuntuk melakukannya. The aperintah memungkinkan untuk menandai simbol tunggal dalam daftar orang tua, dan tadalah indeks simbol tertentu.

Langkah 3

  1. Untuk membungkus wilayah saat ini dengan (), tekan (.
  2. Tekan C-funtuk memajukan satu karakter dan memasukkan if.
  3. Tekan (lagi untuk memasukkan ().
  4. Insert > w 10.
  5. C-f C-m untuk memindahkan string ke baris baru.

Langkah 4

Untuk mengkloning string:

  1. Tandai simbol-atau-string-pada-titik dengan M-m.
  2. Tekan c.

Jika Anda ingin menonaktifkan wilayah dengan cara yang mewah dan meletakkan titik di bagian paling awal dari string, Anda dapat menekan idm:

  1. i akan memilih isi bagian dalam string.
  2. d akan bertukar titik dan tandai.
  3. m akan menonaktifkan wilayah tersebut

Atau Anda bisa melakukannya m C-b C-b C-bdalam kasus ini, atau C-g C-b C-b C-b. Saya pikir idmlebih baik, karena itu sama terlepas dari panjang tali. Saya pikir C-x C-x C-f C-g juga akan bekerja terlepas dari panjang string.

Akhirnya, masukkan 2untuk mendapatkan kode akhir:

(defadvice linum-update-window (around linum-dynamic activate)
  (let* ((w (length (number-to-string
                     (+ (count-lines (point-min) (point-max)) 1))))
         (linum-format (concat " %" (number-to-string w) (if (> w 10)
                                                             "2|d "
                                                           "d "))))
    ad-do-it))

Ringkasan

Urutan penuh adalah: at( C-f, if, (, > w 10, C-f C-m M-m cidm, 2.

Perhatikan bahwa jika Anda menghitung penyisipan kode, satu-satunya kunci yang tidak terkait dengan manipulasi AST adalah dua C-fdan satu C-m.


3
Lispy terdengar menarik! Untuk OP: Anda dapat mengembangkan alur kerja yang serupa dengan paredit: emacsrocks.com/e14.html dan memperluas wilayah: github.com/magnars/expand-region.el , atau hanya bermain-main dengan perintah pencocokan tanda kurung bawaan : gnu. org / software / emacs / manual / html_node / emacs / Parentheses.html
Tyler

Saya yakin Anda menebak ketika Anda terikat untuk memecahkan masalah bagi saya; terima kasih atas usahanya. Saya berhasil mengacaukan jalan saya menggunakan kode Anda sebagai contoh. Lihat pembaruan saya untuk solusi yang benar.
Zhro

6

Anda akan terbiasa dengannya seiring waktu, tetapi tentu saja ada banyak hal yang dapat Anda lakukan untuk mempercepatnya:

Lekukan

Ada metode untuk kegilaan ini. Anda dapat melakukan ini:

(a-fun (another-fun (magic-macro 1)))

Misalkan itu 1benar-benar ekspresi yang besar, dan Anda ingin membukanya sendiri.

(a-fun (another-fun (magic-macro 
  1)))

Ini menyesatkan. 1Diindentasi hanya satu slot, meskipun seluruh tiga tingkat bersarang lebih tinggi! Lebih baik letakkan di samping orang tuanya.

(a-fun (another-fun (magic-macro 
                      1)))

Jika kami menggunakan skema ini pada kode Anda sendiri, kami mendapatkannya:

(custom-set-variables '(linum-format 'dynamic))
(defadvice linum-update-window (around linum-dynamic activate)
  (let* ((w (length (number-to-string
                      (+ (count-lines (point-min) (point-max)) 1))))       
          (linum-format 
            (concat " %" (number-to-string w) "d ")))
     ad-do-it))

Perhatikan korelasi kuat antara lekukan dan tingkat sarang. Garis dengan tingkat yang lebih besar dari sarang selalu diindentasi lebih dari garis dengan lebih sedikit.

Ini saja akan banyak membantu. Anda dapat dengan mudah melihat "bentuk" kode, dan sebagian besar bahasa lain telah melatih Anda untuk mengaitkan indentasi dengan blok dan blok dengan beberapa bentuk sarang (baik tersurat maupun tersirat).

Sebagai latihan, saya telah menghapus tanda kurung yang tidak penting dari kode. Anda harus dapat membaca kode dan menyediakan tanda kurung yang hilang, mengingat pengetahuan dasar tentang Elisp (yaitu, hal-hal apa saja fungsi dan nilai, dan struktur let*).

custom-set-variables '(linum-format 'dynamic)
defadvice linum-update-window (around linum-dynamic activate)
  let* w length number-to-string
                  + 
                    count-lines (point-min) (point-max) 
                    1       
         linum-format 
           concat " %" (number-to-string w) "d "
     ad-do-it

1
Perhatikan bahwa di Emacs, tab pemukul hampir selalu akan mengatur lekukan dengan benar seperti dijelaskan di sini - Anda tidak boleh melakukannya dengan menambahkan spasi dengan tangan!
Tyler

Bind "Cm" ke newline-and-indentuntuk emacs-lisp-mode dan lisp-interaksi-mode memecahkan contoh pertama Anda, PythonNut. Dan TAB akan melakukan pekerjaan itu sepanjang waktu.
Davor Cubranic

5

Saya memasukkan ini sebagai jawaban yang berbeda.

Terkadang, lekukan akan mengecewakan Anda. Jalan lain Anda adalah menggunakan sesuatu seperti rainbow-delimiters:

masukkan deskripsi gambar di sini

Ini membuat level bersarang paren apa pun menjadi eksplisit dan mudah dipindai.

Namun ada satu masalah yang cukup besar: orangtua itu menggelikan. Ada keseimbangan penekanan di sini. rainbow-delimitersbiasanya akan memberikan banyak penekanan pada parens dengan mengorbankan sisa kode Anda! Tetapi jika Anda menekan pelangi ke bawah, mereka akan semakin sulit untuk dipindai.

Jika Anda dapat menemukan satu set wajah yang menyeimbangkan ini dengan baik, maka tentu saja gunakan itu.

Yang mengatakan, satu solusi (salah satu yang membuat saya berkotek dengan gembira), adalah memiliki dua pasang wajah, dan beralih di antara mereka dengan cepat. Saat Anda melakukan hal-hal lain, wajah menjadi encer dan menghilang ke latar belakang:

masukkan deskripsi gambar di sini

Tetapi ketika Anda meletakkan titik pada paren, itu meninju paren sehingga Anda dapat melihat tingkat bersarang:

masukkan deskripsi gambar di sini

Dan di sini adalah kode untuk melakukan itu:

(defvar rainbow-delimiters-switch nil
  "t if rainbow-delimiters are currently punched")
(defvar rainbow-delimiters-face-cookies nil
  "a list of face-remap-add-relative cookies to reset")

(make-variable-buffer-local 'rainbow-delimiters-switch)
(make-variable-buffer-local 'rainbow-delimiters-face-cookies)

(add-hook 'prog-mode-hook #'rainbow-delimiters-mode)
(add-hook 'text-mode-hook #'rainbow-delimiters-mode)

(with-eval-after-load 'rainbow-delimiters
  (set-face-foreground 'rainbow-delimiters-depth-1-face "#889899")
  (set-face-foreground 'rainbow-delimiters-depth-2-face "#9b7b6b")
  (set-face-foreground 'rainbow-delimiters-depth-3-face "#7b88a5")
  (set-face-foreground 'rainbow-delimiters-depth-4-face "#889899")
  (set-face-foreground 'rainbow-delimiters-depth-5-face "#839564")
  (set-face-foreground 'rainbow-delimiters-depth-6-face "#6391aa")
  (set-face-foreground 'rainbow-delimiters-depth-7-face "#9d748f")
  (set-face-foreground 'rainbow-delimiters-depth-8-face "#7b88a5")
  (set-face-foreground 'rainbow-delimiters-depth-9-face "#659896")

  (defun rainbow-delimiters-focus-on ()
    "Punch the rainbow-delimiters"
    (setq rainbow-delimiters-face-cookies
      (list
        (face-remap-add-relative 'rainbow-delimiters-depth-1-face
          '((:foreground "#3B9399") rainbow-delimiters-depth-1-face))
        (face-remap-add-relative 'rainbow-delimiters-depth-2-face
          '((:foreground "#9B471D") rainbow-delimiters-depth-2-face))
        (face-remap-add-relative 'rainbow-delimiters-depth-3-face
          '((:foreground "#284FA5") rainbow-delimiters-depth-3-face))
        (face-remap-add-relative 'rainbow-delimiters-depth-4-face
          '((:foreground "#3B9399") rainbow-delimiters-depth-4-face))
            (face-remap-add-relative 'rainbow-delimiters-depth-5-face
          '((:foreground "#679519") rainbow-delimiters-depth-5-face))
        (face-remap-add-relative 'rainbow-delimiters-depth-6-face
          '((:foreground "#0E73AA") rainbow-delimiters-depth-6-face))
        (face-remap-add-relative 'rainbow-delimiters-depth-7-face
          '((:foreground "#9D2574") rainbow-delimiters-depth-7-face))
        (face-remap-add-relative 'rainbow-delimiters-depth-8-face
          '((:foreground "#284FA5") rainbow-delimiters-depth-8-face))
        (face-remap-add-relative 'rainbow-delimiters-depth-9-face
          '((:foreground "#199893") rainbow-delimiters-depth-9-face)))
      rainbow-delimiters-switch t))

  (defun rainbow-delimiters-focus-off ()
    "Reset the rainbow-delimiters faces"
    (mapc #'face-remap-remove-relative rainbow-delimiters-face-cookies)
    (setq rainbow-delimiters-switch nil))

  (defun rainbow-delimiters-focus-on-maybe ()
    "Punch the rainbow-delimiters if the point is on a paren"
    (when (looking-at "[][(){}]")
      (unless (or rainbow-delimiters-switch (minibufferp))
        (rainbow-delimiters-focus-on))))

  (defun rainbow-delimiters-focus-off-maybe ()
    "Reset the rainbow-delimiters if the point is not on a paren"
    (unless (looking-at "[][(){}]")
      (when rainbow-delimiters-switch
        (rainbow-delimiters-focus-off))))

  (run-with-idle-timer 0.6 t 'rainbow-delimiters-focus-on-maybe)
  (run-with-idle-timer 0.1 t 'rainbow-delimiters-focus-off-maybe))

Ini keren! Adakah alasan Anda memilih pembatas pelangi daripada tanda kurung?
Tyler

@ Tyler tidak ada alasan khusus, meskipun saya masih tetap dengan pembatas pelangi sekarang (tapi itu mungkin hanya karena saya sudah terbiasa). Saya belum pernah mendengar tentang highlight-kurung sampai saat ini.
PythonNut

4

Jika Anda membuat indentasi kode Anda, maka Anda benar-benar perlu indentasi dengan benar. Pengembang Lisp memiliki harapan seperti apa lekukan yang seharusnya. Ini tidak berarti bahwa kode tersebut terlihat sama. Masih ada berbagai cara untuk memformat kode.

  • berapa lama seharusnya sebuah garis?
  • bagaimana cara mendistribusikan panggilan fungsi / makro?
  • berapa banyak ruang lekukan yang harus ada?
(defadvice linum-update-window (around linum-dynamic activate)
   (let* ((w (length (number-to-string
      (+ (count-lines (point-min) (point-max)) 1))))
         (linum-format (concat " %" (number-to-string w) "d ")))
            ad-do-it))

Saya berharap bahwa lekukan menunjukkan penahanan dalam beberapa cara. Tetapi tidak dalam kode Anda.

Secara default kode Anda mungkin indentasi seperti ini. Jawaban lain menjelaskan bagaimana Anda dapat melakukannya dengan bantuan Emacs:

(defadvice linum-update-window (around linum-dynamic activate)
  (let* ((w (length (number-to-string
                     (+ (count-lines (point-min) (point-max)) 1))))
         (linum-format (concat " %" (number-to-string w) "d ")))
    ad-do-it))

Saya berharap bahwa letvariabel terikat mulai pada kolom vertikal yang sama. Saya juga berharap bahwa tubuh yang letkurang lekuk. Kita belajar bagaimana sebuah letindentasi. Setelah Anda melatihnya sedikit, itu adalah pola visual yang mudah dikenali.

Blok pembangun visual utama dalam kode adalah defadvice, let*dan banyak panggilan fungsi. Dalam defnama memberitahu saya bahwa itu adalah definisi yang diikuti oleh nama, daftar argumen dan badan.

Jadi saya suka melihat

defadvice name arglist
  body

Yang let*akan menjadi let*:, daftar ikatan dan tubuh.

Jadi saya suka melihat:

let*  list of bindings
  body

Lebih detail:

let*   binding1
       binding2
       binding3
  body

Untuk panggilan fungsi, saya ingin melihat:

FUNCTIONNAME ARG1 ARG2 ARG3

atau

FUNCTIONNAME ARG1
             ARG2
             ARG3

atau

FUNCTIONNAME
  ARG1
  ARG2
  ARG3

Yang digunakan tergantung pada berapa lama argumen itu. Kami tidak ingin membuat garis terlalu panjang dan setiap argumen pada barisnya sendiri memungkinkan kami untuk memiliki lebih banyak struktur.

Jadi, Anda perlu menulis kode menggunakan pola-pola itu dan Anda perlu memastikan bahwa pembaca dapat dengan mudah mengidentifikasi pola-pola itu dalam kode Anda.

Kurung harus secara langsung melampirkan konstruksi mereka.

(sin 10)

(sin
  10)

Hindari contoh spasi putih:

(  sin 10  )

atau

(
   sin
)

atau

(sin 10
)

Dalam Lisp, tanda kurung tidak memiliki fungsi sintaksis bahasa, mereka adalah bagian dari sintaksis dari struktur data daftar (s-ekspresi). Jadi kami menulis daftar dan memformat daftar. Untuk memformat isi daftar kami menggunakan pengetahuan tentang bahasa pemrograman Lisp. Sebuah letekspresi harus diformat berbeda dari panggilan fungsi. Masih keduanya adalah daftar dan tanda kurung harus langsung melampirkan daftar. Ada beberapa contoh di mana masuk akal untuk memiliki tanda kurung tunggal pada sebuah baris, tetapi jarang menggunakannya.

Gunakan tanda kurung untuk mendukung Anda menemukan batas ekspresi. Biarkan mereka membantu Anda untuk berpindah dari daftar ke daftar, untuk mengedit daftar, untuk memotong & menyalin daftar, untuk mengganti daftar, untuk indent / format daftar, pilih daftar, ...


2

Untuk bantuan dasar dengan indentasi, gunakan TAB dan "CMq" ( indent-pp-sexp); mengikat "Cm" untuk newline-and-indentakan menghemat Anda harus menekan TAB setelah baris baru.

Anda dapat menavigasi dengan sexp dengan "CM-kiri / kanan / atas / bawah / home / end", yang sangat berguna.

Jika Anda khawatir tentang menjaga keseimbangan kurung, gunakan sesuatu seperti smartparens (itu sedikit lebih memaafkan paredit itu , yang awalnya bisa terasa seperti mengenakan jaket pendek). Itu juga dilengkapi dengan banyak binding untuk menavigasi dan mengedit di tingkat sexp.

Terakhir, untuk menyoroti parens, mulailah dengan mengaktifkan opsi (Menu menu-> Tanda kurung yang cocok, atau show-paren-mode.) Anda juga dapat menggunakan salah satu paket yang disebutkan oleh daftar hukum dalam komentarnya, seperti "highlight-parenthesis" atau "rainbow-delimiters ".


1

Sebagai tambahan dari apa yang orang lain berikan sebagai jawaban, berikut adalah 2 sen saya:

  • Lekukan otomatis yang disediakan oleh emacs-lisp-modesangat penting.
  • blink-matching-parenaktif (non- nil) secara default. Biarkan begitu.
  • Saya menggunakan show-paren-mode, untuk menyorot paren kiri yang sesuai dengan paren kanan sebelum kursor.
  • Saya sementara menghapus dan mengetik ulang paren kanan sebelum kursor, jika saya ingin melihat lebih baik di mana paren kiri yang cocok adalah.

Saya tidak menggunakan pasangan listrik atau pelangi apa pun atau "bantuan" semacam itu. Bagi saya itu adalah masalah, bukan bantuan.

Secara khusus, electric-pair-modebagi saya, merupakan gangguan yang tidak nyaman. Tetapi beberapa orang menyukainya. Dan saya membayangkan bahwa mungkin bermanfaat dalam beberapa konteks pemasangan lain selain tanda kurung Lisp (saya bayangkan juga begitu, tetapi saya juga tidak yakin untuk kasus penggunaan semacam itu).

Anda akan menemukan yang terbaik untuk Anda. Hal utama yang ingin saya katakan adalah: (1) lekukan otomatis adalah teman Anda, seperti beberapa cara untuk menemukan paren kiri yang cocok dengan paren kanan sebelum titik.

Khususnya, melihat apa yang dilakukan lekukan otomatis untuk Anda segera mengajari Anda bahwa Anda tidak akan pernah lagi ingin menempatkan orangtua yang benar di telepon. Gaya pengkodean, yang ada di mana-mana dalam bahasa lain, hanya berisik.

Selain lekukan otomatis yang Anda dapatkan RETdan TAB, dapatkan nyaman menggunakan C-M-q. (Gunakan C-h kdi emacs-lisp-modeuntuk mencari tahu apa kunci ini lakukan.)


1

Saya perhatikan beberapa orang telah menyebutkan pelangi-pembatas, itu juga mode favorit saya saat mengedit kode lisp.

Sebenarnya saya suka tanda kurung, hal terbaik tentang Lisp adalah tanda kurung itu, menyenangkan untuk berurusan dengan mereka jika Anda tahu caranya:

  • instal evil-mode dan pluginnya evil-surround, sehingga Anda dapat mengedit tanda kurung dengan mudah, misalnya, tekan ci(akan menghapus semua yang ada di dalamnya (), va(akan memilih benda yang dibungkus oleh "()" dan "()" itu sendiri. dan Anda dapat menekan %untuk melompat di antara tanda kurung yang cocok

  • gunakan flycheck atau flymake, tanda kurung yang tidak cocok akan digarisbawahi secara real time


0

Kesulitannya di sini adalah Anda ingin menambahkan beberapa kode sebelum dan sesudah tertentu sexp. Dalam situasi ini sexp adalah (concat " %" (number-to-string w) "d "). Anda ingin menyisipkan pernyataan if (if (> w 1) sebelum dan pernyataan lain " %2d ") sesudahnya.

Bagian utama dari kesulitan adalah untuk mengisolasi ini sexp, secara pribadi saya menggunakan perintah di bawah ini untuk mengisolasi asexp

(defun isolate-sexp () (interactive)
       (save-excursion (forward-sexp) (if (not (eolp-almost))
               (split-line) nil)))
(defun eolp-almost () (interactive)
(save-excursion (while (equal (char-after) ? ) (forward-char 1))
        (if (eolp) t nil )      ))

Cukup letakkan kursor di awal (concat " %" (number-to-string w) "d "), yaitu, di yang pertama (, lalu terapkan di atas isolate-sexp. Anda memperoleh

(defadvice linum-update-window (around linum-dynamic activate)
   (let* ((w (length (number-to-string
      (+ (count-lines (point-min) (point-max)) 1))))
         (linum-format (concat " %" (number-to-string w) "d ")
                                  ))
            ad-do-it))

Kemudian tambahkan kode yang sesuai sebelum dan sesudah ini sexp, yaitu

(defadvice linum-update-window (around linum-dynamic activate)
   (let* ((w (length (number-to-string
      (+ (count-lines (point-min) (point-max)) 1))))
         (linum-format (if (> w 1) (concat " %" (number-to-string w) "d ") " %2d ")
                                  ))
            ad-do-it))

Dan voila. Kode yang diperoleh dengan cara ini mungkin tidak indah tetapi kemungkinan tersesat lebih kecil.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.