[Edytuj od osób niebędących autorami: pochodzi z 2010 r., A proces został znacznie uproszczony od maja 2011 r. Dodam do tej odpowiedzi post z notatkami dotyczącymi konfiguracji z lutego 2012 r.]
Będziesz musiał złożyć kilka elementów: Emacs, SLIME (który działa doskonale z Clojure - patrz swank-clojure), swank-clojure (implementacja Clojure odpowiednika serwera SLIME), tryb clojure, Paredit i, z Oczywiście, na początek słoik Clojure, a potem może jakieś dodatki, wśród których Leiningen byłby chyba najbardziej zauważalny. Gdy już to wszystko ustawisz, będziesz miał - w Emacsie - wszystkie funkcje przepływu pracy / edycji, o których wspomniałeś w pytaniu.
Podstawowe ustawienia:
Poniżej znajdują się świetne samouczki, które opisują, jak to wszystko ustawić; w sieci jest więcej, ale niektóre inne są dość przestarzałe, podczas gdy te dwa wydają się na razie w porządku:
w którym znajdują się sztuczki branżowe dotyczące autorstwa clojure wpis na blogu Phila Hagelberga; Phil utrzymuje swank-clojure i clojure-mode, a także pakiet zwany Emacs Starter Kit, który jest czymś, na co każdy nowicjusz w świecie Emacsa powinien się przyjrzeć. Wydaje się, że te instrukcje zostały zaktualizowane wraz z ostatnimi zmianami w infrastrukturze; w razie wątpliwości poszukaj dodatkowych informacji w grupie Google Clojure.
Konfigurowanie postów Clojure, Incanter, Emacs, Slime, Swank i Paredit na blogu projektu Incanter. Incanter to fascynujący pakiet zapewniający DSL podobny do R do obliczeń statystycznych osadzonych bezpośrednio w Clojure. Ten post będzie przydatny, nawet jeśli nie planujesz używać - ani nawet instalować - Incantera.
Wszystko działa:
Po skonfigurowaniu wszystkich tych rzeczy możesz spróbować od razu zacząć z nich korzystać, ale zdecydowanie radzę wykonać następujące czynności:
Spójrz na instrukcję SLIME - jest zawarta w źródłach i właściwie jest bardzo czytelna. Nie ma też absolutnie żadnego powodu, dla którego powinieneś czytać cały 50-stronicowy podręcznik potwora; po prostu rozejrzyj się, aby zobaczyć, jakie funkcje są dostępne.
Uwaga: funkcja autodoc SLIME, którą można znaleźć w najnowszych źródłach zewnętrznych, jest niekompatybilna ze swank-clojure - ten problem nie pojawi się, jeśli zastosujesz się do zalecenia Phila Hagelberga, aby używać wersji ELPA (wyjaśnienie znajduje się we wspomnianym wcześniej wpisie na blogu) lub po prostu wyłącz autodokres (co jest stanem domyślnym). Ta ostatnia opcja ma dodatkowy urok, ponieważ nadal możesz używać najnowszego SLIME z Common Lisp, na wypadek gdybyś również tego używał.
Zapoznaj się z dokumentacją dotyczącą paredit. Można to zrobić na dwa sposoby: (1) spójrz na źródło - na początku pliku znajduje się ogromna liczba komentarzy, które zawierają wszystkie potrzebne informacje; (2) wpisz C-h mEmacs, gdy tryb paredit jest aktywny - pojawi się bufor z informacjami o aktualnym trybie głównym, a następnie informacje o wszystkich aktywnych trybach podrzędnych (jednym z nich jest paredit).
Aktualizacja: Właśnie znalazłem ten fajny zestaw notatek na Paredit autorstwa Phila Hagelberga ... To jest link do pliku tekstowego, pamiętam, że widziałem gdzieś fajny zestaw slajdów z tymi informacjami, ale nie mogę ich teraz znaleźć . Zresztą to miłe podsumowanie tego, jak to działa. Zdecydowanie spójrz na to, nie mogę teraz żyć bez Paredit, a ten plik powinien bardzo ułatwić rozpoczęcie korzystania z niego, jak sądzę. :-)
W rzeczywistości ta C-h mkombinacja powie ci o wszystkich przypisaniach klawiszowych aktywnych w SLIME REPL, w trybie clojure (będziesz chciał pamiętać C-c C-ko wysłaniu bieżącego bufora do kompilacji), a nawet w dowolnym buforze Emacsa.
Jeśli chodzi o ładowanie kodu z pliku, a następnie eksperymenty z nim w REPL: wykorzystanie wspomnianej C-c C-kkombinacji do sporządzenia bieżącego bufora, to use
lub require
jego nazw w REPL. Następnie eksperymentuj.
Uwagi końcowe:
Przygotuj się na chwilę poprawiania rzeczy, zanim wszystko kliknie. W grę wchodzi wiele narzędzi, a ich interakcje są w większości dość płynne, ale nie na tyle, aby można było bezpiecznie założyć, że na początku nie będziesz musiał wprowadzać pewnych korekt.
Na koniec trzymam fragment kodu, .emacs
którego nie znajdziesz nigdzie indziej (chociaż jest oparty na fajnej funkcji Phila Hagelberga). Na przemian uruchamiam swoje instancje z lein swank
(jedną z fajniejszych funkcji Leiningena) i korzystam z clojure-project
funkcji przedstawionej poniżej, aby rozpocząć całość z poziomu Emacsa. Zrobiłem co w mojej mocy, aby te ostatnie tworzyły środowisko ściśle odpowiadające temu, które zapewnia lein swank
. Aha, i jeśli chcesz tylko REPL w Emacsie do szybkiego i brudnego eksperymentu, to przy prawidłowej konfiguracji powinieneś być w stanie użyć M-x slimebezpośrednio.
(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))