Programming Scala in Vim

I moved from programming Java in Eclipse to programming Scala in Eclipse.  I didn’t need any convincing that Scala was a surperior language than Java, but the fact that Scala tools were years behind Java tools smacked me in the face.  ScalaIDE, the Eclipse plugin for Scala, would have unexpected bugs (right clicking browse to source works, but F3 doesn’t), unimplemented features (can’t watch variables), and huge performance issues.  An Eclipse plugin should never grind Eclipse to a halt and issue OutOfMemoryExceptions on a 4 core 32 GB machine (admittedly it was a 32-bit OS).  The plugin has improved greatly in the past months, but it still causes many headaches. Besides, Eclipse doesn’t work over ssh.

First, you will need syntax highlighting in vim.  To set this up, go to this GitHub repository. You will to download three of the files and put them in <code>$HOME/.vim/</code>

  • ~/.vim/indent/scala.vim (indentation rules)
  • ~/.vim/ftdetect/scala.vim (detect scala files)
  • ~/.vim/syntax/scala.vim (syntax highlighting)

Now when you start vim, you should have syntax highlighting (although you might need to add :syntax on to your vimrc.

While syntax highlighting is a must, it alone probably won’t pull you away from a full-featured IDE.  However, with continuous compilation using the Fast Scala Compiler (fsc), one can code effectively in Scala using vim.

It’s helpful to have two panes so you can see the output of the compiler while you are editing the code. I like doing this in a screen instance. screen has the added benefit that, if you are using an ssh terminal, you can disconnect and reconnect without losing your place.  screen has the downside that now you are able to have windows inside vim, inside screen, and (maybe) inside your window manager.  The fact that each (necessarily) has a separate key to jump between windows can be frustrating (note: vim may allow terminals in buffers at some time). screen also does not do a great job of managing multiple windows, and it overrides CTRL+A.

Regardlesss, start up screen. To create a split window, hit CTRL+S SHIFT+S (control S followed by shift S). Next, switch down to the new pane with CTRL+A TAB and create a new screen window with CTRL+A C. You can move between these two panes with CTRL+A TAB, as before.

Before you do jump back up to the top pane, however, you might as well start continuous compilation in the lower pane. If you are using maven, start mvn scala:cc and if you are using sbt, start sbt ~compile. Now switch back to your code pane, open a file with vim, make an edit, save your changes, and watch!

If you were to make a mistake and save, you get fast feedback.

As a side note, if you are not interested in real time compilation but would rather compile with the built-in make command (:make) you can set your compiler to maven and use this maven compiler plugin for vim.  You may even find this helpful in addition, because when you compile with :make, you can jump to the errors with QuickFix.

By this point we have syntax highlighting and real-time feedback from the compiler.  This is great, but you’ll probably still miss a few key IDE features.  For one, it’s hard to jump between files.

Vim has a few commands that can help you switch between files. find will search for exact matches and open them in the editor. You can use wildcards and search recursively.

:find **/Hello*scala

Or, if you are more comfortable doing so, you can edit the results of an external command.
:e `find -name Hello*scala`

Vim also supports :grep (external grep) and :vimgrep (internal grep) command. The latter supports a lot of vim features (for example, you can navigate through multiple results by opening the quicklist window :copen), but is slower because each file is loaded into vim. This vim tip contains more information on finding files using vim commands.

While useful, I find these tools rather limited. I prefer the Command-T plugin, which adds excellent search functionality. From any vim project, you can hit &lt;LEADER&gt;+T (the leader key is ‘\’ by default) and then type to interactively find a file. While not worlds different than the built-in commands, I find Command-T much more effective and easier to use.

If you are looking for more control when jumping between files, you can add navigation to definitions using exuberant ctags.  The ctags project was created to support this functionality in vi with C.  exuberant ctags has replaced the original with the ability to extend to many languages.

First, you will download the following gist to $HOME/.ctags in order to support scala.

You can generate ctags for scala (and any other supported language, which include Java by default) by running ctags -R. If you want to create tags for dependencies, the following command will unpack all the available sources for dependencies in target/dependency.

mvn dependency:unpack-dependencies
  -Dclassifier=sources
  -Dmdep.failOnMissingClassifierArtifact=false

You could generate tags once globally for each project, but I find it easier to create tags on a per-project basis. You may still want to have a seperate ctags file for OpenJDK sources. In this case, you can have a secondary tags file.

Vim has excellent support for ctags.  First, you can set the tag file by adding the following to your vimrc (looks for tags file in the directory of the open file, then the tags file in the current directory).

set tags=./tags,tags

You can chain more tags files if you have more than one.
set tags=./tags,tags,/my/other/tags

For a taste, I’ll introduce a few common commands. Jump to a tag inside vim using :ta TagName. Or better yet, jump to the tag under the cursor with CTRL+]. You can return to where you were with CTRL+T. To learn more about using ctags in vim, read :h ctags or this vim wiki.

If you want, check out my vimrc.

Enjoy your vim IDE! Happy vimming!


Some more useful tools.

7 thoughts on “Programming Scala in Vim

  1. The .vim/ftdetect/scala.vim file caused lots of errors when I bring up vim (in Mac OS 10.6.5). Do you know if something is wrong with that file? Thanks

    • It hasn’t changed since March, and I use it and it works fine (vim 7.3.322). The file is only a single line (au BufRead,BufNewFile *.scala set filetype=scala), so it shouldn’t be able to cause too many errors. Are you sure you didn’t mix it up with another file?

    • Hello, Zebulah.

      How did you get that file into your computer? Have you used “wget” to fetch it? Perhaps what you have saved is the HTML from GitHub, instead of the appropriate file.

      If that is the case, perhaps you can try this in order to fetch the right files:

      for d in indent ftdetect syntax ; do mkdir -p ~/.vim/$d ; wget -O ~/.vim/${d}/scala.vim https://raw.github.com/scala/scala-dist/master/tool-support/src/vim/${d}/scala.vim ; done

      Please note that files are fetched from address “raw.github.com”, instead of just “github.com”.

      Good luck.

  2. Maybe I’m not as smart/advanced as everyone else but what is the obsession with IDE’s and especially Eclipse? I can see a major benefit when using Java (and for Java Eclipse it is very impressive) but for Scala I see little benefit. Scala comes with a good interpreter that makes prototyping fairly easy. I can’t see much improvement coming from an IDE. IDE’s typically add their own layer of complexity as well. With some IDE’s I feel like I am learning a new programming language. Enough with learning new technologies, I just want to get to solving problems.

  3. Re: “note: vim may allow terminals in buffers at some time”

    Regardless of the number of votes for this feature, vim is not likely to ever do this.

    :help design-not
    explicitly addresses this:

    - Vim is not a shell or an Operating System.  You will not be able to run a
      shell inside Vim or use it to control a debugger.  This should work the
      other way around: Use Vim as a component from a shell or in an IDE.
      A satirical way to say this: "Unlike Emacs, Vim does not attempt to include
      everything but the kitchen sink, but some people say that you can clean one
      with it.  ;-)"
    

    BTW, your

    .ctags
    gist is currently broken.

  4. Nice summary of available tools.

    You may want to give two other vim plugins a try:

    https://github.com/derekwyatt/vim-scala
    - gives you highlighting and lots of other features like ‘:make’ via sbt

    https://github.com/scrooloose/syntastic
    - gives you ‘in the editor syntax checking’ on every save via the ‘scala’ command
    - errors are displayed right in your code via colorful markers
    - no need to have that continuous compiler running in a separate screen

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>