Code Intelligence in Vim

By Isaac Snow on September 19, 2018


Do you use Vim and miss the powerful features for navigating your code that Sourcegraph gives you in your browser?

Code intelligence in Sourcegraph is powered by language servers that implement the Language Server Protocol. This means you can install these language servers locally and get code intelligence on your machine.

In this post, I’ll walk you through setting up a language server client for Vim and Neovim. Once complete, you’ll be able to go to definition, find references and more.

Prerequisites

I’ll start with this minimal .vimrc file:

syntax on
set number
set hidden " Required for specific actions that require multiple buffers

I’ll also use vim-plug to manage plugins used in this post. Follow the installation steps in the README for your specific setup.

Now let’s configure Vim to use vim-plug by adding the following to your .vimrc:

call plug#begin('~/.vim/plugged')

" Plugins go here

call plug#end()

Language Server Setup

Before we configure the Vim language server client, we need a language server installed locally, so the client has something to communicate with.

At Sourcegraph, we write a lot of Go, so we’ll use the Go language server for this example. If you don’t use Go, you can pick a language server for your language of choice.

Note that Go must be installed to use the Go language server.

Let’s install the Go language server.

go get -u github.com/sourcegraph/go-langserver

Make sure it was installed and is executable.

go-langserver -version

If the above didn’t work, make sure you have Go configured correctly.

That’s it! The Go language server is ready to use.

Language Server Client Setup

Now it’s time to install the language server client plugin. We’ll use LanguageClient-neovim. Although the name contains Neovim, it supports Vim as well.

To install the plugin, let’s add the plugin to our .vimrc so vim-plug can install it:

call plug#begin('~/.vim/plugged')

Plug 'autozimu/LanguageClient-neovim', {
    \ 'branch': 'next',
    \ 'do': 'bash install.sh',
    \ }

call plug#end()

After you add this to your .vimrc, make sure you install the plugin. For vim-plug, just run the :PlugInstall editor command.

Next, we need to tell the language client how to use the language servers you have installed. To do this, we’ll add a configuration option to your .vimrc:

let g:LanguageClient_serverCommands = {
    \ 'go': ['go-langserver']
    \ }

That’s it! You now have many of the powerful features you’re used to from Sourcegraph inside Vim. Now let's use it.

Language Client Usage

Now use this on a Go file you have locally or save the below to hello.go in your Go workspace.

package main

import "fmt"

var subject string

func main() {
    subject = "World"

    fmt.Printf("Hello, %s!", subject)
}

Open this file, then type the following command to execute the context menu function.

:call LanguageClient_contextMenu()

This command opens up a context menu showing you all of the different functionalities provided by the language server. To execute an action, type the number listed by the item and press enter.

While this is pretty cool, it’s still a bit clunky to use. Let’s set up some shortcuts. Add each of the following to your .vimrc:

  • Get “hover” information by hitting the keys <leader>h

    nnoremap <silent> <leader>d :call LanguageClient_textDocument_hover()<CR>
  • Go to definition by hitting the keys <leader>d

    nnoremap <silent> <leader>d :call LanguageClient_textDocument_definition()<CR>
  • Find references by hitting the keys <leader>fr

    nnoremap <silent> <leader>fr :call LanguageClient_textDocument_references()<CR>

Gotcha alert! The language client adds the list of references to Vim’s location list. Once the operation has completed, you’ll see “Location list updated.” To see the list, type :lopen. I recommend installing junegunn/fzf for an easier-to-navigate list that opens automatically.

  • Rename symbol by hitting the keys <leader>r

    nnoremap <silent> <leader>r :call LanguageClient_textDocument_rename()<CR>
  • Open the context menu to get each of the available actions by hitting the keys <leader>m

    nnoremap <silent> <leader>r :call LanguageClient_contextMenu()<CR>

There you go! You now have the basic features you know and love from Sourcegraph code intelligence inside Vim or Neovim.

Got any other Vim plugins and integrations I should know about? Let me know by tweeting at ij_snow and @srcgraph!