Ein sanftes Tutorial zu Emacs / Swank / Paredit für Clojure

87

Ich ziehe nach Emacs, um an Clojure / Lisp zu arbeiten. Welche Informationen muss ich auf Emacs einrichten, um Folgendes ausführen zu können?

  1. automatische Anpassung / Generierung entsprechender schließender Klammern
  2. Autoindent Lisp / Clojure-Stil, nicht C ++ / Java-Stil
  3. Satzstellung markieren
  4. Hervorrufen von REPL
  5. Um einen Teil des Codes aus der Datei in die REPL laden und auswerten zu können.

Es wäre großartig, wenn ich auch die Liste der Befehle erhalten könnte, um diese Dinge zu erhalten, nachdem ich die Dinge auf Emacs eingerichtet habe.

user855
quelle

Antworten:

89

[Vom Nichtautor bearbeiten: Dies ist aus dem Jahr 2010 und der Prozess wurde seit Mai 2011 erheblich vereinfacht. Ich werde dieser Antwort ab Februar 2012 einen Beitrag mit meinen Setup-Notizen hinzufügen.]

Sie müssen einige Teile zusammenstellen: Emacs, SLIME (das perfekt mit Clojure zusammenarbeitet - siehe swank-clojure), swank-clojure (die Clojure-Implementierung des SLIME-Server-Gegenstücks), clojure-mode, Paredit und, of Natürlich das Clojure-Glas für den Anfang, dann vielleicht einige Extras, unter denen Leiningen vielleicht das bemerkenswerteste wäre. Sobald Sie alles eingerichtet haben, haben Sie in Emacs alle Workflow- / Bearbeitungsfunktionen, die Sie in der Frage erwähnen.

Grundeinstellung:

Im Folgenden finden Sie großartige Tutorials, in denen beschrieben wird, wie Sie all dies einrichten. Es gibt mehr im Web, aber einige der anderen sind ziemlich veraltet, während diese beiden im Moment in Ordnung zu sein scheinen:

  1. in denen Tricks des Handels in Bezug auf Clojure-Autorenschaft auf Phil Hagelbergs Blog gefunden werden; Phil unterhält den Swank-Clojure- und Clojure-Modus sowie ein Paket namens Emacs Starter Kit, das sich jeder Neuling in der Emacs-Welt unbedingt ansehen sollte. Diese Anweisungen scheinen mit den jüngsten Änderungen an der Infrastruktur auf den neuesten Stand gebracht worden zu sein. Suchen Sie im Zweifelsfall nach zusätzlichen Informationen in der Google-Gruppe von Clojure.

  2. Einrichten von Clojure-, Incanter-, Emacs-, Slime-, Swank- und Paredit-Posts im Blog des Incanter-Projekts. Incanter ist ein faszinierendes Paket, das ein R-ähnliches DSL für statistische Berechnungen bietet, die direkt in Clojure eingebettet sind. Dieser Beitrag ist auch dann nützlich, wenn Sie Incanter nicht verwenden oder gar installieren möchten.

Alles zum Laufen bringen:

Sobald Sie all diese Dinge eingerichtet haben, können Sie versuchen, sie sofort zu verwenden, aber ich würde Ihnen dringend raten, Folgendes zu tun:

  1. Schauen Sie sich das SLIME-Handbuch an - es ist in den Quellen enthalten und tatsächlich sehr gut lesbar. Es gibt auch absolut keinen Grund, warum Sie das gesamte 50-seitige Monster-Handbuch lesen sollten . Schauen Sie sich einfach um, um zu sehen, welche Funktionen verfügbar sind.

    Hinweis: Die Autodoc-Funktion von SLIME in den neuesten Upstream-Quellen ist nicht mit Swank-Clojure kompatibel. Dieses Problem tritt nicht auf, wenn Sie Phil Hagelbergs Empfehlung zur Verwendung der ELPA-Version folgen (eine Erklärung finden Sie in seinem oben genannten Blog-Beitrag.) oder lassen Sie einfach Autodoc ausgeschaltet (dies ist der Standardzustand der Dinge). Die letztere Option hat den zusätzlichen Reiz, dass Sie weiterhin das neueste SLIME mit Common Lisp verwenden können, falls Sie dies ebenfalls verwenden.

  2. Schauen Sie sich die Dokumente für paredit an. Es gibt zwei Möglichkeiten, dies zu tun: (1) Sehen Sie sich die Quelle an - oben in der Datei befindet sich eine große Anzahl von Kommentaren, die alle Informationen enthalten, die Sie wahrscheinlich benötigen. (2) C-h mGeben Sie Emacs ein, während der Paredit-Modus aktiv ist. Ein Puffer mit Informationen zum aktuellen Hauptmodus wird angezeigt, gefolgt von Informationen zu allen aktiven Nebenmodi (Paredit ist einer davon).

    Update: Ich habe gerade diese coolen Notizen zu Paredit von Phil Hagelberg gefunden ... Das ist ein Link zu einer Textdatei. Ich erinnere mich, dass ich irgendwo eine schöne Reihe von Folien mit diesen Informationen gesehen habe, aber ich kann sie jetzt nicht finden . Wie auch immer, es ist eine schöne Zusammenfassung, wie es funktioniert. Schauen Sie es sich auf jeden Fall an, ich kann jetzt nicht ohne Paredit leben und diese Datei sollte es meiner Meinung nach sehr einfach machen, damit zu beginnen. :-)

  3. Tatsächlich C-h minformiert Sie die Kombination über alle Tastenkombinationen, die bei SLIME REPL aktiv sind, im Clojure-Modus (Sie sollten sich daran erinnern C-c C-k, dass Sie den aktuellen Puffer zur Kompilierung abgeschickt haben ) und in jedem Emacs-Puffer.

Wie für den Code aus einer Datei geladen und dann mit ihm in der REPL experimentiert: Verwenden Sie die oben genannte C-c C-kKombination die aktuellen Puffer zu kompilieren, dann useoder requireseinen Namensraum an der REPL. Als nächstes experimentieren Sie weg.

Schlussbemerkungen:

Seien Sie bereit, Dinge für eine Weile zu optimieren, bevor alles klickt. Es sind viele Tools beteiligt, und ihre Interaktionen sind größtenteils recht reibungslos, aber nicht bis zu dem Punkt, an dem man davon ausgehen kann, dass Sie zunächst keine Anpassungen vornehmen müssen.

Schließlich ist hier ein bisschen Code, den ich behalte, .emacsden Sie anderswo nicht finden werden (obwohl er auf einer coolen Funktion von Phil Hagelberg basiert). Ich wechsle zwischen dem Starten meiner Swank-Instanzen mit lein swank(einer der cooleren Funktionen von Leiningen) und dem Verwenden der clojure-projectunten aufgeführten Funktion, um das Ganze in Emacs zu starten. Ich habe mein Bestes getan, um letztere zu einer Umgebung zu bringen, die genau der von entspricht lein swank. Oh, und wenn Sie nur eine REPL in Emacs für ein schnelles und schmutziges Experiment benötigen, sollten Sie mit dem richtigen Setup in der Lage sein, diese M-x slimedirekt zu verwenden .

(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
quelle
2
Vielen Dank für das schöne Schreiben!
user855
3
Bitte. Ich hoffe, es bringt dich mit Clojure auf den Weg. Viel Spaß beim Hacken! :-)
Michał Marczyk
2
ł: Sehr schön zu schreiben. Vielen Dank.
Ralph
Das ist in der Tat ein sehr schönes Tutorial. Ich habe gerade herausgefunden, dass die beste Option Emacs ist, auch wenn es mir nicht wirklich gefallen hat. IDEE, Eclipse und Netbeans passen einfach nicht ins Bild.
Adam Arold
8

Das Emacs Starter- Kit hat großartige Bewertungen für den Einstieg in Clojure erhalten:

Um nur den ausgeflippten Teil Ihrer Frage zu beantworten:

Leiningen ist eine wirklich einfache Möglichkeit, Swank mit dem richtigen Klassenpfad einzurichten und mit Emacs zu verbinden.

Ein großartiges Video finden Sie hier: http://vimeo.com/channels/fulldisclojure#8934942 Hier ist ein Beispiel für eine project.clj-Datei, die

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

dann renne:

lein swank

und von Emacs:

 alt-x slime-connect
Arthur Ulfeldt
quelle
1

CIDER (Clojure Interactive Development Environment) muss hier erwähnt werden.

Es wird das meiste abdecken, wonach Sie suchen. Es enthält:

  • interaktive REPL
  • Debuggen
  • Testlauf
  • Code-Navigation
  • Dokumentationssuche
  • viel mehr

Neben CIDER gibt es noch einige weitere wichtige und nützliche Add-Ons für die Clojure-Entwicklung, die ich jeweils (und subjektiv) zu gruppieren versuche:

Grundlagen

  • smartparens - Paarung, Manipulation, Navigation in Klammern (oder Parinfer, wenn Sie es vorziehen)

  • clj-refactor - hat einige erstaunliche Funktionen, wie das automatische Hinzufügen / Kompilieren von Namespaces (möglicherweise wird es bald in CIDER integriert).

  • Clojure-Modus - Schriftsperre, Einrückung, Navigation

  • Unternehmen - Textvervollständigungs-Framework (oder wählen Sie einen anderen Auto-Completer)

  • Regenbogenbegrenzer - hebt Begrenzer wie Klammern, Klammern oder Klammern entsprechend ihrer Tiefe hervor / färbt sie ein

  • flycheck - On-the-Fly-Erweiterung zur Syntaxprüfung

  • flycheck-clj-kondo - Integration für clj-kondo

Feinheiten

  • Clojure-Snippets - erweiterbare Verknüpfungen zu längeren Codeblöcken

  • Dumb-Jump - Springe zu Definitionen

  • Welche Taste - Zeigt die verfügbaren Tastenkombinationen im Popup an

  • Klammern markieren - Markieren Sie die umgebenden Klammern

  • crux - eine Sammlung lächerlich nützlicher Erweiterungen für Emacs

  • comment-dwim-2 - Ersatz für Emacs 'eingebautescomment-dwim

Allgemeine Grundlagen (für jede Sprache)

  • Magit- Git-Porzellan in Emacs

  • Projektil - Projektverwaltung zum Auffinden von Dateien, Suchen usw.

  • Helm - inkrementelle Vervollständigung und Auswahl Verengung Rahmen (oder Swiper )

Andere Ressourcen

Wenn Sie nach einem Setup suchen, das bereits den größten Teil / die gesamte Arbeit für Sie erledigt hat, stehen folgende Optionen zur Verfügung:

Micah Elliott
quelle