Contributing

The general architecture of ENSIME looks like this:

architecture

which is explained in a recent talk about ENSIME by @rorygraves and @fommil and an even more recent one by @fommil (both are still relevant). All our code is hosted at github.com/ensime.

Where to Start

The first thing to do is to decide what you want to contribute!

If you are looking for a small task to pick up, have a look at our latest milestone on github.

Anything with the Low Hanging Fruit or Needs Reproduction labels are suitable for a new contributor. Please contact us on the github issue directly if you want to contribute something: this avoids duplication of efforts, and also lets us discuss the best way to do it.

We have regular Hack Days in London. If you can set aside the time to join us, they are a fun and exciting way to contribute to ENSIME.

If you can’t come to a hack day but you’d really like to have some live help from somebody, please ask. We can use the libre software meet.jit.si to screen share and discuss tickets anytime that is convenient.

If you’d like an ENSIME logo sticker for your laptop, let us know in your PR and privately email your postal address (or feel literally free to print your own, the logo is CC BY-SA 3.0 and is not trademarked).

Editors

If you want to work on editor support for ENSIME there may be additional documentation at these locations:

If you want to add support for an editor not listed here, please get in touch at gitter.im/ensime/ensime-server and read the server documentation below to get an idea of what the API looks like.

Build Tools

If you want to work on build tool support, there may be documentation at these locations:

If you want to add support for a new build tool, the manual .ensime instructions are a good place to start.

Scala Compiler and Refactoring

Much of the Scala support of ENSIME is provided by the scala compiler itself and the refactoring library. Scala IDE also uses these components and their documentation on accessing the presentation compiler is recommended reading. We also recommend watching a recent talk about scala-refactoring by @mlangc.

If you’d like to improve these components, you may wish to ask questions at gitter.im/scala/contributors and gitter.im/scala-ide/scala-ide respectively.

Many problems (e.g. the infamous “red squiggles on valid code”) may be incredibly difficult to solve in the compiler and we created ensime/pcplod to help you create minimal examples of what is broken and to allow you to work with macro/plugin authors to fix the issues. If the problem appears to be a presentation compiler bug, you will need to fix the bug upstream.

Server

The remainder of this document focuses on contributing to the server component, which is hosted at github.com/ensime/ensime-server. If you pick up a ticket, please comment on it to let us know so that we can help (and also to avoid overlapping with somebody else). Feel free to ask questions on the github issue tracker or gitter.im/ensime/ensime-server.

The server API is documented in org/ensime/api with example JSON payloads in org/ensime/jerky. The preferred protocol for most editors is JSON over WebSockets, which we call our JERKY protocol. A legacy S-Expression over TCP protocol is used by Emacs (deriving from the SWANK protocol of SLIME), but ENSIME 2.0 will hopefully see us move to S-Expressions over WebSockets, which we will call our SWANKY protocol.

Compiling and Tests

Make sure you have 0.13.13+ of the sbt start script, otherwise project compilation will fail with a java.lang.OutOfMemoryError or java.lang.StackOverflowError.

Before you start, run this sbt command on your ensime-server repository as the .ensime file is required to run the integration tests (even if you are not using ENSIME to hack on ENSIME).

sbt ensimeConfig

Don’t forget to compile the integration tests as well as the tests, e.g.

sbt test:compile it:compile

The .drone.yml file documents the exact commands that we use during our CI and should serve as a good reference.

Implementing a Feature or Bugfix

It all starts with a test. Find a test that is already testing something similar to what you want to achieve, and adapt it.

We have several styles of tests: unit tests, in-memory source tests (e.g. RichPresentationCompilerSpec), on-disk source tests (e.g. BasicWorkflow) and the Emacs client tests. It may be instructive for you to read and understand some of these tests to get a feel for the right level to write your test.

Guidelines

We do not have any official style guide. Code formatting is enforced by scalariform. When in doubt, prefer functional idioms encouraged by Typelevel such as referential transparency, typeclass derivation and immutable data structures. We made a huge mistake depending on akka and we would like to fix that by replacing it.

Note that many functional styles of programming introduce huge memory overheads and we have several critical paths where we cannot afford to trade style over performance. We encourage locally scoped mutability if it improves performance and / or readability. We integrate with several heavily mutable external systems, such as the ASM classpath visitor, file systems, databases and the compiler APIs, so we try to be pragmatic.

Because we are at the forefront of the development cycle for new versions of Scala, we prefer to restrict our usage of external scala libraries. Therefore, please prefer Java dependencies where possible.

Manual QA Testing

To build your own server jar:

sbt ++2.10.6 ensime/assembly # replace with your version of scala

check that again: Make sure the Scala major version matches the Scala major version of the project in which you wish to use the ensime-server snapshot build.

Next, use your build tool to provide this information in the .ensime file of your project. e.g. if you use sbt-ensime, put this in your ~/.sbt/0.13/global.sbt (all projects) or ensime.sbt (just one project):

import org.ensime.EnsimeKeys._

ensimeServerJars in ThisBuild := Seq(file("/path/to/your/ensime-assembly.jar"))

make sure you’re running the developer version of your editor plugin.



[edit]