Enable Cypher Language Server for Neovim


Sometimes all it takes is a terminal and your favorite editor to get things done. In this case, perhaps you’d like to write Cypher statements with syntax highlight and grammar check.

This post will focus on getting a Neovim environment from 0 to Cypher support — and with a pleasant visual improvement. Neovim is a Vim-based text editor engineered for extensibility and usability, to encourage new applications and contributions.

This guide assumes you don’t yet have anything configured in your Neovim configuration. If you already have a plugin manager enabled or even language server plugins installed, you can skip those sections.

Requirements

There is not much needed to get the full Cypher support working.
All you need, besides Neovim obviously, is a current npm and Node.js version, on which the Cypher language server will be installed and run.

Setting Up the Needed Infrastructure

First ensure that your Neovim installation is on a version that has Cypher file support (v0.10.0+) by calling nvim -v. The output should contain something like:

NVIM v0.10.2
Build type: Release

When opening a .cypher file, it should look like this:

Cypher statement without syntax highlight
Cypher statement without syntax highlight

Because this guide starts with a fresh configuration, we need to add some boilerplate code to get a package manager running in Neovim. I have chosen to use lazy.nvim and something similar to its default setup, which leads to a ~/.config/nvim/init.lua like this:

require("config.lazy-bootstrap")
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"
require("config.lazy")

And create one file called ~/.config/nvim/lua/config/lazy-bootstrap.lua for the initial installation of the package manager, if it does not exist:

-- Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = "https://github.com/folke/lazy.nvim.git"
local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
if vim.v.shell_error ~= 0 then
vim.api.nvim_echo({
{ "Failed to clone lazy.nvim:\n", "ErrorMsg" },
{ out, "WarningMsg" },
{ "\nPress any key to exit..." },
}, true, {})
vim.fn.getchar()
os.exit(1)
end
end
vim.opt.rtp:prepend(lazypath)

Create another called ~/.config/nvim/lua/config/lazy.lua for the initialization of the plugin manager, including all needed plugins:

require("lazy").setup({
spec = {
-- here we will place the plugins
},
install = { colorscheme = { "habamax" } },
checker = { enabled = true },
})

When Neovim gets started now, we should see … nothing. This is due to the fact that there is no plugin defined yet, so let’s change this.

Adding the Needed Plugins

To get the right language server support into Neovim, we need three plugins:

  • nvim-lspconfig — Required for having built-in LSP support (file type association, start/stop, etc.)
  • mason — Handles the installation of LSPs, linters, etc.
  • mason-lspconfig — Bridges nvim-lspconfig with Maven to have auto-installation and more in place

Cypher Language Server Support for Neovim explains more about what those plugins do.

Because the targeted setup is straightforward, those plugins can be added directly to the spec section in the lazy setup:

require("lazy").setup({
spec = {
"neovim/nvim-lspconfig",
"williamboman/mason-lspconfig.nvim",
"williamboman/mason.nvim"
},
install = { colorscheme = { "habamax" } },
checker = { enabled = true },
})

In the next step, another config file (~/.config/nvim/lua/config/mason.lua) gets added to enable mason and tell mason-lspconfig which language server to install when asked:

require("mason").setup {}
require("mason-lspconfig").setup {
ensure_installed = { "cypher_ls" },
}

And enable the language server in the init.lua:

require("config.lazy-bootstrap")
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"
require("config.lazy")
require("config.mason")
require('lspconfig')['cypher_ls'].setup {}

When opening a .cypher file now, it won’t just highlight the syntax but also show information on incorrect usage.

Cypher statements with syntax highlight and error messages

Make It Even Nicer (Optional and Opinionated)

The current color scheme is using the default shell colors. Whether the individual parts are recognizable depends on the contrast.

You know what makes the world a better place and also your Neovim and everything else much more enjoyable? The Catppuccin color palette.
Luckily, there is a Neovim plugin that will help with the setup.

The Catppuccin Neovim plugin needs to be added to the list of plugins:

require("lazy").setup({
spec = {
"neovim/nvim-lspconfig",
"williamboman/mason-lspconfig.nvim",
"williamboman/mason.nvim",
{ "catppuccin/nvim", name = "catppuccin", priority = 1000 }
},
install = { colorscheme = { "habamax" } },
checker = { enabled = true },
})

The syntax looks a bit different for this plugin, but this is mostly due to the fact that it would otherwise have the default name nvim — definitely not the intention. The priority (default 50) just says that this plugin should be loaded as late as possible on start because it isn’t important for other plugins.

Having done this, let’s get back to the init.lua and define the color scheme:

require("config.lazy-bootstrap")
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"
require("config.lazy")
require("config.mason")
require('lspconfig')['cypher_ls'].setup {}
vim.cmd.colorscheme "catppuccin"

So now we have a much nicer color scheme.

Cypher statements with syntax highlight and error messages (Catppuccin themed)

Head over to the color scheme’s documentation to get a taste of all the flavors that are offered.

Summary

This post has shown how to get a Neovim environment from 0 to Cypher support with an aesthetic improvement bonus. We walked through setup, adding the plugins, and adding color. Go ahead and give it a try.

To learn more about Cypher, check out the Cypher Fundamentals course on Neo4j GraphAcademy.

Happy Cypher writing!


Enable Cypher Language Server for Neovim was originally published in Neo4j Developer Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.