[ This is an old post, written at a time when Ensime-vim was the only viable option. In 2021 I recommend “Scala metals”]
I’ve been using VIM as my Scala IDE for the last year and I can report I’ve had a very positive experience with it. Below I have a short table of what IDE features I use and what plugins offer those features. Before you read that stuff however you need to align your perceptions and expectations with mine. I’ve used vim to write Python and Perl every workday for 8 years. I have put forth considerable effort to make vim work for me as a Scala IDE. It didn’t happen overnight. Python and Perl are weakly-typed. Many IDEs simply can’t offer “Jump to definition” in Perl code accurately as there’s no strict rules on where `$obj->$method` would even go without evaluating the program at runtime. My expectations for a productive environment are probably far less than those coming from IntelliJ or Visual Studio would hope for. You have been warned.
Compared to Python and Perl, Scala has a complicated type system, Futures, functional style and hidden implicits. All of this makes learning Scala quite a challenge. Using a full IDE such as IntelliJ (which I did for my first six months) is the best way to learn and get productive in Scala. Out of the box there’s solid sbt integration, compiler errors and feedback, type deduction, auto-completion and way more than I’m even attempting to make available to VIM.
I’ll iterate this once more for clarity: I use and recommend vim as a Scala IDE if you’re a vim expert who wishes to continue using vim in your workflow. I do not advocate it as better or more suitable than other editors, especially to those that don’t use vim.
My motivation for writing post was because I spent days trying to set up ensime-vim a year ago and it was a bit of disaster. Many of you may also have had the same bad experience. Since then I’ve tried again and been more successful. This post is to give those interested in using Scala and Vim together a refresher in what’s possible on the modern version and if it’s worth investing a couple days into getting yourself setup. For vim lovers, the answer is yes, definitely.
This table lists features, how important I feel there are, which plugin offers the feature and notes on it’s implementation:
IDE Feature | Priority | Feature available in VIM | Plugin required | Notes |
---|---|---|---|---|
Syntax Highlighting | Essential | Yes | vim-scala | Does accurate Scala highlighting but not as good as intellij. Doesn't interpolate strings correctly |
Poor-mans Jump to Definition | Essential | Yes | ctags | Available via ctags. Pretty poor experience |
Accurate Jump to Definition | Essential | Yes | ensime-vim | :EnDeclaration |
Rename symbol | Nice to have | Yes | ensime-vim, vim-multiple-cursors | :EnRename or using the vim multiple cursors plugin |
Automatically add Imports | Essential | Yes | ensime-vim | :EnSuggestImport offers completion from real viable imports your project includes |
Show symbol’s type | Essential | Yes | ensime-vim | :EnType works as well as intelliJ's add declaration feature. Very impressive |
Show/highlight compilation errors | Nice to have | Yes | ensime-vim | :EnTypeCheck marks characters as read and putting your cursor over shows the errors. Personally I just run sbt in a separate console however. |
Autocomplete (as you type) | Nice to have | Yes | omni-complete | In insert mode type Ctrl+X, Ctrl+0. I rarely use this feature but it does work with correct types etc. Very impressive. |
Project browser | Nice to have | Yes | Nerdtree | Browsing and opening files in vim is something you'd want to do using your normal vim skills |
Quick Jump to file | Nice to have | Yes | ctrlp.vim | A general vim plugin autocompletes filenames as you type but vim file management tools just as effective. |
Integrated debugger | Nice to have | Supposedly but Unproven / Untested | ensime-vim | There's a host of :EnDebug commands that I haven't explored. |
Show references / usage | Essential | Yes | ack.vim | I use :Ack |
Git integration | Nice to have | Yes | vim-fugitive | There's a whole host of features here. This plug in isn't Scala specfic. I only use :Gblame to find information on lines of code. |
The plugins referenced above can be found here:
General Guide to Installing Ensime-vim
The first and most annoying blocker. Ensime requires your copy of vim to be compiled with +python support. You may need to hunt down the correct version in your distro’s package manager. Debian and others recently switched +python3 support which makes finding a compatible vim a little harder. I had to personally recompile vim from source to enable the feature. You can use the command to find out if you have +python support:
vim --version
Installing plugins in VIM is not simple, unless you’re using the pathogen plugin to manage this process. Get pathogen here. After this, other plugins can be installed by just “git cloning” them into your ~/.vim/bundles directory.
First, put this into ~/.sbt/0.13/global.sbt
import org.ensime.EnsimeCoursierKeys._ import org.ensime.EnsimeKeys._ ensimeIgnoreMissingDirectories := true ensimeIgnoreSourcesInBase := true
Add this to ~/.sbt/0.13/plugins/plugins.sbt
addSbtPlugin("org.ensime" % "sbt-ensime" % "1.12.8")
Then in your Scala project’s root directory (where sbt or activator should be) run this to build the symbols for ensime:
sbt compile ensimeConfig ensimeConfigProject
Then you’re set and ready to go! You’ll need to do this for each project. After that, when you open Scala files in vim you should be greeted with the reassuring message in vim’s promt:
[ensime] Analyzer is ready
Now you’re ready the try out the commands in the table. In some scenarios I’ve had to manually run the command :EnClasspath but generally this shouldn’t be required.
Fixing issues
If Ensime crashes or won’t start, delete all of these directories and try again:
~/.config/ensime-vim/ ~/.ivy2/ ~/.coursair/ .ensime_cache .ensime
Errors are reported at the path below and can help you debug and fix some of the issues.
.ensime_cache/server.log
Be aware that sometimes Ensime won’t work if your application doesn’t cleanly compile because your code already contains compiler errors.
Good luck and have fun!