Format Clojure Code in Neovim


Here's how to format clojure code in neovim.

LSP Help

Neovim has built-in LSP abilities. Null-ls gives it more abilities. This project was very recently archived, so the future of it (or alternatives) is unclear, but this is what I will use for now.

Null-ls has some build-in sources. Importantly, it knows how to talk to zprint, a formatting tool that knows how to parse Clojure.

Set up LSP

Modify your nvim setup to include null-ls. Here using packer:

require 'packer'.startup(function(use)
  use 'jose-elias-alvarez/null-ls.nvim'
)

Then :PackerSync.

Then set up formatting generally. Here, we will:

  • Use only null-ls for formatting. (Other tools can conflict.)
  • Set up formatting on save (BufWritePre)
  • Set up a shortcut that calls null-ls formatting, <leader>f

See an example common.lua file:

local M = {}

-- from: https://github.com/jose-elias-alvarez/null-ls.nvim/wiki/Avoiding-LSP-formatting-conflicts
local lsp_formatting = function(bufnr)
  vim.lsp.buf.format({
      filter = function(client)
          -- use only null-ls for formatting (eg, not tsserver)
          return client.name == "null-ls"
      end,
      bufnr = bufnr,
  })
end

local augroup = vim.api.nvim_create_augroup("LspFormatting", {})

M.on_attach = function(client, bufnr)
  if client.supports_method("textDocument/formatting") then
    vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr })
    -- format on save
    vim.api.nvim_create_autocmd("BufWritePre", {
      group = augroup,
      buffer = bufnr,
      callback = function()
        lsp_formatting(bufnr)
      end,
    })
  end

  local bufopts = { noremap=true, silent=true, buffer=bufnr }
  vim.keymap.set('n', '<leader>f', lsp_formatting, bufopts)
end

return M

Then import that formatting setup and tell null-ls to use it and to use zprint as a source:

local common = require('jt.lsp.common')
local null_ls = require "null-ls"

null_ls.setup({
  common.on_attach,
  sources = {
    null_ls.builtins.formatting.zprint,
  },
})

Install zprint

The easiest way to install zprint is to download the prebuilt zprint library from github. (note: zprintl is the version for linux.)

Download it and rename it zprint and put it in your $PATH somewhere you like.

If anyone knows of a packaged version of zprint published somewhere that is better for this purpose, please let me know.

Format Your File

After installed and configed, restart nvim, and open a .clj or .edn file, and give it a format. Remember, you can use the key binding we set up above:

<leader>f

Beautiful indentations from here on out.