[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:
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.
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:
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ó.
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. :-)
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 đó use
hoặc require
khô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 .emacs
mà 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-project
chứ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
'(
"src/"
"classes/"
"test/"
))
(setq clojure-project-jar-classpaths
'(
"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"))))
(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)
(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 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))