Un tutorial amable de Emacs/Swank/Paredit para Clojure
(4)
Me estoy mudando a Emacs para trabajar en Clojure / Lisp. ¿Cuál es toda la información que necesito configurar en Emacs para poder hacer lo siguiente?
- coincidencia automática / generación de corchetes de cierre correspondientes
- Estilo Autindent Lisp / Clojure, no estilo C ++ / Java
- Resaltado de sintaxis
- Invocando REPL
- Para poder cargar una parte del código del archivo en el REPL y evaluarlo.
Sería genial si también pudiera obtener la lista de comandos para obtener estas cosas después de configurar todo en Emacs.
[Editar de un autor: esto es de 2010, y el proceso se ha simplificado significativamente desde mayo de 2011. Agregaré una publicación a esta respuesta con mis notas de configuración a partir de febrero de 2012.]
Necesitarás juntar algunas piezas: Emacs, SLIME (que funciona perfectamente con Clojure - ver swank-clojure), swank-clojure (la implementación Clojure de la contraparte del servidor de SLIME), clojure-mode, Paredit y, de Por supuesto, el jarro de Clojure para empezar, y tal vez algunos extras entre los que Leiningen sería quizás el más notable. Una vez que lo configure todo, tendrá, dentro de Emacs, todas las funciones de flujo de trabajo / edición que menciona en la pregunta.
Configuración básica:
Los siguientes son excelentes tutoriales que describen cómo configurar todo esto; hay más en la Web, pero algunos de los otros están bastante desactualizados, mientras que estos dos parecen estar bien por ahora:
en el que se encuentran trucos del oficio sobre la publicación de la autoría de clojure en el blog de Phil Hagelberg; Phil mantiene swank-clojure y clojure-mode, así como un paquete llamado Emacs Starter Kit, que es algo que cualquier recién llegado al mundo de Emacs debería tener en cuenta. Estas instrucciones parecen haberse actualizado con cambios recientes en la infraestructura; en caso de duda, busque información adicional en el grupo de Google de Clojure.
Configuración de Clojure, Incanter, Emacs, Slime, Swank y Paredit en el blog del proyecto Incanter. Incanter es un paquete fascinante que proporciona un DSL tipo R para cálculos estadísticos incrustados directamente en Clojure. Esta publicación será útil incluso si no planea usar - o incluso instalar - Incanter.
Poniéndolo todo a trabajar:
Una vez que haya configurado todo esto, podría probar y comenzar a usarlo de inmediato, pero le recomendaría encarecidamente que haga lo siguiente:
Eche un vistazo al manual de SLIME: está incluido en las fuentes y es realmente muy legible. Además, no hay absolutamente ninguna razón por la que deberías leer todo el manual de monstruos de 50 páginas; solo eche un vistazo para ver qué características están disponibles.
Nota: la función autodoc de SLIME tal como se encuentra en las últimas fuentes originales es incompatible con swank-clojure ; este problema no surgirá si sigue la recomendación de Phil Hagelberg de usar la versión ELPA (consulte la publicación del blog antes mencionada para obtener una explicación) o simplemente deje el autodoc apagado (que es el estado predeterminado de las cosas). La última opción tiene un atractivo adicional ya que aún puede usar el último SLIME con Common Lisp, en caso de que también lo use.
Echa un vistazo a los documentos de paredit. Hay dos formas de hacerlo: (1) observe la fuente: hay una gran cantidad de comentarios en la parte superior del archivo que contienen toda la información que probablemente necesite; (2) escriba Ch m en Emacs mientras el modo de crédito está activo: aparecerá un búfer con información sobre el modo principal actual seguido de información sobre todos los modos menores activos (el crédito es uno de ellos).
Actualización: Acabo de encontrar este genial conjunto de notas sobre Paredit de Phil Hagelberg ... Es un enlace a un archivo de texto, recuerdo haber visto un buen conjunto de diapositivas con esta información en alguna parte, pero parece que no puedo encontrarlo ahora . De todos modos, es un buen resumen de cómo funciona. Definitivamente échele un vistazo, no puedo vivir sin Paredit ahora y este archivo debería hacer que sea muy fácil comenzar a usarlo, creo. :-)
De hecho, la combinación Ch m le informará sobre todas las combinaciones de teclas activas en SLIME REPL, en modo clojure (querrá recordar Cc Ck para enviar el búfer en uso para la compilación) y de hecho en cualquier búfer de Emacs.
En cuanto a cargar el código de un archivo y luego experimentar con él en el REPL: use la combinación de Cc Ck antes mencionada para compilar el búfer en use
, luego use
o require
su espacio de nombre en el REPL. Luego, experimenta lejos.
Notas finales:
Esté preparado para tener que modificar las cosas por un tiempo antes de que todo haga clic. Hay muchas herramientas involucradas y sus interacciones son en general bastante fluidas, pero no hasta el punto en que sería seguro asumir que no tendrá que hacer algunos ajustes inicialmente.
Finalmente, aquí hay un poco de código que guardo en .emacs
que no encontrarás en ninguna otra parte (aunque está basado en una función genial de Phil Hagelberg). Alterno entre comenzar mis instancias swank con lein swank
(una de las funciones más clojure-project
de Leiningen) y usar la clojure-project
que se encuentra a continuación para comenzar todo desde Emacs. He hecho todo lo posible para que este último produzca un entorno que se parezca mucho al proporcionado por lein swank
. Ah, y si solo quieres un REPL en Emacs para un experimento rápido y sucio, entonces con la configuración correcta deberías poder usar Mx slime directamente.
(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))
El kit de inicio de Emacs ha recibido excelentes críticas para comenzar con Clojure:
Para contestar solo la parte de su pregunta:
Leiningen es una forma realmente fácil de configurar swank con la ruta de clase correcta y conectarla a Emacs.
Un gran video está aquí: http://vimeo.com/channels/fulldisclojure#8934942 Aquí hay un ejemplo de un archivo project.clj que
(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)
entonces corre:
lein swank
y de Emacs:
alt-x slime-connect
Hay otro tutorial más excelente:
- http://www.braveclojure.com/basic-emacs/ (1ra parte)
- http://www.braveclojure.com/using-emacs-with-clojure/ (2da parte)
En 30 a 45 minutos uno puede tener todo configurado desde cero.
El tutorial no presupone ningún conocimiento previo de Emacs (y Clojure también; en las publicaciones anteriores hay una buena introducción a Clojure).
Clojure con Emacs en Clojure Documentation también puede ser útil.