Hướng dẫn nhẹ nhàng về Emacs / Swank / Paredit cho Clojure


87

Tôi đang chuyển đến Emacs để làm việc trên Clojure / Lisp. Tất cả thông tin tôi cần thiết lập trên Emacs để có thể thực hiện những việc sau là gì?

  1. khớp / tạo dấu ngoặc đóng tương ứng tự động
  2. kiểu autoindent Lisp / Clojure, không phải kiểu C ++ / Java
  3. Đánh dấu cú pháp
  4. Gọi REPL
  5. Để có thể tải một phần mã từ tệp vào REPL và đánh giá nó.

Sẽ thật tuyệt nếu tôi cũng có thể nhận được danh sách các lệnh để có được những thứ này sau khi thiết lập mọi thứ trên Emacs.

Câu trả lời:


89

[Chỉnh sửa từ người không phải là tác giả: đây là từ năm 2010 và quy trình đã được đơn giản hóa đáng kể kể từ tháng 5 năm 2011. Tôi sẽ thêm một bài đăng cho câu trả lời này cùng với ghi chú thiết lập của tôi kể từ tháng 2 năm 2012]

Bạn sẽ cần phải kết hợp một số phần lại với nhau: Emacs, SLIME (hoạt động hoàn toàn tốt với Clojure - xem swank-clojure), swank-clojure (triển khai Clojure của đối tác máy chủ của SLIME), clojure-mode, Paredit và, của tất nhiên, chiếc lọ Clojure để bắt đầu, sau đó có lẽ một số tính năng bổ sung trong đó Leiningen có lẽ là đáng chú ý nhất. Khi bạn đã thiết lập tất cả, bạn sẽ có - trong Emacs - tất cả các tính năng chỉnh sửa / quy trình công việc mà bạn đề cập trong câu hỏi.

Thiết lập cơ bản:

Sau đây là các hướng dẫn tuyệt vời mô tả cách thiết lập tất cả những điều này; có nhiều hơn trên Web, nhưng một số trong số những cái khác đã khá lỗi thời, trong khi hai cái này có vẻ ổn cho đến nay:

  1. trong đó được tìm thấy các mánh khóe buôn bán liên quan đến quyền tác giả áo choàng đăng trên blog của Phil Hagelberg; Phil duy trì swank-clojure và clojure-mode, cũng như một gói có tên Emacs Starter Kit, đây là thứ mà bất kỳ người mới nào đến với thế giới Emacs cũng nên xem qua. Những hướng dẫn này dường như đã được cập nhật với những thay đổi gần đây đối với cơ sở hạ tầng; trong trường hợp nghi ngờ, hãy tìm thêm thông tin trên nhóm Google của Clojure.

  2. Thiết lập Clojure, Incanter, Emacs, Slime, Swank và Paredit đăng trên blog của dự án Incanter. Incanter là một gói hấp dẫn cung cấp DSL giống R để tính toán thống kê được nhúng ngay vào Clojure. Bài đăng này sẽ hữu ích ngay cả khi bạn không có kế hoạch sử dụng - hoặc thậm chí cài đặt - Incanter.

Đưa tất cả vào hoạt động:

Sau khi thiết lập tất cả những thứ này, bạn có thể thử và bắt đầu sử dụng nó ngay lập tức, nhưng tôi thực sự khuyên bạn nên làm như sau:

  1. Hãy xem hướng dẫn sử dụng của SLIME - nó được bao gồm trong các nguồn và thực sự rất dễ đọc. Ngoài ra, hoàn toàn không có lý do gì bạn nên đọc toàn bộ cuốn sách hướng dẫn quái vật dài 50 trang; chỉ cần nhìn xung quanh để xem những tính năng nào có sẵn.

    Lưu ý: tính năng autodoc của SLIME như được tìm thấy trong các nguồn ngược dòng mới nhất không tương thích với swank-clojure - vấn đề này sẽ không xuất hiện nếu bạn làm theo khuyến nghị của Phil Hagelberg để sử dụng phiên bản ELPA (xem bài đăng trên blog của anh ấy để được giải thích) hoặc đơn giản là tắt tự động lấy nét (là trạng thái mặc định của mọi thứ). Tùy chọn thứ hai có một số hấp dẫn bổ sung ở chỗ bạn vẫn có thể sử dụng SLIME mới nhất với Common Lisp, trong trường hợp bạn cũng sử dụng nó.

  2. Hãy xem các tài liệu cho paredit. Có hai cách để giải quyết vấn đề này: (1) xem nguồn - có một lượng lớn nhận xét ở đầu tệp chứa tất cả thông tin bạn có thể cần; (2) nhập C-h mEmacs trong khi chế độ paredit đang hoạt động - một bộ đệm sẽ bật lên với thông tin về chế độ chính hiện tại, sau đó là thông tin về tất cả các chế độ phụ đang hoạt động (paredit là một trong những chế độ đó).

    Cập nhật: Tôi vừa tìm thấy bộ ghi chú thú vị này trên Paredit của Phil Hagelberg ... Đó là một liên kết đến một tệp văn bản, tôi nhớ đã thấy một bộ trang trình bày đẹp với thông tin này ở đâu đó, nhưng dường như không thể tìm thấy nó bây giờ . Dù sao, nó là một bản tóm tắt tốt đẹp về cách nó hoạt động. Chắc chắn hãy nhìn vào nó, tôi không thể sống mà không có Paredit bây giờ và tệp này sẽ giúp bạn bắt đầu sử dụng nó rất dễ dàng. :-)

  3. Trên thực tế, sự C-h mkết hợp sẽ cho bạn biết về tất cả các keybinding đang hoạt động tại SLIME REPL, ở chế độ clojure-mode (bạn sẽ muốn ghi nhớ C-c C-kviệc gửi bộ đệm hiện tại để biên dịch) và thực sự trong bất kỳ bộ đệm Emacs nào.

Đối với việc tải mã từ một tệp và sau đó thử nghiệm với nó tại REPL: sử dụng C-c C-ktổ hợp đã nói ở trên để biên dịch bộ đệm hiện tại, sau đó usehoặc requirekhông gian tên của nó tại REPL. Tiếp theo, hãy thử nghiệm đi.

Ghi chú cuối cùng:

Hãy chuẩn bị tinh chỉnh mọi thứ trong một thời gian trước khi tất cả kích hoạt. Có rất nhiều công cụ liên quan và các tương tác của chúng hầu như khá trơn tru, nhưng không đến mức an toàn nếu cho rằng bạn sẽ không phải thực hiện một số điều chỉnh ban đầu.

Cuối cùng, đây là một đoạn mã mà tôi giữ lại .emacsmà bạn sẽ không tìm thấy ở nơi khác (mặc dù nó dựa trên một hàm thú vị của Phil Hagelberg). Tôi xen kẽ giữa việc bắt đầu các phiên bản swank của mình với lein swank(một trong những tính năng thú vị hơn của Leiningen) và sử dụng clojure-projectchức năng như được tìm thấy bên dưới để bắt đầu toàn bộ từ bên trong Emacs. Tôi đã cố gắng hết sức để tạo ra một môi trường phù hợp chặt chẽ với môi trường được cung cấp bởi lein swank. Ồ, và nếu bạn chỉ muốn REPL trong Emacs để có một thử nghiệm nhanh chóng và bẩn thỉu, thì với thiết lập chính xác, bạn sẽ có thể sử dụng M-x slimetrực tiếp.

(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))

2
Cảm ơn bạn rất nhiều vì bài viết đẹp!
user855,

3
Không có gì. Hy vọng nó sẽ giúp bạn trên con đường của bạn với Clojure. Chúc bạn hack vui vẻ! :-)
Michał Marczyk

2
ł: Viết lên rất hay. Cảm ơn.
Ralph

Đó thực sự là một hướng dẫn rất hay. Tôi chỉ phát hiện ra rằng lựa chọn tốt nhất là Emacs ngay cả khi tôi không thực sự thích nó. IDEA, Eclipse và netbeans chỉ đơn giản là không phù hợp với hình ảnh.
Adam Arold

10

Có một hướng dẫn tuyệt vời hơn:

Trong 30 đến 45 phút, người ta có thể thiết lập mọi thứ từ đầu.

Hướng dẫn này không giả định bất kỳ kiến ​​thức nào trước đây của Emacs (và cả Clojure nữa - trong các bài viết trước đó có một phần giới thiệu hay về Clojure).


8

Bộ Emacs Starter đã nhận được những đánh giá tuyệt vời để bắt đầu với Clojure:

Để chỉ trả lời phần trống của câu hỏi của bạn:

Leiningen là một cách thực sự dễ dàng để thiết lập swank với classpath chính xác và kết nối nó với Emacs.

Đây là một video tuyệt vời: http://vimeo.com/channels/fulldisclojure#8934942 Đây là ví dụ về tệp project.clj

(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)

sau đó chạy:

lein swank

và từ Emacs:

 alt-x slime-connect


1

Ở đây phải đề cập đến CIDER (Clojure Interactive Development Environment).

Nó sẽ bao gồm hầu hết những gì bạn đang tìm kiếm. Nó bao gồm:

  • REPL tương tác
  • gỡ lỗi
  • chạy thử nghiệm
  • điều hướng mã
  • tra cứu tài liệu
  • nhiều hơn

Ngoài CIDER, có một số tiện ích bổ sung cần thiết và tốt đẹp khác để phát triển clojure mà tôi sẽ cố gắng phân nhóm tương ứng (và theo chủ quan):

Những điều cần thiết

  • smartparens - ghép nối trong ngoặc đơn, thao tác, điều hướng (hoặc parinfer nếu bạn thích)

  • clj-refactor –- có một số tính năng tuyệt vời, như tự động thêm / biên dịch không gian tên (nó có thể sớm được tích hợp vào CIDER)

  • chế độ clojure - khóa phông chữ, thụt lề, điều hướng

  • công ty - khung hoàn thành văn bản (hoặc chọn một trình tự động hoàn thành khác)

  • cầu vồng - đánh dấu / tô màu các dấu phân cách như dấu ngoặc đơn, dấu ngoặc nhọn hoặc dấu ngoặc nhọn theo độ sâu của chúng

  • flycheck - tiện ích mở rộng kiểm tra cú pháp nhanh chóng

  • flycheck-clj-kondo - tích hợp cho clj-kondo

Niceties

  • clojure-snippets - các phím tắt có thể mở rộng tab cho các đoạn mã dài hơn

  • nhảy câm - chuyển đến định nghĩa

  • key-nào - hiển thị các keybindings có sẵn trong cửa sổ bật lên

  • đánh dấu ngoặc đơn - đánh dấu các dấu ngoặc đơn xung quanh

  • mấu chốt - một Bộ sưu tập các thiết bị điện tử hữu ích đến kỳ lạ cho Emacs

  • comment-dwim-2 - thay thế cho Emacs tích hợp sẵncomment-dwim

Cơ bản chung (cho bất kỳ ngôn ngữ nào)

  • magit - sứ git bên trong Emacs

  • projectile - dự án mgmt để tìm tệp, tìm kiếm, v.v.

  • helm - hoàn thành gia tăng và khung thu hẹp lựa chọn (hoặc swiper )

Các nguồn lực khác

Nếu bạn đang tìm kiếm một thiết lập đã thực hiện hầu hết / tất cả công việc này cho bạn, một vài tùy chọn là:

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.