Saturday, October 29, 2011

Using emacs and leiningen on Windows for clojure pt. 2

Setting up leiningen

So in the last post, I described how to set up emacs and leiningen for Windows.  We're actually not quite done with some of the tools we'll need.  In the last post, we installed a package for emacs called the slime-repl.  Now it's time to install a plugin for leiningen that lets SLIME talk to the clojure REPL.

There's a nifty plugin called swank-clojure that allows the SLIME protocol to talk to a running clojure process and interact with it.  I can't go into too much detail into all the commands of SLIME itself since I'm still learning it as well, but I will show you how to install it, and run a REPL with it.

The first step will be actually installing swank-clojure itself.  You can even do this from within emacs itself.  To do this, type in M-x eshell in your minibuffer.  You will get an emacs version of the command console.  It's not exactly the cmd console, and if you've ever used MSYS or cygwin shells, it's kind of similar.  For example, instead of using the command dir to list directories, you use ls.  Also, to tab complete a directory, you use posix style forward slashes instead of back slashes (RANT ON: I have spent weeks at my job discovering and working around assinine Microsoft pathing issues.  Whoever thought that having spaces in directory paths, or using backslashes...which are also escape characters...as path separators, needs to be forced to listen to Justin Bieber and Rebecca Black songs continuously for 24hrs with no breaks...RANT OFF).

In the eshell, you can run the command to install a leiningen plugin like this:

lein plugin install swank-clojure 1.3.3

Assuming you have no proxies (or your proxy for leiningen is correctly set up), and leiningen was successfully installed previously (did you remember to install curl or wget in your PATH?), then the command above will install the swank-clojure plugin for you.

Creating a leiningen project

So now we get to learning what leiningen provides for you.  If you are a Java programmer, odds are that you are familiar with Maven (or maybe Ivy).  Leiningen is for clojure what Maven is for Java.  Indeed, you could use Maven for your clojure projects, but leiningen does many clojure specific things for you.  It will also drastically reduce the time required to set up a clojure project.

The first step is to create your project.  Leiningen has a command called new which sets up a base project for you.  For example, if I am in directory C:\Users\stoner (my name is Sean Toner , thank goodness it's not Frank Ucker :) ), and I use the command:

lein new MyFirstCljProject

then leiningen will create a directory named MyFirstCljProject, and you will see a bunch of files and directories inside of it.






The two most important ones right now are the project.clj file (in the root folder you created) and the src folder.  The project.clj file is somewhat equivalent to a maven pom.xml file.  Basically, the project.clj file describes all the necessary dependencies, AOT compilations, initial REPL namespaces, and other pieces of information to build or run your clojure project.  Basically the project.clj file is a clojure map, where the keys are various values (described here from the leiningen sample file), and the values are whatever is appropriate to your project.

We will start off with a simple project just to get familiar with leiningen, the emacs SLIME interface to the REPL, and how leiningen uses the project.clj file

Our first Clojure project

Let's start off by running the lein new command I showed above in your HOME directory (if you're using Vista or Windows 7, that would be your C:\Users\user_name directory most likely).  Running the command above on my system will create a folder called C:\Users\stoner\MyFirstCljProject.

Here's the output of the project.clj file that leiningen initially generates for you:


(defproject MyFirstCljProject "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.2.1"]])


Notice the :dependencies keyword.  This is equivalent to a Maven dependency artifact.  In fact, you can convert a Maven artifact to a leiningen dependency pretty easily.  This can allow you to add Maven repositories above and beyond leiningen's default repositories, and then download required jars that way (I don't think you can download pom artifacts, as I've never tried, but it wouldn't make sense to do that for a clojure/leiningen project).  For example, here is the maven dependency from the Netty website:

<dependency>
      <groupId>org.jboss.netty</groupId>
      <artifactId>netty</artifactId>
      <version>X.Y.Z.Q</version>
      <scope>compile</scope>
</dependency>

The leiningen equivalent to this would be:

:dependencies [[org.jboss.netty/netty "3.2.6.Final"]]

One point of confusion for me when I was first learning leiningen was that all the examples only showed one dependency example.  What if you have multiple dependencies?  Easy enough.  Let's add the logback logger.

:dependencies [[org.clojure/clojure "1.3.0"]
                       [org.jboss.netty/netty "3.2.6.Final"]
                       [qos.logback/logback-core "0.9.30"]
                       [qos.logback/logback-classic "0.9.30"]
                       [org.slf4j/slf4j-api "1.6.3"]])

The above will automatically pull in clojure itself, netty, and the required components to use the logback logger (with the slf4j common interface).  We won't be using all of these dependencies yet, but go ahead and add them to your project.clj file.  Go ahead and do this with emacs.

Editing with emacs

Copy the above, and in emacs, do the following.  Put your cursor at the beginning of the line, ":dependencies [[org.clojure/clojure "1.2.1"]], in the project.clj file.  If you don't have the project.clj file open in emacs, remember, to "visit" a file, use C-x C-f, enter the path to the file, and hit enter.  Once you move your cursor to this spot, hit C-space.  This sets a "mark" point.  Now we will "highlight" the portion of the text we wish to replace.  Hit C-n...notice that the cursor moves to the next line below, and that all the portion is highlighed.  It should look something like this now:


Now that your text is highlighted, we can replace this text from our system clipboard.  I've been trying to find an easier way to do this in emacs, but I haven't found one yet.  In most other editors, if you have a selected region, and you "paste" into it, it will write over the selected region.  Emacs does not do this.  If you attempt right now to use C-y to "paste" the copied section into the highlighted region, rather than replace the highlighted region, it will instead paste the copied text from the point of the cursor (rather than the highlighted region).   So what I do is this:

C-w  # deletes the region
C-y   # replaces the yanked region (but wait!!)
M-y  # cycles to and inserts the next item in the kill-region

After doing this, your file should look like this:


If you don't like the identation from above, try this...use C-space to begin your mark at the [org.jboss... line. Then use M-> to go the end of the file (that sould be Alt + Shift + the . key).  That last command moves the cursor to the end of the file.  Your emacs should look like this:



Now to adjust the region to the next column, use the C-M-\ command (that would be Ctrl + Alt + \).  Your lines should now all be lined up.



That's it for now.  In the next installment, we'll actually start adding some clojure code, and play with the SLIME repl!!


No comments:

Post a Comment