Tutorial lembut untuk Emacs / Swank / Paredit untuk Clojure

87

Saya pindah ke Emacs untuk mengerjakan Clojure / Lisp. Informasi apa yang saya perlukan untuk mengatur di Emacs agar dapat melakukan hal berikut?

  1. pencocokan otomatis / pembuatan tanda kurung tutup yang sesuai
  2. autoindent Lisp / Clojure style, bukan C ++ / Java style
  3. Penyorotan sintaks
  4. memohon repl
  5. Untuk dapat memuat bagian kode dari file ke dalam REPL dan mengevaluasinya.

Akan sangat bagus jika saya juga bisa mendapatkan daftar perintah untuk mendapatkan hal-hal ini setelah mengatur semuanya di Emacs.

pengguna855
sumber

Jawaban:

89

[Edit dari non-penulis: ini dari 2010, dan prosesnya telah disederhanakan secara signifikan sejak Mei 2011. Saya akan menambahkan postingan ke jawaban ini dengan catatan penyiapan saya per Feb 2012.]

Anda harus mengumpulkan beberapa bagian: Emacs, SLIME (yang bekerja sangat baik dengan Clojure - lihat swank-clojure), swank-clojure (implementasi Clojure dari mitra server SLIME), clojure-mode, Paredit dan, dari Tentu saja, toples Clojure sebagai permulaan, lalu mungkin beberapa tambahan di antaranya Leiningen mungkin akan menjadi yang paling menonjol. Setelah Anda mengatur semuanya, Anda akan memiliki - di dalam Emacs - semua fitur alur kerja / pengeditan yang Anda sebutkan dalam pertanyaan.

Pengaturan dasar:

Berikut ini adalah tutorial bagus yang menjelaskan cara mengatur semua ini; ada lebih banyak di Web, tetapi beberapa di antaranya sudah cukup usang, sedangkan keduanya tampaknya baik-baik saja untuk saat ini:

  1. di mana ditemukan trik-trik perdagangan tentang tulisan clojure di blog Phil Hagelberg; Phil mempertahankan mode swank-clojure dan clojure, serta sebuah paket yang disebut Emacs Starter Kit yang merupakan sesuatu yang disarankan untuk dilihat oleh pendatang baru di dunia Emacs. Instruksi ini tampaknya diperbarui dengan perubahan terkini pada infrastruktur; jika ragu, cari informasi tambahan di grup Google Clojure.

  2. Menyiapkan posting Clojure, Incanter, Emacs, Slime, Swank, dan Paredit di blog proyek Incanter. Incanter adalah paket menarik yang menyediakan DSL mirip-R untuk komputasi statistik yang disematkan langsung ke Clojure. Posting ini akan berguna bahkan jika Anda tidak berencana menggunakan - atau bahkan menginstal - Incanter.

Menempatkan semuanya untuk bekerja:

Setelah Anda mengatur semua hal ini, Anda dapat mencoba dan mulai menggunakannya segera, tetapi saya sangat menyarankan Anda untuk melakukan hal berikut:

  1. Lihat manual SLIME - ini termasuk dalam sumber dan sebenarnya sangat mudah dibaca. Juga, sama sekali tidak ada alasan mengapa Anda harus membaca seluruh manual monster 50 halaman; lihat-lihat saja untuk melihat fitur apa saja yang tersedia.

    Catatan: fitur autodoc SLIME seperti yang ditemukan di sumber upstream terbaru tidak kompatibel dengan swank-clojure - masalah ini tidak akan muncul jika Anda mengikuti rekomendasi Phil Hagelberg untuk menggunakan versi ELPA (lihat postingan blognya yang disebutkan sebelumnya untuk penjelasan) atau cukup biarkan autodoc mati (yang merupakan keadaan default). Opsi terakhir memiliki beberapa daya tarik tambahan karena Anda masih dapat menggunakan SLIME terbaru dengan Common Lisp, jika Anda juga menggunakannya.

  2. Lihat dokumen paredit. Ada dua cara untuk melakukannya: (1) lihat sumbernya - ada banyak sekali komentar di bagian atas file yang berisi semua informasi yang mungkin Anda perlukan; (2) ketik C-h mEmacs saat paredit-mode aktif - buffer akan muncul dengan informasi tentang mode mayor saat ini diikuti dengan informasi tentang semua mode minor yang aktif (paredit adalah salah satunya).

    Pembaruan: Saya baru saja menemukan kumpulan catatan keren ini di Paredit oleh Phil Hagelberg ... Itu adalah tautan ke file teks, saya ingat melihat satu set slide yang bagus dengan informasi ini di suatu tempat, tetapi sepertinya tidak dapat menemukannya sekarang . Bagaimanapun, ini adalah ringkasan yang bagus tentang cara kerjanya. Coba lihat, saya tidak bisa hidup tanpa Paredit sekarang dan file ini seharusnya membuatnya sangat mudah untuk mulai menggunakannya, saya yakin. :-)

  3. Faktanya, C-h mkombinasi tersebut akan memberi tahu Anda tentang semua keybinding yang aktif pada SLIME REPL, dalam mode clojure (Anda pasti ingin mengingat C-c C-kuntuk mengirim buffer saat ini nonaktif untuk kompilasi) dan memang di buffer Emacs mana pun.

Adapun untuk memuat kode dari file dan kemudian bereksperimen dengannya di REPL: gunakan C-c C-kkombinasi yang disebutkan di atas untuk mengkompilasi buffer saat ini, lalu useatau requirenamespace di REPL. Selanjutnya, bereksperimenlah.

Catatan akhir:

Bersiaplah untuk mengubah beberapa hal untuk sementara waktu sebelum semuanya diklik. Ada banyak alat yang terlibat dan sebagian besar interaksinya cukup lancar, tetapi tidak sampai pada titik di mana Anda dapat berasumsi bahwa Anda tidak perlu melakukan beberapa penyesuaian pada awalnya.

Akhirnya, inilah sedikit kode yang saya simpan .emacsyang tidak akan Anda temukan di tempat lain (meskipun ini didasarkan pada fungsi keren oleh Phil Hagelberg). Saya bergantian antara memulai contoh swank saya dengan lein swank(salah satu fitur Leiningen yang lebih keren) dan menggunakan clojure-projectfungsi seperti yang ditemukan di bawah ini untuk memulai semuanya dari dalam Emacs. Saya telah melakukan yang terbaik untuk membuat yang terakhir menghasilkan lingkungan yang sangat cocok dengan yang disediakan oleh lein swank. Oh, dan jika Anda hanya menginginkan REPL di Emacs untuk percobaan yang cepat dan kotor, maka dengan pengaturan yang benar, Anda dapat menggunakannya M-x slimesecara langsung.

(setq clojure-project-extra-classpaths
      '(
        ; "deps/"
        "src/"
        "classes/"
        "test/"
        ))

(setq clojure-project-jar-classpaths
      '(
        ; "deps/"
        "lib/"
        ))

(defun find-clojure-project-jars (path)
  (apply #'append
         (mapcar (lambda (d)
                   (loop for jar in (remove-if (lambda (f) (member f '("." "..")))
                                               (directory-files d t))
                         collect jar into jars
                         finally return jars))
                 (remove-if-not #'file-exists-p
                                clojure-project-jar-classpaths))))

(defun find-clojure-jar (jars)
  (let ((candidates
         (remove-if-not
          (lambda (jar)
            (string-match-p "clojure\\([0-9.-]+\\(SNAPSHOT|MASTER\\)?\\)?\\.jar$" jar))
          jars)))
    (if candidates
        (car candidates)
      (expand-file-name "~/.clojure/clojure.jar"))))

(defun find-clojure-contrib-jar (jars)
  (let ((candidates
         (remove-if-not
          (lambda (jar)
            (string-match-p "clojure-contrib\\([0-9.-]+\\(SNAPSHOT|MASTER\\)?\\)?\\.jar$" jar))
          jars)))
    (if candidates
        (car candidates)
      (expand-file-name "~/.clojure/clojure-contrib.jar"))))

;;; original due to Phil Hagelberg
;;; (see `Best practices for Slime with Clojure' thread on Clojure Google Group)
(defun clojure-project (path)
  "Sets up classpaths for a clojure project and starts a new SLIME session.

   Kills existing SLIME session, if any."
  (interactive (list (ido-read-directory-name
                      "Project root:"
                      (locate-dominating-file default-directory "pom.xml"))))
  (when (get-buffer "*inferior-lisp*")
    (kill-buffer "*inferior-lisp*"))
  (cd path)
  ;; I'm not sure if I want to mkdir; doing that would be a problem
  ;; if I wanted to open e.g. clojure or clojure-contrib as a project
  ;; (both lack "deps/")
                                        ; (mapcar (lambda (d) (mkdir d t)) '("deps" "src" "classes" "test"))
  (let* ((jars (find-clojure-project-jars path))
         (clojure-jar (find-clojure-jar jars))
         (clojure-contrib-jar (find-clojure-contrib-jar jars)))
    (setq swank-clojure-binary nil
          ;; swank-clojure-jar-path (expand-file-name "~/.clojure/clojure.jar")
          swank-clojure-jar-path clojure-jar
          swank-clojure-extra-classpaths
          (cons clojure-contrib-jar
                (append (mapcar (lambda (d) (expand-file-name d path))
                                clojure-project-extra-classpaths)
                        (find-clojure-project-jars path)))
          swank-clojure-extra-vm-args
          (list (format "-Dclojure.compile.path=%s"
                        (expand-file-name "classes/" path)))
          slime-lisp-implementations
          (cons `(clojure ,(swank-clojure-cmd) :init swank-clojure-init)
                (remove-if #'(lambda (x) (eq (car x) 'clojure))
                           slime-lisp-implementations))))
  (slime))
Michał Marczyk
sumber
2
Terima kasih banyak atas artikel yang indah!
pengguna855
3
Sama-sama. Semoga ini membantu Anda dengan Clojure. Selamat meretas! :-)
Michał Marczyk
2
ł: Tulisan yang sangat bagus. Terima kasih.
Ralph
Itu memang tutorial yang sangat bagus. Saya baru tahu bahwa opsi terbaik adalah Emacs meskipun saya tidak terlalu menyukainya. IDEA, Eclipse dan netbeans sama sekali tidak cocok dengan gambar.
Adam Arold
8

The Emacs Starter kit telah mendapat ulasan yang besar untuk memulai dengan Clojure:

Untuk menjawab hanya bagian mewah dari pertanyaan Anda:

Leiningen adalah cara yang sangat mudah untuk menyiapkan swank dengan classpath yang benar dan menghubungkannya ke Emacs.

Video yang bagus ada di sini: http://vimeo.com/channels/fulldisclojure#8934942 Berikut adalah contoh file project.clj yang

(defproject project "0.1"
    :dependencies [[org.clojure/clojure
                      "1.1.0-master-SNAPSHOT"]
                   [org.clojure/clojure-contrib
                      "1.0-SNAPSHOT"]]
    :dev-dependencies [[leiningen/lein-swank "1.1.0"]]
    :main my.project.main)

lalu lari:

lein swank

dan dari Emacs:

 alt-x slime-connect
Arthur Ulfeldt
sumber
1

CIDER (Clojure Interactive Development Environment) harus disebutkan di sini.

Ini akan mencakup sebagian besar dari apa yang Anda cari. Itu termasuk:

  • REPL interaktif
  • debugging
  • uji coba
  • navigasi kode
  • pencarian dokumentasi
  • lebih banyak lagi

Selain CIDER, ada beberapa add-on penting dan bagus untuk dimiliki untuk pengembangan clojure, yang akan saya coba kelompokkan masing-masing (dan secara subyektif):

Penting

  • smartparens - pasangan tanda kurung, manipulasi, navigasi (atau parinfer jika Anda mau)

  • clj-refactor –- memiliki beberapa fitur luar biasa, seperti auto-add / compiling namepaces (akan segera digabungkan ke dalam CIDER)

  • clojure-mode - font-lock, indentasi, navigasi

  • perusahaan - kerangka penyelesaian teks (atau pilih pelengkap otomatis lainnya)

  • pembatas pelangi - menyoroti / mewarnai pembatas seperti tanda kurung, tanda kurung atau kawat gigi sesuai dengan kedalamannya

  • flycheck - ekstensi pemeriksaan sintaks on-the-fly

  • flycheck-clj-kondo - integrasi untuk clj-kondo

Kebaikan

General Essentials (untuk bahasa apa pun)

  • magit - git porcelain di dalam Emacs

  • proyektil - manajemen proyek untuk menemukan file, mencari, dll

  • helm - penyelesaian bertahap dan seleksi kerangka penyempitan (atau swiper )

Sumber Daya Lainnya

Jika Anda mencari pengaturan yang telah melakukan sebagian besar / semua pekerjaan ini untuk Anda, beberapa opsi adalah:

Mikha Elliott
sumber